Flow-based architecture
Flows provide a structured, stateful way to handle complex user interactions with proper security, validation, and error handling.Core flow interface
All flows implement theFlow interface defined in selfservice/flow/flow.go:38:
Flow types
Kratos supports two flow types defined inselfservice/flow/type.go:11:
Browser flows
Browser flows are designed for traditional web applications with server-side rendering or cookie-based sessions.Characteristics
- CSRF protection - Anti-CSRF tokens embedded in forms
- Cookie sessions - Session tokens stored in HTTP-only cookies
- Redirects - Automatic redirects to UI and return URLs
- Form-based submission - Standard HTML forms with
Content-Type: application/x-www-form-urlencoded
Browser flow lifecycle
-
Initiate flow
Kratos creates a flow and redirects to the UI URL with
?flow=<id> -
Render UI
UI application fetches flow data and renders the form
-
Submit form
-
Process and redirect
- On success: Redirect to
return_toor default URL - On error: Redirect back to UI with error messages
- On success: Redirect to
Browser flows require cookies and JavaScript to be enabled. The CSRF token must be included in all form submissions.
Example: Login flow structure
Fromselfservice/flow/login/flow.go:41:
API flows
API flows are designed for native mobile apps, SPAs, and machine-to-machine integrations.Characteristics
- No CSRF protection - Not needed for API clients
- Token-based sessions - Session tokens returned in response body
- JSON communication -
Content-Type: application/json - No redirects - Responses contain flow state and data
- Explicit flow management - Client controls flow lifecycle
API flow lifecycle
-
Initialize flow
-
Submit data
-
Handle response
- Success: Session token in response
- Error: Updated flow with error messages
- Requires action: Flow state indicates next step
API flows are stateless from the client perspective. Clients must include the flow ID in all requests.
Flow states
Flows transition through states as users progress. States are defined inselfservice/flow/state.go:31:
State transitions
Login flow states
Login flow states
choose_method- Initial state, user selects authentication methodshow_form- Display form for selected method (password, OIDC, etc.)success- Authentication successful, session created
Recovery flow states (v2)
Recovery flow states (v2)
recovery_awaiting_address- User enters recovery addressrecovery_awaiting_address_choice- Multiple addresses found, user selects onerecovery_awaiting_address_confirm- Confirming address ownershiprecovery_awaiting_code- User enters recovery codepassed_challenge- Recovery successful
State management
Flow lifecycle
Creation
Flows are created with:- Unique ID - UUID v4 for identification
- Expiration time - Configurable TTL (typically 1 hour)
- Request URL - Original URL for context preservation
- CSRF token - For browser flows only
- UI container - Form structure with nodes
Expiration
Flows expire after a configured duration. Expired flows cannot be submitted:Internal context
Flows maintain internal state inInternalContext (not exposed to clients):
- MFA challenges
- Temporary codes
- Flow-specific state
- Strategy coordination
CSRF protection
Browser flows include CSRF protection to prevent cross-site attacks.How it works
- Kratos generates a CSRF token when creating the flow
- Token is embedded in the UI container nodes
- UI includes token in form submission
- Kratos validates token before processing
Token structure
- Never exposed in JSON responses (note the
json:"-"tag) - Only available when rendering the UI
- Single-use per flow
- Automatically validated by the framework
CSRF tokens are only used in browser flows. API flows do not require or validate CSRF tokens.
UI container
The UI container describes the form structure and is the same for both flow types.Container structure
Nodes
Nodes represent form fields, buttons, scripts, and text:Flow types overview
Registration flow
Creates new identities with trait validation and optional verification. Endpoints:- Browser:
GET /self-service/registration/browser - API:
POST /self-service/registration/api - Submit:
POST /self-service/registration?flow=<id>
Login flow
Authenticates existing identities and creates sessions. Endpoints:- Browser:
GET /self-service/login/browser - API:
POST /self-service/login/api - Submit:
POST /self-service/login?flow=<id>
- Multi-factor authentication (AAL2)
- Forced re-authentication (
?refresh=true) - AAL upgrade requests (
?aal=aal2)
Recovery flow
Recovers access to accounts via recovery addresses. Endpoints:- Browser:
GET /self-service/recovery/browser - API:
POST /self-service/recovery/api - Submit:
POST /self-service/recovery?flow=<id>
Verification flow
Verifies ownership of verifiable addresses (email, phone). Endpoints:- Browser:
GET /self-service/verification/browser - API:
POST /self-service/verification/api - Submit:
POST /self-service/verification?flow=<id>
Settings flow
Allows users to update traits, passwords, and security settings. Endpoints:- Browser:
GET /self-service/settings/browser - API:
POST /self-service/settings/api - Submit:
POST /self-service/settings?flow=<id>
The settings flow requires an active session. Users must be authenticated.
Flow strategies
Each flow supports multiple strategies (authentication methods):- password - Username/password authentication
- oidc - OpenID Connect / OAuth2
- webauthn - WebAuthn / passkeys
- totp - Time-based one-time passwords
- lookup_secret - Backup recovery codes
- code - Email/SMS codes
- link - Magic links
- profile - Profile updates (settings only)
Return URLs
Flows support return URL functionality for post-completion redirects.Browser flows
Return URLs are validated against allowed domains:API flows
Return URLs can be included in flow initialization but are not automatically enforced. Clients handle navigation.Error handling
Flow errors are handled gracefully:Browser flows
- Error occurs during processing
- Flow is updated with error messages
- User redirected back to UI
- UI displays errors in context
API flows
- Error occurs during processing
- HTTP 400 response with updated flow
- Client parses errors from flow UI messages
- Client re-renders form with errors
Best practices
Flow selection
- Use browser flows for traditional web apps
- Use API flows for SPAs and mobile apps
- Never mix browser and API flow patterns
Flow management
- Always check flow expiration before rendering
- Create new flows on expiration
- Don’t cache flow IDs across sessions
- Store flow IDs in URL parameters or temporary storage
Security
- Always include CSRF tokens in browser flows
- Validate return URLs against allowed domains
- Use HTTPS in production
- Implement rate limiting on flow endpoints