Capability

OIDC / OAuth 2.0 Federation

A full OpenID Connect relying party at the access edge — verified ID tokens, replay-safe flows, and per-tenant IdP routing.

Modern enterprise and consumer IdPs — Entra ID, Okta, Auth0, Google Workspace, GitHub, Keycloak — speak OpenID Connect on top of OAuth 2.0. The right thing for new applications is to plug into that IdP, not maintain a parallel user database. AAM behaves as a standards-correct OIDC relying party in front of the application. The authorization code flow is initiated with PKCE, a nonce, and a session-bound state; the user signs in at the IdP with whatever MFA and policy that IdP enforces; the IdP returns to AAM with an authorization code; AAM exchanges the code for tokens, fetches the IdP's JWKS, and verifies the ID token's signature, audience, issuer, validity window, and nonce before extracting the identity. The verified ID token claims are merged with the userinfo endpoint response and mapped into the canonical AAM session identity. One AAM gateway can route different applications to different IdPs, and different tenants of the same application to different IdPs, at the same time. The rest of the access engine — conditional access, posture, edge MFA, Backend SSO — composes on top of the OIDC session. Every step is audited; ID token validation outcomes (signature, nonce, audience, issuer, expiry) are first-class audit events so the security team can reason about "who signed in via which IdP, with which result" from a single stream.

OIDC + OAuth 2.0
Standards-correct relying party — authorization code, PKCE, JWKS-verified ID tokens, nonce and state defenses.
S256 PKCE
Default code-challenge method — intercepted codes cannot be redeemed by an attacker.
Shared JWKS cache
1-hour TTL across worker processes and gateway instances, with on-miss refresh for IdP key rotation.

OIDC looks simple from the outside — and is full of footguns when implemented per-app

OpenID Connect on top of OAuth 2.0 is the dominant federated identity protocol for modern stacks. Every major enterprise IdP supports it; every cloud workforce IdP exposes it; every modern application framework offers a library for it. The temptation is to assume that adding a few lines of SDK code per application is enough.

In practice, an OIDC relying party that handles real production traffic must do a long list of things correctly. The ID token's signature must be verified against the IdP's published JWKS, with the correct key selected by kid and the cache refreshed when the IdP rotates keys. The audience claim must match the configured client ID. The issuer must match the configured expected issuer. The expiry must be checked with a bounded clock-skew tolerance. The nonce in the ID token must match the nonce AAM sent in the authorization request — and if it doesn't, that's a replay attempt, not a parsing error.

The OAuth 2.0 layer underneath has its own footguns. State must be CSRF-bound to the user's session and have a short TTL. PKCE must be used (S256 ideally) so an intercepted authorization code cannot be redeemed by an attacker. Mixup attacks — where an attacker tricks the relying party into talking to the wrong IdP — are defeated by binding the callback to a specific IdP and validating issuer accordingly. None of these defenses are automatic in a naïve SDK integration.

The other failure mode is embedding the OIDC SDK directly into every application. Each app then carries its own copy of the trust decisions, the JWKS cache, the audit logging, and the IdP configuration. A single IdP change becomes a coordinated multi-application rollout. MFA, conditional access, posture, and logout behaviour end up re-solved per application, often inconsistently.

OIDC belongs at the access edge — verified once, correctly, in one place that already runs MFA, conditional access, posture, and Backend SSO. The application stays out of the federation protocol and receives a clean, validated identity instead.

How we approach it

One AAM gateway terminates OIDC correctly at the edge; the rest of the access engine composes on top.

Full OpenID Connect relying party plus OAuth 2.0 client

Authorization code flow with PKCE, ID token signature verification via JWKS, nonce-bound replay defense, state-bound CSRF defense, audience/issuer/validity enforcement. The same engine speaks plain OAuth 2.0 for IdPs that don't expose an ID token, so token-only providers and full OIDC providers share one codebase.

Per-application and per-tenant IdP routing

One AAM gateway can route different applications to different IdPs, and different tenants of the same application to different IdPs, at the same time. IdP selection happens per request from the application or tenant context — no separate gateway per IdP, no manual chooser for the user.

Replay, CSRF, and mixup attacks defeated by default

Nonce binds the ID token to the authorization request that asked for it; state binds the callback to the user's session; PKCE binds the code redemption to the original public client. None of these are optional flags that an integrator can forget — they are the default flow.

Composed with MFA, conditional access, posture, and Backend SSO

