| Internet-Draft | OIDC Client Context | March 2026 |
| McGuinness | Expires 16 September 2026 | [Page] |
This specification defines the client_context authorization request parameter for OpenID Connect. The parameter enables a Client to convey structured contextual information to the OpenID Provider (OP) so that the OP can apply context-specific authentication policy, display, claim release, and audit processing when issuing an ID Token.¶
The mechanism is designed for deployments where a single client_id represents multiple logical applications, tenants, or operational purposes, such as AI agents acting on behalf of users or just-in-time administrative workflows requiring privilege elevation.¶
The OP returns the applied context in the ID Token, allowing the Client to verify that authentication occurred under the intended context and to bind subsequent operations accordingly. The returned context is request context confirmed by the OP; it is not, by itself, a durable authorization object or lifecycle-governed authority grant.¶
This note is to be removed before publishing as an RFC.¶
The latest revision of this draft can be found at https://mcguinness.github.io/connect-client-context/draft-mcguinness-connect-client-context.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-mcguinness-connect-client-context/.¶
Source for this draft and an issue tracker can be found at https://github.com/mcguinness/connect-client-context.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 16 September 2026.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
OpenID Connect Core [OIDC.Core] defines a protocol for authenticating End-Users and conveying identity claims to Clients via ID Tokens issued by an OpenID Provider (OP). While this model works well for simple deployments with a one-to-one relationship between a registered client and a logical application, modern deployments increasingly require richer context.¶
A growing class of deployments uses a single registered client_id to represent multiple distinct logical contexts. Consider:¶
Multi-application SaaS platforms. A platform vendor registers one client but hosts dozens of distinct applications (calendar, email, CRM). Each application may require different authentication policies; the email client might allow password authentication, while the financial reporting module requires MFA. The OP has no way to distinguish which application is requesting authentication.¶
Multi-tenant enterprise services. A B2B SaaS provider serves many enterprise customers under one client registration. Each tenant may have its own password policy, MFA requirements, or allowed identity providers (e.g., only employees from example.com may authenticate to the example.com tenant). Without tenant context, the OP cannot enforce per-tenant policy.¶
AI agents acting on behalf of users. An AI assistant platform registers a single client but spawns many concurrent agent sessions, each operating under a specific task or purpose (e.g., "draft a response to these emails" or "provision a new cloud environment"). The OP needs to understand the agent's operational context to determine whether step-up authentication is appropriate and which claims to release.¶
Just-in-time administrative workflows. Any client application, not just a dedicated privileged access management tool, may need to gate a sensitive operation behind a fresh, purpose-specific authentication. For example, a SaaS admin panel, a developer portal, or an internal tooling app might require a user to re-authenticate specifically to register a new OAuth client, approve a change request, or review audit logs, rather than relying on a long-lived general-purpose session. The OP needs purpose context to enforce step-up authentication and restrict the resulting session to that specific operation.¶
Existing OpenID Connect and OAuth 2.0 parameters each serve a distinct purpose but none address client-local identity context:¶
scope indicates which permissions or resources are requested, not why or under which application context.¶
claims (Section 5.5 of [OIDC.Core]) requests specific user attributes to be returned in the ID Token or UserInfo response; it operates in the output direction, shaping what the OP returns. client_context operates in the input direction, shaping how the OP authenticates. The two parameters are orthogonal: claims says "give me these attributes"; client_context says "authenticate under this context".¶
acr_values communicates the desired authentication assurance level, not the business or purpose context that determines what assurance is appropriate.¶
resource ([RFC8707]) identifies the protected resource audience for access tokens, not the logical application or tenant context for authentication.¶
authorization_details ([RFC9396]) conveys structured authorization semantics for access tokens, not contextual metadata for ID Token issuance.¶
None of these parameters provide a structured, extensible mechanism for a Client to communicate the logical context under which authentication is requested.¶
This specification introduces the client_context request parameter to address this gap. The parameter carries a structured object containing typed context members that the OP can use as input to authentication policy, display, claim release decisions, and audit logging. The OP returns the applied context in the ID Token, enabling the Client to cryptographically verify that authentication was performed under the intended context.¶
This specification is guided by the following principles:¶
client_context is request context for authentication policy, display, and audit. It influences authentication behavior and ID Token content, but does not define access token permissions.¶
client_context is not itself a durable authorization object and does not, by itself, define access permissions or lifecycle governance.¶
purpose.kind is the stable purpose-class identifier and the primary policy key for purpose-scoped authentication.¶
params contains purpose-specific, validated instance inputs for authentication policy, display, and audit. It is not a general-purpose extension bag and does not itself define authority semantics.¶
Authorization Servers MAY support only a subset of registered context types. A conformant implementation does not need to support every type defined by this specification.¶
Clients MUST discover or otherwise know which context types an OP supports and MUST be prepared for requests containing unsupported types to fail with unsupported_client_context_type.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
This specification uses the following terms from OpenID Connect Core [OIDC.Core]:¶
OAuth 2.0 Authorization Server that implements OpenID Connect and is capable of authenticating the End-User and providing Claims about the End-User to a Relying Party.¶
OAuth 2.0 Client application using OpenID Connect, also referred to as a Relying Party (RP).¶
JSON Web Token (JWT) that contains Claims about the Authentication event, issued by the OP.¶
The following terms are defined by this specification:¶
Structured information about the logical context under which a Client is requesting authentication, conveyed via the client_context parameter.¶
A registered identifier (e.g., app, tenant, purpose) denoting the semantic category of a context object.¶
A JSON object conveyed in the client_context parameter or claim. The envelope contains a contexts member containing typed context objects. Profiles MAY define additional envelope-level members, but those members are outside base-spec processing unless the profile defines their semantics.¶
A type-specific JSON object contained in the contexts member of a client context envelope.¶
An operational context representing a specific task, workflow, or purpose for which authentication is being requested, as opposed to a general-purpose login.¶
The client_context value supplied by the Client in the authorization request.¶
The context values that the OP validated, normalized as needed, and actually used for authentication policy, display, claim release, or audit processing. Applied context is conveyed in the client_context claim in the ID Token.¶
A reduced, audience-appropriate representation derived from applied context for use in downstream assertions, logs, or correlated systems. Projected context is not required to contain the full client_context value.¶
The following diagram illustrates the flow of a client_context-bearing authorization request through an OpenID Connect interaction.¶
Client OpenID Provider
| |
|-- Authorization Request ----------->|
| client_context: { |
| contexts: { |
| app: { id: "admin_console" }, |
| tenant: { id: "example.com" },|
| purpose: { |
| kind: "https://example.com/purposes/deprovision-user-access" } |
| } |
| } |
| scope, acr_values, claims, ... |
| |
| [Context Validation]
| [Policy Evaluation]
| [Authentication]
| [Context Applied]
| |
|<-- Authorization Code --------------|
| |
|-- Token Request ------------------->|
| |
|<-- ID Token ------------------------|
| acr: "http://...mfa" |
| client_context: { |
| contexts: { |
| app: { id: "admin_console" }, |
| tenant: { id: "example.com" },|
| purpose: { |
| kind: "https://example.com/purposes/deprovision-user-access" } |
| } |
| } |
| ...standard claims... |
| |
| [Client verifies context] |
| [Enables context-bound actions] |
¶
The protocol proceeds as follows:¶
The Client constructs an authorization request that includes requested context in client_context alongside standard OpenID Connect parameters.¶
The OP receives the request and validates the client_context parameter structure.¶
The OP evaluates the supplied context as input to its authentication policy, display processing, claim release, and audit handling, for example, determining that a purpose context with kind https://example.com/purposes/deprovision-user-access requires step-up MFA authentication, or that a tenant context restricts authentication to a specific identity provider.¶
The OP authenticates the End-User according to the derived policy.¶
The OP issues an ID Token that includes a client_context claim reflecting the applied context. This MAY differ from the requested context if the OP normalized values or applied local policy.¶
The Client validates the ID Token, verifies the returned applied context, and enables only the operations appropriate for the confirmed context.¶
For each context type, Required members lists what the Client MUST include. Optional members lists what the Client MAY include. OP policy guidance describes how the OP SHOULD process that type. Each type also identifies its selector field, which is the field used for allow-list enforcement via client_context_values registration metadata.¶
app)
The app context type identifies the logical application within a multi-application client deployment.¶
Required members:¶
idREQUIRED. String identifier for the logical application. The value space is defined by the client and SHOULD be registered in the client's metadata.¶
For the purposes of client_context_values registration metadata, the selector field for app is id.¶
Example:¶
{ "id": "calendar" }
¶
OP policy guidance: The OP MAY use the id value to select an application-specific login theme, restrict claim release to claims relevant to that application, or apply application-specific session policies. The OP SHOULD validate that the requested id is registered as a permitted application for this client_id.¶
tenant)
The tenant context type identifies the organizational tenant on whose behalf authentication is being requested. This is used in multi-tenant deployments where a single client serves multiple organizations.¶
Required members:¶
idREQUIRED. String identifying the tenant. This is typically a domain name (e.g., "example.com"), an internal tenant UUID, or another stable tenant identifier registered with the OP.¶
For the purposes of client_context_values registration metadata, the selector field for tenant is id.¶
Optional members:¶
domainOPTIONAL. The domain associated with the tenant, when the id is not itself a domain. Useful for routing home-realm discovery.¶
Example:¶
{ "id": "example.com" }
¶
OP policy guidance: The OP MAY use tenant context to enforce that only users with verified membership in the tenant may authenticate, redirect to a tenant-specific identity provider for federation, apply tenant-specific password and MFA policies, and include tenant-specific claims in the ID Token (e.g., a tenant identifier claim for downstream services).¶
purpose)
The purpose context type identifies the specific operational task, workflow, or purpose for which authentication is being requested. Purpose context conveys why the authentication is occurring, enabling the OP to apply purpose-specific policy.¶
Purpose context is the primary mechanism for:¶
AI agent task scoping: identifying the specific task an agent is performing on a user's behalf, so that authentication and session scope can be limited to that task.¶
Just-in-time privilege elevation: requesting authentication for a specific administrative action rather than a general administrative session.¶
Automated workflow authorization: identifying a machine-to-machine workflow requiring human authentication for a specific step.¶
Delegated user actions: recording that a user is authenticating to authorize a specific action taken by another entity.¶
The purpose object uses a class/instance model. The kind URI identifies the purpose class: the type of operation being authenticated (e.g., "deprovision user access", "summarize inbox"). The purpose class is stable, registered with the OP, and is the unit against which authentication policy is defined. Instance-specific data such as the specific subject being affected, the ticket number, or the reason code belongs in params. This separation is intentional: the OP's policy engine keys off kind to determine authentication requirements and profile mappings, while params carries the instance inputs that parameterize this specific execution of that class.¶
The purpose object is structured to serve two distinct audiences: a policy engine at the OP that evaluates authentication requirements, and a consent UI that presents the user with a clear description of what they are authorizing. These concerns are separated into distinct sub-objects to avoid ambiguity and enable each consumer to operate independently on its relevant fields.¶
Required members:¶
kindREQUIRED. Absolute URI (per [RFC3986]) identifying the purpose class for this authentication request:¶
What it identifies. The URI names the stable class of operation, not this specific invocation. For example, "https://example.com/purposes/deprovision-user-access" identifies the class "deprovision user access". The specific subject, reason, and ticket reference for this invocation belong in params, not the URI.¶
Stability. The URI MUST be stable across invocations of the same purpose class. Clients MUST NOT encode instance-specific data in the URI.¶
URI format and namespace. https URIs are RECOMMENDED. URNs MAY be used for private or standards-track purpose types. Using a URI provides inherent namespace ownership: the party controlling the URI prefix owns the purpose class definition, enabling interoperability without a central registry. Example values: "https://example.com/purposes/deprovision-user-access", "https://example.com/purposes/approve-change-request", "https://example.com/purposes/summarize-inbox".¶
OP policy key. The OP uses kind as the primary lookup key in its purpose catalog to determine required ACR, session lifetime caps, step-up requirements, and profile-specific mappings. OPs SHOULD validate that kind is registered as a permitted purpose for this client_id before processing the request.¶
For the purposes of client_context_values registration metadata, the selector field for purpose is kind.¶
Optional members:¶
displayOPTIONAL. Object providing human-readable labels for display in the OP's consent and authentication UI. See Section 5.3.2.¶
paramsOPTIONAL. Object containing instance-level parameters specific to this execution of the purpose. The schema of params is defined per kind value; different purpose types carry different parameters. See Section 5.3.3.¶
actorOPTIONAL. Object identifying the entity that triggered this purpose and is requesting the authentication on behalf of the End-User. See Section 5.3.4.¶
constraintsOPTIONAL. Object specifying limiting conditions on the resulting authentication session and tokens. See Section 5.3.5.¶
display Object
The display sub-object carries information for the OP's consent and authentication UI. Its contents are treated as client-supplied labels that the OP SHOULD present to the End-User. display is a request-direction hint: it tells the OP what to show the user; it carries no verification value in the applied context returned to the client. OPs SHOULD omit display from the client_context claim in the issued ID Token. Including display in the returned context provides no additional assurance to the client and unnecessarily inflates the token.¶
titleOPTIONAL. Short human-readable title for the purpose, suitable for a consent screen heading. Example: "Deprovision User Access".¶
descriptionOPTIONAL. Human-readable explanation of the specific task instance, including any relevant context the user needs to make an informed decision. Example: "You are authorizing deprovisioning of all access for bjensen@example.com (ticket HR-8823).". The description SHOULD be specific to the instance, not just the purpose type.¶
localeOPTIONAL. BCP 47 language tag indicating the language of title and description. Example: "en", "fr-CA".¶
params Object
The params sub-object carries the instance-level parameters that distinguish this specific execution of the purpose class from other executions of the same class. Where kind says "what class of operation this is", params says "the specific details of this invocation". Its members are defined per purpose class (identified by kind), MUST be documented in the client's purpose catalog, and MUST NOT be used to carry data that belongs to the purpose class definition itself. This specification does not define params schemas; schemas are defined per purpose class, externally to this specification, by the party that controls the kind URI namespace.¶
Clients and OPs MUST validate params according to the schema and policy associated with the purpose.kind value. Unknown parameter names, malformed values, or values outside the allowed policy for that purpose.kind MUST cause the request to be rejected or the purpose object to be ignored according to local policy.¶
params serves three purposes:¶
Conditional policy evaluation. The OP can write policy rules that branch on parameter values. For example: a purpose with kind https://example.com/purposes/deprovision-user-access where params.reason is security-incident may require a higher assurance level or mandatory re-authentication compared to employment-terminated.¶
Consent display. The OP can use parameter values to construct or supplement its own consent language when display.description is absent or insufficient.¶
Structured audit. Because params is a JSON object rather than a free-text string, audit systems can query and aggregate over it. For example: "all https://example.com/purposes/deprovision-user-access invocations for params.subject in the past 30 days" or "all deprovisioning actions triggered by params.reason of security-incident."¶
Clients SHOULD include only policy-relevant instance attributes in params. params is not a general-purpose authorization descriptor and MUST NOT be used to express resource permissions, downstream access rights, or durable authority semantics.¶
params MAY include policy-relevant target identifiers for an authenticated administrative action, such as a target subject identifier, client identifier, tenant identifier, or deployment environment. params MUST NOT be used to convey command execution state, workflow progress, completion status, or other mutable state that belongs to a downstream command or orchestration protocol.¶
Clients MUST NOT include sensitive personal data in params beyond what is necessary for policy evaluation and audit. Clients SHOULD NOT rely on params values as the sole basis for access control decisions at downstream resource servers; that is the role of access tokens.¶
actor Object
The actor sub-object identifies the entity that triggered the purpose and requested authentication on the End-User's behalf. This enables the OP to apply policy rules based on who or what initiated the authentication, not just what purpose is being performed.¶
actor is OPTIONAL and intended for deployments that need to distinguish direct-user actions from agent- or service-triggered requests. Implementations that do not need this distinction MAY omit actor entirely.¶
typeREQUIRED if actor is present. String indicating the category of the acting entity. RECOMMENDED values:¶
idOPTIONAL. String containing a stable identifier for the acting entity itself (the agent session, service name, or user identifier that names the direct actor). actor.id identifies what is acting. Its interpretation depends on actor.type:
* When type is user: id is a stable identifier for the human user acting as the direct actor (e.g., a platform user ID). If sub is also present, both MUST refer to the same individual.
* When type is agent: id is a stable identifier for the agent instance or agent deployment (e.g., a session ID, model deployment name, or agent registration identifier). It MUST NOT be used to carry the identity of the human principal behind the agent; use sub for that purpose.
* When type is service: id is a stable identifier for the service or application registered with the platform (e.g., a service account name or client ID). It MUST NOT carry a human user identifier.¶
subOPTIONAL. Subject identifier of the human principal on whose authority this actor is acting. actor.sub always refers to a human, regardless of actor.type. When actor.type is agent, sub MUST identify the human user who authorized the agent and MUST NOT contain the agent's own identifier: id names the agent, sub names the human behind it. For user and service types, sub SHOULD be the stable subject identifier of the human who owns or authorized the action, if known.¶
Unverified assertions. The actor value and its sub-fields are client-supplied assertions; they are not authenticated by this parameter alone. The OP MUST NOT treat actor.type, actor.id, or actor.sub as verified facts unless the client has been separately authorized to assert them or the OP verifies them through an independent mechanism.¶
OP policy guidance. When the OP cannot verify actor claims, it SHOULD treat them as advisory context (useful for policy hints and UI display) but MUST NOT rely on them as the sole basis for elevated trust or reduced authentication requirements. When actor.type is agent or service, the OP SHOULD apply more stringent authentication requirements (e.g., mandatory re-authentication, higher ACR) rather than relaxing them, since the presence of a non-human actor represents increased automation risk.¶
Client requirements. Clients SHOULD authenticate the acting entity through independent means (e.g., service-to-service OAuth credentials, platform identity tokens) and convey verified actor identity through those channels before asserting it in actor. Clients MUST NOT fabricate actor.sub values.¶
Clients SHOULD omit actor when the End-User directly starts the authentication within the Client itself with no intermediary.¶
Profiles that need richer delegation-chain semantics MAY define additional actor members or companion structures. This specification does not define a delegation-chain model.¶
constraints Object
The constraints sub-object groups conditions that bound the resulting authentication session and any immediate token outputs of that event. The following distinctions apply:¶
The constraints in this object scope the authentication event and its immediate outputs (session lifetime, token expiry). They are not a durable lifecycle policy.¶
Companion profiles MAY derive longer-lived server-side lifecycle rules from validated constraints, but that derivation is defined by the profile, not this specification.¶
Clients and downstream systems MUST NOT assume the returned constraints object is itself an ongoing authorization lifecycle policy. The returned constraints confirm what the OP applied at authentication time; they do not govern post-issuance authorization decisions.¶
expires_atOPTIONAL. Date-time string ([RFC3339]) after which the applied authentication context for this purpose instance is no longer valid for the intended purpose. The OP SHOULD enforce that any resulting session, token, or other local authorization state used to carry out the purpose does not outlive this value, including refresh tokens where applicable. If expires_at is in the past at the time of processing, the OP MUST reject the request with invalid_client_context_value.¶
max_durationOPTIONAL. Non-negative integer expressing the maximum permitted lifetime of the resulting session and tokens, in seconds, measured from the time of token issuance. When present, the OP SHOULD cap the lifetime of the issued ID Token, access token, and any refresh tokens to this value. If both expires_at and max_duration are present, the OP MUST enforce whichever bound is more restrictive (i.e., whichever results in the earlier expiration). max_duration is a relative constraint and is appropriate when the client cannot predict the exact issuance time; expires_at is appropriate when the authorization is tied to an external deadline (e.g., end of a business day or ticket expiry). Both MAY be present simultaneously to express "no longer than X seconds and no later than Y".¶
The OP SHOULD use kind as the primary key for policy evaluation, looking up authentication requirements (required ACR, session lifetime cap, step-up rules) from its purpose catalog. Companion profiles MAY also use kind as input to a server-side template or policy lookup; for example, mapping a kind URI to a predefined purpose record, authorization template, or approval workflow. Because kind is a stable URI under the client's namespace, it is a reliable join key between the authentication layer and any profile-defined server-side objects.¶
The OP SHOULD present display.title and display.description to the End-User during authentication to provide a complete picture of what the user is authorizing.¶
The OP SHOULD evaluate actor.type when kind alone is insufficient to determine authentication requirements. For example, an OP MAY require re-authentication when actor.type is agent, regardless of existing session state.¶
The OP MAY bind a validated purpose object to the authenticated subject and, when available, to a resulting session identifier such as OIDC sid or a SAML SessionIndex. This allows the returned context to serve as a verifiable record of which subject authenticated for which purpose instance and, where supported, which session carries that applied context.¶
Example: AI agent task¶
{
"kind": "https://example.com/purposes/summarize-inbox",
"display": {
"title": "Summarize Inbox",
"description": "AI Assistant will read your unread emails from the past 7 days and generate a summary.",
"locale": "en"
},
"actor": {
"type": "agent",
"id": "agent-session-a1b2c3",
"sub": "user-9f3d2a"
},
"constraints": {
"expires_at": "2026-04-01T20:00:00Z",
"max_duration": 3600
}
}
¶
Example: just-in-time administrative action¶
{
"kind": "https://example.com/purposes/deprovision-user-access",
"display": {
"title": "Deprovision User Access",
"description": "You are authorizing deprovisioning of all access for bjensen@example.com. This will revoke active sessions, disable the directory account, and remove application assignments (ticket HR-8823).",
"locale": "en"
},
"params": {
"subject": "bjensen@example.com",
"reason": "employment-terminated",
"ticket_ref": "HR-8823"
},
"constraints": {
"expires_at": "2026-04-01T18:00:00Z",
"max_duration": 900
}
}
¶
A minimal conformant implementation of this specification can be small. At minimum:¶
A Client constructs a client_context object containing a non-empty contexts member.¶
An Authorization Server parses the client_context object and validates any supported context types it recognizes.¶
The Authorization Server rejects malformed requests and unsupported context types with the defined errors.¶
If authentication succeeds, the Authorization Server returns the applied client_context in the ID Token.¶
The Client verifies the returned client_context before using it to gate context-sensitive behavior.¶
An implementation does not need to support every context type or every optional member in this specification to claim support.¶
A Client generating an authorization request containing client_context MUST:¶
Encode the parameter value as a JSON object. The object MUST contain a non-empty contexts member; omit the parameter entirely if no context is applicable.¶
Ensure that, when present, the contexts member is a JSON object.¶
Ensure each contexts member name identifies a supported context type and each corresponding member value is a JSON object.¶
Ensure each typed context object's structure conforms to the schema defined for that context type.¶
Include a nonce parameter in the authorization request to bind the resulting ID Token to the request.¶
Clients SHOULD use PAR ([RFC9126]) or a signed Request Object when client_context contains sensitive information such as purpose identifiers or administrative identifiers.¶
When receiving an ID Token in response to a request that included client_context, the Client MUST:¶
Validate the ID Token per Section 3.1.3.7 of [OIDC.Core], including signature verification, issuer, audience, and expiration checks.¶
Verify that the nonce claim in the ID Token matches the nonce sent in the request.¶
If the request included client_context and a token response was successfully received, examine the client_context claim in the ID Token. There are two distinct cases when the claim is absent, and clients MUST handle them differently:¶
Absent because the OP does not support client_context: This case does not arise at this step. An OP that does not support client_context MUST reject the request before issuing tokens (returning unsupported_client_context_type at the authorization or token endpoint). If the client received a successful token response, the OP did not reject the request, so this case does not apply here.¶
Absent from an otherwise valid ID Token: If the ID Token was issued successfully but does not contain a client_context claim, this is a processing failure. The client MUST treat this as a verification failure, MUST NOT proceed with any operations that depend on the applied context, and SHOULD surface a distinct error to the caller indicating that the OP did not confirm the requested context. The client SHOULD NOT silently fall back to using the context it sent in the request.¶
A Client that gates any operation on client_context MUST verify the client_context claim in the validated ID Token. The Client MUST NOT rely on the client_context it sent in the authorization request as confirmation that the OP evaluated or applied that context.¶
Compare the returned context to the requested context. The Client MUST detect and handle:¶
Missing context: A context type that was requested is absent from the returned value. The Client MUST apply local policy to determine whether this is acceptable. For security-critical context (e.g., purpose context for privileged operations), the Client MUST treat missing context as an error and reject the token.¶
Modified context: A context value was altered by the OP (e.g., due to normalization). The Client MUST evaluate whether the modification is acceptable.¶
Additional context: The OP included context objects not present in the request. The Client SHOULD ignore unexpected context types.
Differences limited to request-direction UI hints such as display do not, by themselves, constitute a verification failure unless a profile or local policy explicitly requires equality on those fields.¶
Reject or restrict privileged operations if required context values are absent or inconsistent.¶
The following pseudocode illustrates how a Client might verify returned context for a purpose-bound administrative operation:¶
id_token = validate_and_parse_jwt(token_response.id_token)
# Standard validation
assert id_token.iss == expected_issuer
assert id_token.aud == client_id
assert id_token.nonce == request_nonce
# Context verification
returned_context = id_token.client_context
contexts = returned_context.contexts
purpose = contexts.get("purpose")
if purpose is None:
raise SecurityError("Purpose context missing from ID Token")
if purpose.kind != requested_purpose_kind:
raise SecurityError("Purpose context mismatch")
tenant = contexts.get("tenant")
if tenant is None or tenant.id != expected_tenant:
raise SecurityError("Tenant context invalid")
# All checks passed; enable purpose-scoped operations
enable_operations(purpose.kind)
¶
A SaaS provider serves multiple enterprise customers. Each customer (tenant) may have configured:¶
A specific SAML or OIDC identity provider for their employees.¶
MFA requirements or exemptions.¶
A set of permitted identity attributes to be included in tokens.¶
Example:¶
"client_context": {
"contexts": {
"app": { "id": "project_management" },
"tenant": { "id": "acme-corp.com" }
}
}
¶
The OP uses the tenant context to route the user to Acme Corp's configured identity provider and apply Acme Corp's authentication policy, then returns the tenant context in the ID Token so the application can load Acme Corp's workspace.¶
Just-in-time access is a pattern, not a product category. Any application can adopt it: rather than relying on a broad administrative session established at login, the client requests a fresh authentication scoped to the specific operation the user is about to perform. This reduces the window of exposure if a session is compromised and creates a clear audit trail linking each privileged action to a deliberate authentication event.¶
Example: An admin panel requesting authentication to deprovision a terminated user:¶
"client_context": {
"contexts": {
"app": { "id": "admin_console" },
"tenant": { "id": "example.com" },
"purpose": {
"kind": "https://example.com/purposes/deprovision-user-access",
"display": {
"title": "Deprovision User Access",
"description": "You are authorizing deprovisioning of all access for bjensen@example.com. This will revoke active sessions, disable the directory account, and remove application assignments (ticket HR-8823).",
"locale": "en"
},
"params": { "subject": "bjensen@example.com", "reason": "employment-terminated", "ticket_ref": "HR-8823" },
"constraints": { "expires_at": "2026-04-01T18:00:00Z" }
}
}
}
¶
The OP receiving this request might:¶
Require the user to satisfy a high-assurance authentication policy (e.g., phishing-resistant MFA) regardless of any existing session.¶
Display the purpose details to the user for explicit confirmation.¶
Limit the validity of the applied authentication context so that it does not outlive expires_at.¶
Record the purpose identifier and task details in its audit log.¶
Notify a security team of the elevated access event.¶
The Client then verifies the returned context before enabling the deprovisioning action, ensuring the user cannot perform this action if the OP did not acknowledge the purpose context.¶
OpenID Connect Third Party Initiated Login [OIDC.TPIL] defines a mechanism by which an entity other than the Client (the "initiating party") can start an authentication flow on behalf of a user. The initiating party redirects the user to the Client's login initiation endpoint with parameters, typically iss, login_hint, and target_link_uri, that the Client uses to construct an authorization request to the OP.¶
A common scenario is an application portal or identity hub that launches a specific application in a specific context on behalf of a user:¶
An enterprise portal launching a SaaS application in the context of a specific tenant.¶
An orchestration layer triggering an agent workflow by directing the user to authenticate for a specific purpose.¶
A service desk tool initiating a just-in-time administrative authentication from within a ticket management interface.¶
In each case, the initiating party knows the context under which the authentication should occur, but it is the Client, not the initiating party, that constructs the client_context parameter and sends the authorization request. A mechanism is needed for the initiating party to communicate the desired context to the Client.¶
This specification defines the client_context_hint parameter for use at the Client's login initiation endpoint.¶
client_context_hint Parameter
client_context_hintOPTIONAL. A JSON object in the same envelope format as client_context. Passed by an initiating party to the Client's login initiation endpoint to suggest the context under which authentication should be requested.¶
The parameter is a hint. The Client determines how to use it. The Client MUST NOT forward the hint value directly to the OP without validation.¶
Example: An enterprise portal initiating a login for a specific tenant and application:¶
GET /login-initiation? iss=https%3A%2F%2Fop.example.com &target_link_uri=https%3A%2F%2Fclient.example.org%2Fapp%2Fcalendar &login_hint=alice%40example.com &client_context_hint=%7B%22contexts%22%3A%7B%22app%22%3A%7B%22id%22%3A%22calendar%22%7D%2C%22tenant%22%3A%7B%22id%22%3A%22example.com%22%7D%7D%7D HTTP/1.1 Host: client.example.org¶
The decoded client_context_hint value is:¶
{
"contexts": {
"app": { "id": "calendar" },
"tenant": { "id": "example.com" }
}
}
¶
Example: A service desk initiating a just-in-time administrative authentication:¶
{
"contexts": {
"app": { "id": "admin_console" },
"tenant": { "id": "example.com" },
"purpose": {
"kind": "https://example.com/purposes/deprovision-user-access",
"display": {
"title": "Deprovision User Access",
"description": "You are authorizing deprovisioning of all access for bjensen@example.com. This will revoke active sessions, disable the directory account, and remove application assignments (ticket HR-8823).",
"locale": "en"
},
"params": { "subject": "bjensen@example.com", "reason": "employment-terminated", "ticket_ref": "HR-8823" },
"actor": { "type": "service", "id": "hr-offboarding-system" },
"constraints": { "expires_at": "2026-04-01T18:00:00Z" }
}
}
}
¶
Here the service desk application knows the task being performed but is not itself the application that will perform it; it directs the user to the admin console client to authenticate and execute the action.¶
The Client receiving a client_context_hint at its login initiation endpoint MUST treat the hint as untrusted input from a third party. The following processing rules apply:¶
Parse. The Client MUST parse the hint value as a JSON object. If parsing fails, the Client MUST ignore the hint and proceed with default context or return an error to the initiating party.¶
Validate envelope shape. The Client MUST verify that the hint contains a contexts member whose value is a JSON object, and that the contexts object contains at least one member. If not, the Client MUST ignore the hint or return an error to the initiating party.¶
Validate context types. The Client MUST verify that each context type name under the hint's contexts member is one the Client supports and is permitted for this Client's registration. The Client MUST discard or reject any member whose name is not in the Client's permitted set.¶
Validate context values. The Client MUST validate each field value against its own configuration, for example, confirming that a tenant.id value is a tenant the Client is configured to serve, and that a purpose.kind value is in the Client's list of permitted purpose identifiers. The Client MUST NOT accept context values that would grant access or privilege not authorized by the Client's own policy.¶
Construct client_context. After validation, the Client uses the validated hint, possibly enriched with additional context the Client determines from its own state, as the basis for the client_context parameter in the authorization request to the OP.¶
When a hint includes an actor object, the Client MUST NOT forward that value unchanged unless it has independently authenticated and verified the acting entity. Otherwise, the Client MUST remove the hinted actor or replace it with a locally derived value.¶
Authenticate the initiating party. Clients SHOULD authenticate or verify the origin of the initiation request where possible (e.g., by requiring the initiating party to be a registered application in the same platform, or by verifying a signed initiation token). Unauthenticated initiation requests with client_context_hint SHOULD be limited to low-privilege context types.¶
The result of this processing is that the Client, not the initiating party, is responsible for the client_context that reaches the OP. The hint influences but does not control the authorization request.¶
acr)
The client_context parameter and the acr claim serve complementary but distinct roles. client_context is a request input describing the business context of the authentication. The acr claim is an output describing the authentication assurance that was actually satisfied.¶
The OP MAY use client_context as an input when determining the authentication assurance required. For example, an OP might define policy such as: "any request with a purpose context whose kind matches a high-privilege operation list requires acr phishing-resistant-mfa."¶
Clients SHOULD evaluate both the returned client_context and the acr claim when determining whether to permit privileged operations. A matching client_context with insufficient acr should not be sufficient to authorize a high-privilege action.¶
OAuth 2.0 Resource Indicators ([RFC8707]) allow a Client to identify the protected resource for which an access token is intended, enabling the OP to audience-restrict the access token.¶
The resource parameter indicates the target of an access token. The client_context parameter conveys contextual information driving authentication behavior and ID Token content. These are complementary; both MAY be present in the same request.¶
claims Parameter
The claims parameter (Section 5.5 of [OIDC.Core]) and client_context differ fundamentally in direction. claims is an output request: it tells the OP which user attributes to include in the ID Token or UserInfo response. client_context is an input: it tells the OP the context under which to authenticate the user.¶
A request MAY include both. For example, a purpose-scoped administrative authentication might use client_context to drive step-up MFA policy for a deprovisioning workflow, and claims to request the email attribute for display in the resulting session. The parameters do not interact; each is processed independently by the OP.¶
This discussion is explanatory and does not define additional protocol behavior.¶
client_context is request context for authentication policy, display, and audit. The client_context claim in the ID Token records applied context. Neither value is, by itself, a durable authorization object, an access permission grant, or a lifecycle-governed authority record. A profile or deployment MAY use validated applied context as input to create a separate server-side authority object; this specification does not define that object.¶
Applied context MAY also be used as input to downstream identity or authorization assertions issued by the same OP or an associated component in the same administrative domain. In such profiles, the downstream assertion SHOULD carry projected context rather than the full applied client_context value, purpose.kind MAY serve as a stable join key for profile-defined server-side processing, and UI-oriented fields such as display SHOULD be omitted. Companion profiles MUST define the format, trust model, and issuance rules for any such assertions.¶
An Authorization Server that supports client_context SHOULD advertise this capability in its OpenID Provider Metadata ([OIDC.Discovery]).¶
The following metadata parameters are defined:¶
client_context_types_supportedOPTIONAL. JSON array of strings identifying the context type values supported by this OP. If omitted, clients SHOULD NOT assume any types are supported.¶
client_context_schemasOPTIONAL. JSON object mapping supported context type values to URLs that resolve to JSON Schema documents describing the structure of that context type.¶
client_context_par_requiredOPTIONAL. Boolean. If true, the OP MUST reject any authorization request that includes client_context but was not submitted as a Pushed Authorization Request ([RFC9126]), returning invalid_request. When this flag is set, clients MUST submit client_context via PAR. Default is false.¶
Example discovery document excerpt:¶
{
"issuer": "https://op.example.com",
"authorization_endpoint": "https://op.example.com/authorize",
"client_context_types_supported": [
"app",
"tenant",
"purpose"
],
"client_context_schemas": {
"app": "https://op.example.com/schemas/context/app.json",
"tenant": "https://op.example.com/schemas/context/tenant.json",
"purpose": "https://op.example.com/schemas/context/purpose.json"
},
"client_context_par_required": true
}
¶
The following client registration metadata parameter is defined for use with the OpenID Connect Dynamic Client Registration Protocol [OIDC.Registration] and equivalent static registration mechanisms.¶
client_context_typesOPTIONAL. JSON array of strings listing the context type values that this client is permitted to include in client_context parameters. The OP SHOULD reject requests from this client that include context types not in this list.¶
client_context_valuesOPTIONAL. JSON object mapping context type values to arrays of permitted selector values for that type. Each registered context type definition identifies its selector field. For the context types defined in this specification, app and tenant use id, and purpose uses kind. For example, to restrict a client to specific application IDs or purpose identifiers:¶
{
"client_context_types": ["app", "tenant", "purpose"],
"client_context_values": {
"app": ["calendar", "email", "admin_console"],
"purpose": ["https://example.com/purposes/deprovision-user-access", "https://example.com/purposes/approve-change-request"]
}
}
¶
This registration metadata allows OPs to enforce allow-lists on context values, preventing clients from escalating their context beyond what was administratively approved. Future context type specifications that want to interoperate with client_context_values SHOULD identify a single selector field for registration and allow-list enforcement.¶
Authorization Servers MUST return an error response conforming to Section 4.1.2.1 of [RFC6749] if the client_context parameter is malformed or rejected.¶
The following error codes are defined:¶
invalid_client_contextThe client_context parameter could not be parsed as a JSON object, or the required contexts member is missing or empty, or one or more typed context values are not valid JSON objects, or a required field is missing.¶
unsupported_client_context_typeThe request includes a context type that is not supported by this Authorization Server or not permitted for this client's registration.¶
invalid_client_context_valueA context object contains one or more invalid field values (e.g., an expires_at in the past, an unrecognized kind value for an unsupported purpose type).¶
invalid_requestThe request violates a server policy independent of the context content, such as when client_context_par_required is true and the request was not submitted via PAR ([RFC9126]). This code is defined in [RFC6749] and applied here for PAR enforcement failures.¶
Example error response:¶
HTTP/1.1 302 Found Location: https://client.example.org/cb? error=invalid_client_context &error_description=Context+type+%22purpose%22+is+not+permitted+for+this+client &state=af0ifjsldkj¶
For requests submitted via PAR, errors are returned in the PAR response:¶
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "unsupported_client_context_type",
"error_description": "Context type 'purpose' is not supported by this server"
}
¶
Because client_context influences authentication policy and the contents of ID Tokens, it is important to protect its integrity in transit.¶
Clients SHOULD transmit requests containing client_context using one of:¶
Pushed Authorization Requests ([RFC9126]): Context is submitted directly to the OP over an authenticated server-to-server TLS connection, preventing tampering by user agents or intermediaries. This is the RECOMMENDED mechanism.¶
Signed Request Objects: When PAR is not available, Client SHOULD sign the Request Object containing client_context using the client's private key registered at the OP.¶
Clients MUST NOT transmit sensitive purpose context (e.g., administrative workflow identifiers) as unprotected query parameters where it may be logged by servers, proxies, or browsers.¶
OPs SHOULD retain the applied context used for authentication so that later audit, evidence, or profile-specific processing can determine what context was actually validated and applied.¶
If the OP displayed client-supplied or OP-generated context text to the End-User, the OP SHOULD retain either the rendered display shown to the user or a canonicalized form sufficient to reconstruct what was presented. Profiles MAY bind this retained evidence to approval records, downstream authorization records, or associated audit systems.¶
A malicious party who can modify the authorization request before it reaches the OP could inject or alter context to escalate privileges. For example, substituting a benign application context for an administrative one.¶
Mitigations:¶
Use PAR or signed Request Objects to prevent modification in transit.¶
OPs MUST validate requested context values against the client's registered client_context_values allow-list when one is configured.¶
Clients MUST verify returned context in the ID Token and not assume that submitted context was accepted as-is.¶
A Client that uses client_context to gate privileged operations MUST verify the returned client_context claim in the ID Token before enabling those operations. Failure to verify allows an attacker who obtains an ID Token issued in a different context to abuse it for privileged actions.¶
The returned client_context claim is protected by the ID Token's signature, so verifying the token signature and then checking the claim value provides cryptographic assurance that the OP confirmed the context.¶
Without context binding, an ID Token issued in the context of one application could potentially be replayed in the context of another application hosted by the same client. Including client_context in the ID Token binds the token to the context in which it was issued.¶
Clients SHOULD include nonce in authorization requests containing client_context, and MUST verify the nonce in the returned ID Token. Together with context verification, this prevents token replay across contexts and sessions.¶
A compromised or malicious Client might attempt to request elevated context beyond what is appropriate, for example, requesting purpose identifiers corresponding to highly privileged operations.¶
Authorization Servers SHOULD:¶
When expires_at is included in a purpose context object, the OP SHOULD enforce that the applied authentication context for that purpose does not outlive this value. Any resulting session, token, or other local authorization state used to carry out the purpose SHOULD expire no later than expires_at. Clients SHOULD request a new authentication for a new purpose rather than reusing expired purpose-scoped context. Companion profiles MAY derive longer-lived server-side lifecycle rules from validated constraints, but this specification does not define those lifecycle semantics.¶
The client_context_hint parameter is supplied by an initiating party that may be unauthenticated or partially trusted. An attacker who can send a crafted login initiation request could attempt to inject elevated context values, for example, a purpose identifier corresponding to a privileged administrative workflow, in an attempt to cause the Client to request step-up authentication and then perform an action the attacker desires.¶
Clients MUST validate all hint values against their own allowlists before using them to construct client_context. Clients MUST NOT treat the presence of a hint value as equivalent to the Client's own policy decision to use that context. Where possible, Clients SHOULD authenticate the source of the initiation request before accepting elevated context types such as purpose.¶
For deployments where applied context may serve as approval evidence (for example, purpose-scoped administrative actions or delegated workflows), the OP SHOULD retain a record of the applied context and the consent display actually presented to the End-User at the time of authentication. This record provides evidence that the user was shown an accurate description of the action and chose to authenticate for it.¶
The retained record SHOULD include the applied contexts values, the display content shown to the user, the authenticated subject, and the authentication time. Profiles MAY bind this retained evidence to a downstream authorization record or approval artifact within the OP's administrative domain.¶
This specification does not define retention duration, format, or access controls for retained evidence. Those are deployment and profile concerns.¶
Purpose context MAY contain information that is sensitive from a business or operational security perspective, for example, the name of an administrative action being performed or the identity of a user being affected. Clients SHOULD ensure that purpose context is not unnecessarily logged or exposed.¶
The client_context parameter MAY convey information about the End-User's activities (e.g., which application they are using, the administrative actions they are performing, or the tasks they have delegated to an AI agent). This information is transmitted to the OP and returned in the ID Token, potentially making it available to other parties.¶
Implementations SHOULD minimize the information included in client_context to what is necessary for authentication policy and audit purposes. Free-text fields such as display.description SHOULD NOT contain personally identifiable information beyond what is necessary.¶
When applied context is projected into downstream assertions or other cross-boundary artifacts, implementations SHOULD project only the minimum necessary subset and SHOULD omit UI-oriented fields such as display unless they are specifically required for the audience.¶
OPs MUST handle client_context data in accordance with their privacy policy and applicable law. Context data SHOULD NOT be used for purposes beyond authentication policy evaluation and audit logging without the End-User's explicit consent.¶
This specification requests registration of the following parameters in the "OAuth Parameters" registry defined in [RFC6749].¶
Parameter name: client_context¶
Parameter usage location: authorization request¶
Change controller: IETF¶
Specification document(s): This document¶
Parameter name: client_context_hint¶
Parameter usage location: login initiation endpoint request¶
Change controller: IETF¶
Specification document(s): This document¶
This specification requests registration of the following metadata in the "OAuth Dynamic Client Registration Metadata" registry defined in [RFC7591].¶
| Metadata Name | Specification |
|---|---|
client_context_types
|
This document |
client_context_values
|
This document |
This specification establishes the "OAuth Client Context Type" registry. The registry records context type identifiers that may appear as key names in the contexts member of a client_context envelope.¶
Registration policy: Specification Required per [RFC8126]. Designated experts SHOULD evaluate whether the proposed context type:¶
Has a clear, stable semantics.¶
Does not overlap significantly with existing registered types.¶
Is backed by a publicly available specification.¶
Identifies a single selector field if the type is intended to interoperate with client_context_values registration metadata.¶
Initial registry contents:¶
| Type | Description | Reference |
|---|---|---|
app
|
Identifies the logical application within a multi-application client | This document |
tenant
|
Identifies the organizational tenant associated with the request | This document |
purpose
|
Identifies the operational task or workflow for which authentication is requested | This document |
Private-use context types MUST use URIs as their context type name in the contexts object (e.g., "https://example.com/context-types/custom"). Short string type names (i.e., non-URI strings) are reserved for registered types.¶
This specification requests registration of the following claim in the "JSON Web Token Claims" registry defined in [RFC7519].¶
client_context, acr_values, and authorization_details
This appendix illustrates how client_context, acr_values, and authorization_details ([RFC9396]) work together in a single authorization request. Each parameter operates at a distinct layer and carries information for a different consumer.¶
The scenario: a security operations tool has detected that an employee has been terminated. It initiates a deprovisioning workflow that needs to:¶
Ensure the operator authenticates with phishing-resistant MFA before the action is taken (acr_values).¶
Record in the ID Token that this authentication was specifically for deprovisioning bjensen@example.com, bound to the HR ticket and reason, so the client can confirm the OP evaluated the purpose before enabling any action (client_context).¶
Obtain access tokens scoped to the three resource servers that must be updated: the AS (revoke sessions), the directory service (disable account), and the SCIM provisioning service (remove application assignments) (authorization_details).¶
acr_valuesTells the OP what authentication assurance level is required. The OP uses this to enforce that the user satisfies phishing-resistant MFA before issuing tokens. This is a requirement on the authentication method, independent of any context.¶
client_contextTells the OP why this authentication is occurring. The OP uses the purpose object to enforce that this is a purpose-scoped re-authentication (not a reuse of an existing session), present the operation details to the user on the consent screen, constrain the validity window of the applied context via expires_at, and record the purpose, params, and actor in its audit log. The applied context is returned in the ID Token for the client to verify. That applied context may later be used as input to a separate server-side authority object, but the ID Token claim is not itself that authority object.¶
authorization_detailsTells the authorization server what permissions to encode in the access tokens. Three separate resource servers are targeted: the AS (revoke sessions), the directory service (disable account), and the SCIM provisioning service (remove assignments). Each resource server receives a scoped access token carrying only the permissions it needs. This is enforced at each resource server independently, not by the OP's authentication engine.¶
{
"iss": "https://op.example.com",
"sub": "248289761001",
"aud": "s6BhdRkqt3",
"nonce": "n-0S6_WzA2Mj",
"iat": 1741564800,
"exp": 1741566600,
"acr": "urn:ietf:params:ac:classes:phishing-resistant",
"amr": ["hwk", "pin"],
"email": "bob@example.com",
"client_context": {
"contexts": {
"app": { "id": "admin_console" },
"tenant": { "id": "example.com" },
"purpose": {
"kind": "https://example.com/purposes/deprovision-user-access",
"params": { "subject": "bjensen@example.com", "reason": "employment-terminated", "ticket_ref": "HR-8823" },
"constraints": { "expires_at": "2026-04-01T18:00:00Z" }
}
}
}
}
¶
The acr claim confirms phishing-resistant MFA was satisfied. The client_context claim confirms the applied authentication context for the deprovision-user-access purpose for bjensen@example.com under ticket HR-8823. The client verifies the applied context and acr before invoking any of the three resource servers. Each resource server independently enforces its scoped access token.¶
Authorization Request
|
+----------------+----------------+
| | |
acr_values client_context authorization_details
| | |
v v v
Authentication ID Token Access Token
Policy Content Scoping
| | |
v v v
"Did the user "Was this auth "What can the
satisfy MFA?" for this purpose?" token do?"
| | |
v v v
OP OP Resource Server
(enforced at (verified by (enforced at
auth time) the client) the API)
¶