Product
Everything Assay does with your export.
One file in: your estate written down, connected, graded and signed. No credentials and no access to your Okta, at any point.
Export your folders
In the Okta Workflows console, open a folder and choose Actions → Export. Export as many folders as the estate spans; they are read together as one estate, so calls between folders resolve.
Assay reads it
The export is processed in memory. Your architecture is drawn in about a minute, and every flow is assessed, including the logic hidden inside cards.
You get the evidence
Your grade for free. A paid Assessment for every finding and a signed report. A Workspace to keep it current as the estate changes.
Okta removes connection credentials during export. Anything typed directly into a card stays in the file, and Assay checks for it.
Understand
See what the estate actually is.
Every flow as code
Each flow read back as plain logic an engineer can scan in seconds. Comments the builder wrote are surfaced, and calls into other flows are expanded where they run.
Hidden logic, found
A For Each body or an inline If Error handler is a complete flow the console shows as one card. Assay assesses each one: 560 listed, 867 assessed across 125 public template folders.
Flow map
Every card, branch and error path, with what each card takes and gives and which earlier card supplies it. Save it as PNG, JPEG or SVG.
Architecture
Five layers derived from the export, in the order things run, including flows coupled only through a shared table. Export it as an image or an animated GIF.
Dependencies
Which flow calls which, the entry points, and every flow that nothing in the export can start. Those are your retirement candidates.
Inventory
Every connection and table, and exactly which flows use each one, matched by id rather than by name.
Assess
Know how it holds up, and why.
51 controls, 7 dimensions
Error handling, logic robustness, security and access, intent and documentation, build standards, portability, and efficiency. The framework has 91; the 40 an export cannot prove are reported as not assessed, never passed.
A grade and a score
A risk grade from A to E, set by counting open findings rather than averaging, and a maintainability score from 0 to 100 inside that grade’s band.
Findings with evidence
Every finding names the flow and the card, and the fact in your file that produced it.
Improvement register
What to fix first, which flows each fix affects, and the effort involved.
Prove
Hand over evidence, not opinions.
Signed report
Signed with Ed25519 over the conclusions, not the PDF bytes. Anyone with the public key can verify it offline. PDF and HTML.
Documentation pack
A PDF describing each flow step by step in plain English, with its flow diagram. One flow or the whole estate.
Structured exports
The full assessment as JSON and the findings as CSV, for your own systems and trackers.
Keep it current · Workspace
Watch it change, and see what actually ran.
Version history
What each flow contained on a given date, card by card, and what changed between the version that worked and the one that didn’t. Renames are reported as renames.
Runtime evidence
Point Okta’s execution log stream at Assay and see whether a flagged call actually failed. Okta pushes to Assay; Assay never connects to Okta. Flow-level, as Okta sends it.
Change since last time
Each assessment compared with your baseline: flows added, removed and changed, and whether the grade moved.
Sign in with your Okta
Named sign-in through your own identity provider, so joiners and leavers are handled where you already handle them.
Who it answers
One file. A different answer for each person who asks.
“What can our automation change, and how exposed are we?”
- Every access-changing operation inventoried
- One grade for the whole estate
- Signed evidence for risk committees
“What does this do, and what breaks if I change it?”
- The architecture, derived from the export
- Dependencies and flows nothing can start
- Flows coupled through shared tables
“Where exactly is it fragile?”
- Findings down to the card
- The flow map, card by card
- A prioritised improvement register
“How do you know, and can you prove it?”
- Every control with its evidence
- “Not assessed” stated, never passed
- A report verifiable offline, and change between assessments
“Is what we built any good?”
- The same grade across every client
- A professional handover document
- Proof of quality, not a promise
The report
Click through the report.
Eight views from the report, generated from one real folder export. The live demo has every screen on a full sample estate.
Thirteen of thirteen external calls accept the default finish policy, so a rate limit or a transient error leaves a change half-applied and reports success. One of those calls alters group membership. The grade is set by counting what is open, not by averaging: three unresolved Criticals is an E whatever the sections that scored well did.
What was found
Maintainability score, by dimension
Nobody maintains this diagram. It is read out of the same export as everything else, laid out in the order things actually run, and each entry workflow’s chain is coloured end to end. Every link is routed in its own lane, so no line disappears behind a box.
What the diagram tells you that the console does not
Coupled by a table is the one nobody documents. 2a. SAML Create App writes the App Registry table and 3. Group Assignment reads it. Neither calls the other, nothing in the console connects them, and changing the columns one writes breaks the other in production.
| Grade | Score | Band | What puts an estate here |
|---|---|---|---|
| A Clean | 89–100 | Excellent | nothing open above Informational |
| B Minor issues | 73–88 | Good | an open Medium finding, or eight or more open Low |
| C Needs work | 56–72 | Needs attention | an open High finding, or eight or more open Medium |
| D At risk | 36–55 | High risk | an open Critical finding, or five or more open High |
| E Unsafe to leave | 0–35 | Critical | three or more open Critical findings |
flow add_users_from_a_table_to_an_okta_group(): rows = stash.searchRows2(sort_direction="asc", sort_limit=200, stash=table[…], …) for each item in rows, …: # ─── enter Get user Okta id and add to group ─── raw_output = okta.searchUsers(resultset="First Matching Record", query=email) # unguarded — flow stops here on failure if id != "": compose = compose(text="/api/v1/groups?search=profile.name eq "{{…", 3hugqyie0=groupname) status_code = okta.hTTPRequest(requesttype="GET", request_relative_url=compose) # unguarded — flow stops here on failure get = get(object=body, path="0.id") status2 = okta.addNewUserToGroup(group_id=get, user_id=id) # unguarded — flow stops here on failure join() else: return # ─── back ───
13 of 13 external calls stop the flow on failure. Workflows supports a single shared handler flow referenced from each card.
A rate limit or a transient error retries, or records itself, instead of leaving a change half-applied.
A governance write runs inside a loop set to ignore errors, so per-item failures disappear.
A partially applied change is reported as partial rather than as success.
10 of 27 flows have logging switched off, including flows on the grant path.
Every access change leaves a record an auditor can retrieve.
5 of 7 tables carry no stated purpose, and 5 flows are referenced by nothing.
A new engineer can tell what each table holds and which flows still matter.
Assay reports and does not remediate. These items are written so your team, your integrator or a third party can act on them — and so the next signed report can measure whether they were.
What we will not claim
The limits, stated up front.
See it on your own estate.
Draw your architecture free in about a minute, or explore every screen in the live demo.