CONCEPT Cited by 1 source
Step-up authentication¶
Definition¶
Step-up authentication is an access-control discipline in which a single session carries a gradient of authenticity levels, and specific high-risk operations require the user to elevate their authenticity (re-enter a password, complete a second factor, present a WebAuthn token, etc.) before proceeding. Low-risk operations may execute at the session's current level; high-risk operations trigger a challenge that upgrades the level for a limited time or for a single operation.
The mechanism contrasts with all-or-nothing session authentication, where every operation after login executes at the same privilege level. Step-up is the discipline that lets "browse my profile" sit in the same session as "transfer funds" without forcing the stronger auth challenge on the browse operation.
OpenID Connect mechanics — ACR values¶
OpenID Connect formalises step-up through the
Authentication Context Class Reference (ACR) value. An
ID token carries an acr claim describing the
authentication level that produced the session (e.g.
urn:mace:incommon:iap:bronze vs …silver vs …gold, or
custom org-defined values). A relying party that needs a
specific authentication level declares it in the
authorization request via the acr_values parameter or the
claims parameter; the OP either satisfies it with the
existing session (if already at that level) or walks the
user through additional challenges.
Zalando uses custom ACR values aligned to their SSO provider and declares them in a custom GraphQL scalar:
The external reference URL is a placeholder in the blog
post; the practical pattern is that each organisation
defines its own ACR-value namespace (e.g. LOW, MEDIUM,
HIGH) and documents the meaning at a @specifiedBy
URL.
Integration with GraphQL: field-level elevation¶
Zalando's UBFF combines public product data with
confidential customer data in a single graph. A request
carrying a product field alongside a customer.email
field must have the appropriate ACR level for the
confidential slice without forcing it on the public slice.
The @isAuthenticated schema directive encodes this per-
field:
directive @isAuthenticated(
"""
The ACR value, which indicates the level of authenticity
expected to perform the operation. Optional — if not
provided, the directive validates a user is authenticated
with no ACR requirements.
"""
acrValue: ACRValue
) on FIELD_DEFINITION
type Query {
customer: Customer @isAuthenticated
}
type Mutation {
updateCustomerInfo(
email: String
phoneNumber: String
): UpdateCustomerInfoResult @isAuthenticated(acrValue: HIGH)
}
Reading the schema tells the reviewer which operations require step-up and at what level — the policy lives with the type definition, not scattered across resolver bodies (Source: sources/2023-10-18-zalando-understanding-graphql-directives-practical-use-cases-at-zalando).
Why step-up matters¶
- Session lifetime ≠ challenge lifetime. A browser session that stays open for hours should not continue to authorise money movement hours after the initial password entry. Step-up decouples the two.
- Blast radius of token theft. A stolen low-level token can browse; it cannot transact. The attacker must still pass the elevation challenge.
- Compliance alignment. PSD2 / SCA, HIPAA privileged- operation rules, and similar regimes explicitly require stronger auth for specific operations; step-up is the implementation affordance.
- UX affordance. Low-friction daily operations stay low-friction; the challenge is reserved for the moments that matter.
Contrast with session-wide re-auth¶
- A session-wide re-auth timeout (e.g. "session expires after 15 minutes of idle") forces a challenge on the next operation, regardless of risk. Step-up is operation-scoped: the challenge happens right before the specific high-risk action, and lower-risk actions after it do not require the elevated level.
- Zero-trust frameworks (concepts/zero-trust-authorization) generally assume every request re-authenticates at the session level and additionally rely on device posture, network segment, etc.; step-up adds a per-operation verification layer on top.
Seen in¶
- Zalando UBFF — schema-directive-driven implementation
via
@isAuthenticated(acrValue: HIGH)on mutations likeupdateCustomerInfo; ACR scalar@specifiedBy-annotated with the org's ACR-value spec URL (sources/2023-10-18-zalando-understanding-graphql-directives-practical-use-cases-at-zalando, systems/zalando-graphql-ubff). - Okta's step-up docs (cited by the Zalando post) — the consumer-facing vendor explanation of when and how to deploy step-up.
Related¶
- patterns/directive-based-field-authorization — the GraphQL-schema-directive implementation canonicalised.
- concepts/graphql-schema-directive — the primitive that carries step-up declarations in the schema.
- concepts/sso-authentication — the broader SSO substrate Zalando's UBFF sits on.
- concepts/zero-trust-authorization — adjacent framework; step-up is a per-operation elevation layer inside a session that may itself be zero-trust.
- systems/zalando-graphql-ubff
- systems/graphql