Skip to content

Author a custom flow

This page walks you through creating a custom flow end to end — naming it, building its stages and blocks, saving a draft, and publishing it so it's ready to embed in a system flow.

Before you begin
  • You have tenant Admin access to the admin console.
  • You have a clear idea of the logic the flow should carry — the blocks you'll need and a rough stage structure.
  • The custom flow doesn't need to exist yet in any system flow. Publish first, embed second.

Any tenant Admin can create, edit, and publish custom flows. Viewers can read the flow list and open flows in read-only mode but cannot save changes.

Sign in to the admin console for your tenant (https://<tenant>-<org>.intelliauth.local/admin, substituting your tenant and org slugs).

In the left sidebar, navigate to Flows. The Flows list shows two tabs: System flows and Custom flows. Click Custom flows.

The Custom flows list before you've created any flows. The tab is part of the main Flows section.

Click New custom flow (top right of the list). A creation dialog opens.

The creation dialog. Slug is auto-derived from name but you can edit it.

Fill in two fields:

  • Name — a human-readable label visible to tenant admins. "Banking fraud gate" or "Registration enrichment" work well. Keep it short and descriptive.
  • Slug — a lowercase, dash-separated identifier used internally. Auto-derived from the name; you can override it. The slug uniquely identifies this flow within your tenant.

Two hard rules on slugs:

  • Lowercase letters, digits, and dashes only (a-z, 0-9, -). No spaces, underscores, or dots.
  • Once a flow is published, the slug is permanent. You cannot rename it. If you need to rename a published flow, delete it and create a new one.

Click Create. The builder opens with an empty flow and a single blank stage.

A custom flow is a sequence of stages. Each stage is a named section that holds one or more blocks. You design the stages; there are no locked milestones the way system flows have.

Add a stage by clicking + Add stage at the bottom of the builder. A new stage appears with a placeholder name.

Rename a stage by clicking the stage label and typing a new name. Stage names are for your team — they don't appear to end users.

Stages are yours to name. The builder shows them top to bottom in the order they run.

A good stage structure for a fraud-screening flow might look like:

Custom flow: Banking fraud gate
├─ Stage: Signal collection
├─ Stage: Decision
└─ Stage: Terminal

Start with a stage that gathers or evaluates evidence, then a stage that makes a decision, then a terminal stage where you place your Allow or Deny block. This isn't mandatory — it's a pattern that tends to keep flows readable.

Click + Add block inside a stage. A panel slides open showing the block catalogue filtered for custom flows. Groups you'll find there:

  • Risk — IP reputation, brute-force check, risk evaluate, adaptive auth engine.
  • Identity — identity lookup, attribute enrichment.
  • Control flow — condition, branch, parallel webhook.
  • Notification — webhook, custom action.
  • Terminal — Allow, Deny.

Drag a block from the panel into the stage, or click it to add it at the bottom of the stage. Blocks run in the order shown, top to bottom.

The block palette shows only blocks available in custom flows. Blocks that require system-flow context — like Issue Session — are not shown.

Configure a block by clicking its settings icon (gear). Each block declares its own config fields. Text fields support the {} picker — click the curly-brace icon to insert references to flow state (event.*, step.<block>.*) without typing them manually.

Some blocks you won't see here that are present in system flows:

  • Issue Session — this block creates a user session. It belongs in system flows only.
  • Create User — creates an identity. System flows only.
  • Run custom flow — you cannot nest one custom flow inside another. Custom flows can only be nested one level deep.

Every custom flow must end with a terminal block: either Allow or Deny. You can have both in separate branches of a condition.

  • Allow — the parent system flow continues from where it called this custom flow.
  • Deny — the parent system flow halts. The user's sign-in (or whatever the parent flow was doing) does not complete.

Add the terminal block as the last block in your final stage, or at the end of each branch if your flow uses a condition to route between outcomes.

Above the first stage, you'll see a small card titled Custom flow settings. Today this card surfaces one knob: Stage TTL — the lifetime of the short-lived token IntelliAuth hands the user's browser between steps of the flow. Default is 10m. Leave it alone for most flows; tune it when the flow's pacing genuinely requires a different window.

The settings card sits to the right of START. Click it to open the inline editor.

Click the card. A small popover opens with one field — type a new value and click Save.

Accepted formats: 30s, 5m, 15m, 1h. The valid range is 30 seconds to 1 hour. The popover validates as you type:

  • Below 30 seconds — "Stage TTL must be at least 30s." (Below this floor, users hit token-expired errors on normal network latency.)
  • Above 1 hour — "Stage TTL must be at most 1h." (Above this ceiling, a leaked token stays replayable for too long.)
  • Anything unparseable — "Invalid duration. Try 10m or 1h."

For most custom flows, 10 minutes is the right answer. A user clicking through a fraud screen, an MFA prompt, or a quick policy gate completes the whole sequence well inside that window. Leaving the default also means your flow inherits any future framework-level improvements without an explicit re-tune.

Pick a longer TTL — 30m, 45m, up to 1h — when the flow includes a step that waits on a human in another seat:

  • An approval gate where a senior operator reviews a flagged sign-in before letting it through.
  • A multi-step risk review that pauses for a manual data lookup.
  • Any flow that intentionally introduces a delay you can't shorten.

The token must stay valid across the entire wait, including the approver's response time and any queuing slack.

Pick a shorter TTL — 1m, 2m — when the flow is a tight, fully-automated check with no user input mid-flow. The shorter window narrows the replay surface for a captured token without affecting honest users (who complete in seconds anyway).

Saving updates the flow immediately. The next time this custom flow is invoked, the engine issues stage tokens with the new TTL. There is no separate publish step for the TTL change — it takes effect on save, including for the currently-published version.

Click Save (top right of the builder). The flow is saved as a Draft. Drafts are never executed — a custom flow only runs when it is published and embedded in an active system flow.

Saving as a draft is a good checkpoint before publishing. You can re-open the builder, add blocks, reconfigure them, and save again as many times as you like while the flow is in Draft.

When you're satisfied the flow is correct, click Publish. A confirmation dialog summarises what you're about to make active.

The publish dialog gives you one last look before the flow is made available for embedding.

After publishing:

  • The flow's status changes to Published.
  • It becomes available in the Run custom flow block picker when you edit a system flow.
  • The slug is now permanent.
ConstraintValue
Slug formatLowercase letters, digits, dashes — no spaces, underscores, or dots
Slug mutabilityImmutable after first publish. Delete and recreate to rename.
RecursionA custom flow cannot call another custom flow (Run custom flow is not available in the palette)
Maximum execution time10 seconds total per invocation — shared with the parent system flow
Stage TTL range30 seconds to 1 hour, configurable per flow via the Custom flow settings card. Default 10 minutes.
Required terminal blockAt least one Allow or Deny block before the builder will permit publish
Who can publishTenant Admin (any Admin — no additional role required)

"No terminal block" publish error. Your flow must reach an Allow or Deny block on every possible path. Add a terminal block to the end of each branch, then try again.

Blocks missing from the palette. Some blocks from system flows are not available in custom flows. If a block you expected isn't in the palette, it requires system-flow context — typically because it creates or modifies a session. The palette in the builder shows exactly what's available for custom flows.

Slug conflict. If the slug you typed is already taken by another flow in this tenant, the console shows an inline error. Choose a different slug.

Flow won't run after publish. Publishing alone does not make the flow run. You must embed it in a system flow. See Embed a custom flow in a system flow.

Your custom flow is published and ready. The next step is embedding it inside a system flow so it actually runs when users sign in or sign up — Embed a custom flow in a system flow covers exactly that.