An OIDC authentication does not stand alone — it composes with edge MFA (if the IdP didn't enforce step-up itself), with conditional access predicates, with continuous trust evaluation, and with Backend SSO injection toward the downstream app. The ID token becomes one input into the AAM session, not the whole session.

Capabilities

Standards-correct OIDC relying party plus the operational features that make federation safe and manageable at scale.

Authorization code flow with PKCE (S256 default)

AAM initiates the OAuth 2.0 authorization code flow with PKCE enabled by default — code_challenge_method=S256, a fresh code_verifier per request, never reused. An intercepted authorization code cannot be exchanged for tokens by an attacker that didn't generate the verifier. Plain PKCE remains available for IdPs that demand it; S256 is the configured default.

ID token signature verification against the IdP's JWKS

On callback, AAM fetches the IdP's JWKS, selects the signing key by the ID token's kid header, and verifies the ID token's signature with the algorithm declared in the header (RS256 and the rest of the standard family). A cache miss on kid triggers an immediate JWKS refresh so an IdP key rotation does not stall valid logins.

Audience, issuer, validity, and nonce enforced — not just parsed

The ID token's audience claim must include the configured client ID, the issuer must match the configured expected issuer, the validity window (exp/nbf) is enforced with a bounded clock-skew tolerance, and the nonce must match the nonce AAM sent in the authorization request. A nonce mismatch is treated as a replay-attack signal with its own audit event, not as a parsing error.

Shared JWKS cache with on-miss refresh for key rotation

JWKS responses are cached in a shared store across worker processes and gateway instances with a 1-hour TTL. A cache hit avoids the network round-trip on every login; a cache miss on the requested kid triggers an immediate refresh from the JWKS URI so a routine IdP key rotation does not produce a login outage.

OIDC parameters: scope, display, max_age, ui_locales, acr_values

Standard OIDC authorization parameters are first-class configuration: scope (openid auto-added), display for the IdP login UX, max_age for forced re-authentication, ui_locales for localised IdP pages, and acr_values for requesting a specific authentication context class — useful for asking the IdP to enforce step-up MFA.

Built-in provider profiles plus fully custom IdPs

Built-in profiles ship with sensible defaults for common providers (well-known endpoints, JWKS URIs, scope conventions). A custom-IdP path remains for any standards-compliant OIDC or OAuth 2.0 provider that needs endpoints, scopes, and mappings supplied explicitly.

ID token claims merged with userinfo, signed claims taking precedence

After signature verification, the ID token's claims are merged with the response from the IdP's userinfo endpoint. Signed ID token claims take precedence over unsigned userinfo fields where they overlap, so an attacker who tampered with a userinfo response cannot quietly override a signed identity claim.

Roadmap — RP-Initiated Logout, back-channel logout, dynamic client registration

RP-Initiated Logout (the OIDC spec's signed front-channel logout) and back-channel logout for session termination notifications from the IdP are on the roadmap. OIDC dynamic client registration — onboarding a new application by registering with the IdP automatically — is also planned. The session and audit plumbing already accommodate these flows.

Operational depth

The mechanics that keep an OIDC federation safe, current, and observable.

01

State binding with 10-minute TTL and session check

The OAuth state parameter is stored against the user's session with a 10-minute TTL. On callback, AAM verifies the state belongs to the same session that initiated the flow — an attacker who replays a state value into another user's browser is rejected with an OAUTH_STATE_MISMATCH audit event.

02

Audit on every ID token verification skip — by leaf cause

When ID token signature verification is skipped for any operational reason — JWKS unavailable, no matching kid, malformed JWK, missing JWKS URI — a dedicated audit event records the specific leaf cause. Operators can distinguish a transient JWKS outage from a misconfiguration from an unsupported key type without re-reading runtime logs.

03

Clock-skew tolerance bounded per IdP

ID tokens carry iat, nbf, and exp timestamps. Real clocks drift; AAM applies a bounded clock-skew tolerance (60 seconds by default for the underlying JWT verifier) so small drift does not reject valid logins while large drift — which indicates misconfiguration or replay — still rejects.

04

Token exchange and userinfo with hardened network timeouts

Token exchange and userinfo requests against the IdP use bounded connect, DNS, and overall timeouts so a slow or unresponsive IdP cannot tie up gateway workers. Token exchange runs on a 30-second overall budget; userinfo runs on a 15-second budget; both have shorter connect and DNS budgets so failures fail fast.

05

Per-event audit with correlation back to the AAM session

Every step of the OIDC flow — flow start, callback success, token exchange (with which tokens were returned), ID token signature verification outcome, JWKS fetch outcome — is recorded with a correlation ID that ties back to the AAM session and the downstream backend(s). Forensic reconstruction of "who signed in via which IdP and when" is a single-query operation.

06

Roadmap — automated provider discovery and JWKS rotation telemetry

Automated OIDC provider discovery via the .well-known/openid-configuration endpoint, with operator alerting when discovered endpoints or signing-key sets change, is on the roadmap. JWKS rotation telemetry — metrics on signing-key churn, days-until-current-key-expiry hints, automated rotation runbooks — is also planned.

Where teams use it

Modern enterprise IdPs (Entra ID, Okta, Auth0, Keycloak)

Existing enterprise IdPs that already authenticate the workforce over OIDC. AAM plugs in as a relying party without asking the IdP team to change anything. New applications join the federation by adding an entry to AAM, not by adding an OIDC SDK to each codebase.

Workforce social IdPs (Google Workspace, GitHub)

Internal tooling that authenticates against the organisation's Google Workspace tenant, or developer tooling that uses GitHub as the IdP. AAM speaks OIDC to Google and OAuth 2.0 to GitHub from the same engine, mapping each into the canonical AAM session shape.

Multi-tenant SaaS with per-tenant OIDC IdPs

SaaS applications where each customer brings their own OIDC IdP. One AAM gateway fronts all tenants; each tenant's traffic routes to that tenant's IdP. Adding a tenant is a configuration change in the IdP registry, not a deploy.

Edge MFA and conditional access on top of an OIDC IdP

Some IdPs authenticate but don't enforce step-up MFA or conditional access for every application equally. AAM accepts the IdP's authentication, then composes its own MFA, conditional access predicates, and continuous trust evaluation on top before granting access to the application.

Common questions

Which IdPs does AAM federate with over OIDC and OAuth 2.0?
Any standards-compliant OIDC or OAuth 2.0 IdP. In practice that includes Entra ID (Azure AD), Okta, Auth0, Keycloak, Google Workspace, GitHub, and any custom IdP that exposes the standard endpoints. Built-in profiles ship with sensible defaults for common providers; a custom-IdP path remains for any standards-compliant provider that needs endpoints, scopes, and mappings supplied explicitly.
How does AAM defend against ID token replay, CSRF, and mixup attacks?
Nonce binds the ID token to the authorization request that asked for it — a mismatch is a dedicated replay-attack signal with its own audit event. State binds the callback to the user's session with a 10-minute TTL — a replay across sessions is rejected. PKCE (S256 by default) binds code redemption to the original client — an intercepted authorization code cannot be exchanged for tokens by an attacker. Mixup attacks are defeated by binding the callback to a specific IdP and validating the issuer claim accordingly.
What happens when the IdP rotates signing keys?
JWKS is cached in a shared store with a 1-hour TTL. On callback, AAM selects the signing key from cache by the ID token's kid header. If the kid is not in the cached set — which is what happens immediately after an IdP key rotation — AAM triggers an immediate JWKS refresh from the JWKS URI and retries selection. A routine key rotation does not produce a login outage.
What's the difference between OIDC and plain OAuth 2.0 in this page?
OIDC adds an identity layer on top of OAuth 2.0: a signed ID token containing identity claims is returned alongside the access token. AAM speaks both. For OIDC providers, the ID token is verified against the JWKS and merged with the userinfo response, with signed claims taking precedence. For plain OAuth 2.0 providers (no ID token), AAM relies on the userinfo response alone for identity and applies the same audit, state, and PKCE defenses around the flow.
What happens to the identity after AAM consumes the tokens?
The verified ID token claims and the userinfo response are merged and mapped to the canonical AAM session fields (username, email, groups, display name, custom attributes). That session is what the rest of the access engine reasons about — MFA gating, conditional access predicates, continuous trust evaluation, Backend SSO injection toward the downstream application. The application receives the identity in whatever shape it expects via Backend SSO; the OIDC protocol stops at the AAM edge.

OIDC done correctly, at the edge

We'll connect AAM to your OIDC IdP — enterprise, cloud, or self-hosted — and let the rest of the access engine compose MFA, conditional access, posture, and Backend SSO on top of the verified ID token.