Execution Requirements in Keycloak: Required, Alternative, and Disabled
The three little dropdown settings that quietly decide whether your login screen asks for a password, a one-time code, a fingerprint, or all three — and how Keycloak evaluates them step by step.
Picture a bouncer standing at the entrance of a building with a checklist taped to a clipboard. Some items on that checklist are mandatory — everyone must show ID, no exceptions. Some items are “pick one from this group” — show either a keycard or a guest pass, either works. And some items on the checklist have been crossed out entirely — the building used to check for a membership stamp, but that requirement was retired months ago. Keycloak’s login screen is built exactly the same way, and the three settings that decide which checklist items apply — Required, Alternative, and Disabled — are the subject of this article. If you have never opened Keycloak’s Authentication Flows screen before, this is the article that makes that screen make sense.
1What Execution Requirements Actually Are
In Keycloak, the process of logging in is never a single, fixed piece of code. Instead, it is modeled as an authentication flow — an ordered sequence of individual, swappable steps called executions. One execution might check a username and password. Another might send and verify a one-time code by SMS. Another might check whether the browser already has a valid session cookie, allowing it to skip straight through. Each of these executions is a small, self-contained unit that Keycloak can mix, match, and reorder to build very different login experiences without writing new code for each variation.
An execution requirement is the setting attached to each individual execution that tells Keycloak how important that step is, relative to the other steps around it, when the overall flow is evaluated for a real login attempt. There are three requirement levels you will use constantly, and a fourth, more advanced one worth knowing about:
Required
This step must succeed for the login to continue. If it fails, the entire login attempt fails, no matter what other steps exist.
Alternative
This step is one option among a group of alternatives — only one execution in that group needs to succeed for the group as a whole to be satisfied.
Disabled
This step is switched off entirely. Keycloak skips it completely during evaluation, as if it were not part of the flow at all.
Conditional
A newer requirement level used on sub-flows, which only runs its contained steps if a defined condition (like a specific user attribute) is met.
Think of an airport security checkpoint. Showing your boarding pass and ID is Required — everyone does it, no exceptions, and skipping it stops you cold. Choosing to walk through the metal detector or the body scanner is Alternative — you pick one lane, and either one satisfies that stage of the checkpoint. A retired requirement, like an old health-screening desk that used to sit at the end of the line, is Disabled — it is still physically part of the layout, but nobody is asked to stop there anymore.
These settings are configured directly on the Authentication Flows screen in the Keycloak Admin Console, as a small dropdown next to each execution row, letting an administrator reshape the entire login experience without touching a single line of application code.
2Architecture and Core Components
Understanding execution requirements well means understanding the four pieces they interact with inside Keycloak’s authentication engine.
Flow
- A named, ordered container of executions — for example, the built-in “browser” flow used for standard username/password logins.
- A realm can define many flows: one for browser login, one for direct grant (API-style login), one for resetting a forgotten password, and more.
Execution
- A single, concrete step inside a flow — “Username Password Form,” “OTP Form,” “WebAuthn Authenticator,” and dozens of others Keycloak ships with.
- Each execution is backed by a Java class (an “authenticator”) that contains the actual logic for that step.
Sub-Flow
- A flow nested inside another flow, itself treated as a single execution from the parent flow’s point of view.
- Sub-flows are how Keycloak builds grouped choices, like “pick one of: OTP or WebAuthn,” inside a larger overall flow.
Requirement
- The Required / Alternative / Disabled / Conditional setting attached to each execution or sub-flow, controlling how it factors into the pass/fail evaluation of its containing flow.
- This is the setting this entire article focuses on.
It helps to see a concrete, realistic flow layout. Keycloak’s default “browser” flow, in a typical realm, resembles something like this once expanded:
A Realistic Browser Flow Layout
Cookie (Alternative) — checks for an existing valid session. Identity Provider Redirector (Alternative) — checks if the user should be redirected to an external login. Then a sub-flow called “browser forms” (Alternative), which itself contains Username Password Form (Required) followed by a nested “browser conditional OTP” sub-flow (Conditional), which contains OTP Form (Required) — only reached if the user has OTP configured.
Notice something important in that example: the same word “Required” appears at two very different levels of nesting, and it means something slightly different each time depending on which group it belongs to. That nuance is exactly what the next chapter unpacks.
3How Requirement Levels Work Internally
Keycloak’s authentication engine evaluates a flow by walking through its executions in order, top to bottom, applying a specific rule for each requirement level. Understanding these rules precisely — not just approximately — is the difference between designing a flow that behaves as intended and one that quietly locks users out or, worse, lets them skip a step they were supposed to complete.
Required Executions
Every Required execution at a given level must succeed. If any one of them fails, the overall flow fails immediately — evaluation does not continue past that point.
Alternative Executions
Among all the Alternative executions at the same level, only one needs to succeed. Keycloak tries them and treats the group as satisfied the moment any one succeeds — but if a level mixes Required and Alternative executions together, all the Required ones still must pass regardless of what the Alternatives do.
Disabled Executions
Completely skipped. A Disabled execution never runs, never blocks the flow, and never counts toward satisfying an Alternative group. It behaves as if it had been deleted from the flow.
Conditional Sub-Flows
The sub-flow only participates at all if its configured condition passes (for example, “user has a specific attribute” or “user has configured this credential type”). If the condition fails, the entire sub-flow is treated as skipped, similar to Disabled.
An important, easily-missed detail: Alternative only makes sense when there are at least two Alternative executions at the same level to choose between. A single lonely Alternative execution, with no sibling Alternatives at that level, effectively behaves like Required — there is nothing else it could be “an alternative to.”
Think of a restaurant’s fixed-price menu. The soup course is Required — every diner gets it, full stop. The main course is Alternative between three choices — chicken, fish, or a vegetarian option — pick exactly one and the course is satisfied. A seasonal dessert that used to be on the menu but has been crossed out by the chef is Disabled — it simply is not served anymore, and nobody at the table is asked about it.
Sub-flows add one more layer of subtlety worth calling out explicitly: a sub-flow’s own requirement level (Required, Alternative, Conditional, or Disabled) is evaluated from its parent flow’s perspective, exactly like any other single execution. But inside that sub-flow, its own child executions have their own independent Required/Alternative/Disabled settings, evaluated among themselves. This nesting is what allows Keycloak to express fairly sophisticated login logic — “always ask for a password, and then, only if the user has 2FA configured, ask for one of either an OTP code or a WebAuthn key” — using only these four simple settings, applied at different levels of the tree.
4Data Flow and the Evaluation Lifecycle
Tracing a single login attempt from start to finish makes the evaluation logic concrete.
User initiates login
A user is redirected to Keycloak’s login page, which begins executing the realm’s configured flow (for browser-based login, typically the “browser” flow) from its first execution.
Top-level executions run in order
Keycloak walks the top-level list, running Required executions and Alternative executions according to the rules in the previous chapter, skipping anything Disabled.
A sub-flow is reached
When evaluation reaches a sub-flow, Keycloak first checks that sub-flow’s own requirement level and, for a Conditional sub-flow, evaluates its condition against the current user or session.
The sub-flow’s own children are evaluated
If the sub-flow is entered, its own internal executions are evaluated using the same Required/Alternative/Disabled rules, independently of the parent level.
Success or failure bubbles back up
Whether the sub-flow, as a whole, counts as succeeded or failed is reported back to the parent level exactly like any other single execution’s outcome would be.
Final outcome
Once every required piece across every level has been satisfied, the login succeeds and a session is created. If any Required execution or Required sub-flow fails, the login attempt fails immediately, and the user sees an error rather than proceeding further.
flowchart TD
A["Login attempt begins"] --> B["Cookie check
(Alternative)"]
B -- Valid session found --> Z["Login succeeds
immediately"]
B -- No session --> C["Identity Provider Redirector
(Alternative)"]
C -- Redirect configured --> Y["Redirect to
external IdP"]
C -- No redirect --> D["Browser Forms sub-flow
(Alternative)"]
D --> E["Username Password Form
(Required)"]
E -- Fails --> F["Login fails"]
E -- Succeeds --> G{"OTP Conditional
sub-flow: condition met?"}
G -- No, user has no OTP --> H["Flow complete
login succeeds"]
G -- Yes, OTP configured --> I["OTP Form
(Required inside sub-flow)"]
I -- Fails --> F
I -- Succeeds --> H
Fig 1. A realistic browser flow evaluation, showing Alternative, Required, and Conditional levels interacting
5Advantages, Disadvantages, and Trade-offs
Advantages
- Lets an administrator redesign the entire login experience through configuration alone, with no custom code deployment needed.
- Supports gradual, opt-in security rollouts — for example, making OTP Conditional on a user attribute lets a company migrate users to two-factor authentication in stages.
- Reuses a small, consistent vocabulary (Required, Alternative, Disabled, Conditional) across every flow type in Keycloak, so the mental model transfers between browser login, direct grant, registration, and password reset flows.
- Nesting via sub-flows expresses fairly complex login logic without needing a general-purpose scripting language for the common cases.
Disadvantages / Trade-offs
- Deeply nested flows with many sub-flows can become hard to read at a glance, especially for someone new to the realm’s configuration.
- The “a lone Alternative behaves like Required” rule is easy to forget and a common source of confusing, hard-to-diagnose behavior.
- Because flows are shared configuration, a change intended for one use case (say, tightening the browser flow) can unintentionally affect another client relying on the same flow.
- Testing every combination of Required, Alternative, and Conditional paths thoroughly takes real, deliberate effort — it is easy to verify the “happy path” and miss an edge case.
6Security Considerations
Because execution requirements directly control how a user proves their identity, mistakes here have an outsized security impact compared to almost any other Keycloak setting.
Accidentally Disabling a Step
Setting a security-relevant execution (like OTP Form) to Disabled during troubleshooting, and forgetting to re-enable it, silently removes that protection for every future login.
Turning Required into Alternative
Changing a mandatory step to Alternative alongside a weaker option means an attacker only needs to satisfy the weaker of the two paths, not both.
Execution Order Within a Level
Keycloak evaluates executions at a given level in the order they are listed, which can affect which Alternative is attempted first and how early a login can short-circuit — worth reviewing after any reordering.
Poorly Scoped Conditions
A Conditional sub-flow whose condition is too broad or too narrow can unintentionally exempt a group of users from a security step meant to apply to everyone.
Realistic Failure Scenario
A support engineer, trying to help a locked-out user during an incident, temporarily sets the OTP Conditional sub-flow’s requirement to Disabled on the shared browser flow to let that one user back in without their authenticator device. The change is applied realm-wide, not to that one user, and is forgotten after the incident closes. Every user in the realm logs in without two-factor authentication until the change is eventually noticed during a routine configuration review.
For a one-off exception like the scenario above, a narrowly-targeted approach — such as a temporary Conditional rule scoped to that specific user’s attribute, or a completely separate flow assigned only to that one user’s client — avoids weakening the shared flow for everyone else.
7Monitoring, Logging, and Metrics
Because flow configuration mistakes are silent by nature — a Disabled step does not throw an error, it simply stops running — observability is the main defense against them going unnoticed.
| Signal | What It Tells You | Typical Consumer |
|---|---|---|
| Login event log | Records each authentication attempt, which executions it passed through, and the final outcome. | Security / support teams |
| Flow configuration change events | Captures who changed a requirement level, on which flow, and when. | Change-management reviewers |
| Drop in OTP/2FA login events | An unexpected decline in successful two-factor logins can indicate a step was accidentally disabled or made Alternative. | Security engineer / on-call |
| Failed login spikes on a specific execution | Repeated failures concentrated on one execution type can point to a misconfigured Required step or an external dependency (like an SMS provider) being down. | Platform / on-call engineer |
This is similar to a factory’s quality-control line, where each inspection station logs whether an item passed through it. If a manager later notices the log shows items skipping straight past the “final inspection” station entirely, that is the signal something in the line’s configuration was changed — not necessarily something wrong with any individual item.
8Design Patterns and Anti-Patterns
Effective Patterns
- Duplicate before you edit — copy a built-in flow before modifying it, so the original remains available as a known-good fallback.
- Push optional steps into Conditional sub-flows — rather than making a security step Alternative alongside a weaker option, gate it behind a condition so it stays mandatory for whoever it applies to.
- Keep top-level flows shallow — group related choices into a clearly-named sub-flow rather than letting the top level grow long and hard to scan.
- One flow per distinct use case — give a genuinely different login experience (like a kiosk client) its own flow instead of overloading one shared flow with many conditions.
Anti-Patterns to Avoid
- Lone Alternatives — leaving a single execution set to Alternative with no sibling to choose between, creating confusing, Required-like behavior under an Alternative label.
- Disabling instead of removing intentionally — using Disabled as a permanent design choice rather than a temporary, clearly-tracked state.
- Editing the built-in default flows directly — modifying “browser” or “direct grant” in place, making it hard to tell what changed from the out-of-the-box defaults.
- Deep, unnamed nesting — sub-flows inside sub-flows inside sub-flows with generic names, making the tree nearly impossible to reason about months later.
9Best Practices and Common Mistakes
Test With a Real, Non-Admin User
Verify flow changes using an ordinary test account, since administrative accounts sometimes take different code paths that mask the actual experience of a typical user.
Walk Every Branch on Paper First
Before editing a flow, sketch out every Alternative and Conditional branch and what a user sees in each one, to catch logic gaps before they reach production.
Name Sub-Flows Descriptively
Replace generic names with intent-revealing ones, such as “2FA — Conditional for Finance Team,” so future readers understand purpose without reverse-engineering the condition.
Review Flow Assignments Per Client
Remember that different clients can be bound to different flows, so a change to one flow will not silently ripple through to a client using a different, dedicated flow.
Common Mistake #1 — Mixing Required and Alternative at the Same Level Without Realizing the Interaction
Placing a Required execution alongside two Alternative executions at the same level means the Required one always still has to pass, in addition to satisfying one of the Alternatives — a detail that surprises administrators expecting the Alternatives to make the whole level optional.
Common Mistake #2 — Forgetting That Disabled Executions Still Appear in the Console
A Disabled execution remains visible in the flow’s configuration screen, which can make it easy to assume it is still active simply because it is still listed, rather than checking its actual requirement setting.
Common Mistake #3 — Not Re-Testing After Reordering
Because execution order within a level affects which Alternative is reached first and how conditions are evaluated, reordering executions without re-testing the flow can introduce subtle behavior changes that are easy to miss during a quick visual review.
10Real-World and Industry Examples
The idea of a configurable, step-by-step authentication pipeline built from mandatory and optional stages is not unique to Keycloak — it shows up, in different forms, across the identity industry.
Okta Sign-On Policies
Okta lets administrators build layered sign-on policies where certain factors are mandatory and others are offered as interchangeable choices, echoing the same Required-versus-Alternative distinction.
Azure AD Conditional Access
Microsoft Entra ID (formerly Azure AD) applies conditional rules that require additional verification only when certain conditions are met — the same principle behind Keycloak’s Conditional sub-flow requirement level.
Bank and Fintech Step-Up Authentication
Many banking apps require a password for ordinary login but step up to an additional factor only for higher-risk actions like a large money transfer, mirroring a Conditional, situationally-required step.
Companies Running Keycloak
Organizations using Keycloak as a central identity provider commonly build a Conditional OTP flow so employees can be migrated onto two-factor authentication department by department, without forcing every employee onto it on the same day.
Across all of these, the underlying pattern is the same: separate what must always be true from what is one acceptable option among several, and separate both of those from what should only apply in specific circumstances. Keycloak’s Required, Alternative, and Conditional levels are simply a direct, configuration-driven expression of that same widely-used idea.
11Frequently Asked Questions
12Summary and Key Takeaways
Execution requirements are Keycloak’s way of turning a fixed login screen into a flexible, configurable checklist. Required steps are non-negotiable, Alternative steps offer a genuine choice among equals, Disabled steps are switched off entirely, and Conditional sub-flows apply their contents only when a specific circumstance is met. Together, these four simple levels — applied consistently across nested levels of a flow — let an administrator express surprisingly sophisticated authentication logic without writing a single line of custom code. The mechanics are simple once seen clearly; the discipline lies in testing every branch, naming things clearly, and treating changes to shared flows with the same care as any other security-critical configuration change.
Key Takeaways
- Authentication in Keycloak is built from ordered executions inside a flow, each carrying a Required, Alternative, Disabled, or Conditional setting.
- Required means mandatory — its failure fails the whole flow immediately.
- Alternative means “pick one” among sibling executions at the same level, but only when at least two genuine alternatives exist.
- Disabled means completely skipped, as though the execution were removed, though its configuration is preserved for later.
- Conditional sub-flows only run their contained steps when a defined condition is met, enabling staged, situational security requirements.
- Nesting via sub-flows lets a Required step at one level contain its own independent Alternative or Conditional choices underneath it.
- Most real-world problems come from silent misconfiguration — a forgotten Disabled step, a lone Alternative, or an over-broad Conditional rule — making testing, naming, and monitoring the real safeguards.