Authentication Architecture Patterns

Design enterprise authentication. Covers OAuth 2.0, OIDC, JWTs, session management, passwordless auth, SSO, and choosing between authentication patterns for different application types.

Authentication Architecture Patterns is a guide to the structural decisions that define how systems verify identities across distributed environments. It addresses when and why to choose one approach over another—ranging from single sign-on to federated identity, from token-based flows to zero-trust access. This page focuses on the *how* of authentication: the protocols, flows, data formats, and failure modes that underpin identity systems in modern applications.

Choosing an Authentication Flow

Selecting the right flow depends on the user experience requirements, client types, and security constraints. Each flow defines the sequence of steps between user, client, and identity provider, and its implementation must account for edge cases.

Resource Owner Password Credentials (ROPC)

Use when clients have full control over user credentials and require no user interaction beyond login. Common in mobile apps, IoT devices, and CLI tools.

POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=alice&password=secret&scope=profile email offline_access

The identity provider responds with:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJh bGljZSIsImV4cCI6MTcxMjM0NTYwMCwiaWF0IjoxNzEyMzQ1MjAwLCJpc3MiOiJhY3RpdmUiLCJzdWIiOiJh bGljZSJ9.XYq1rKj9W0j5Qh6a9N4r3u1h8o5vZg5ZmFk5s1b2kC8",
  "refresh_token": "f45d3e2b1a0c9b8d7c6e5f4a3b2c1d0e",
  "expires_in": 3600,
  "token_type": "Bearer",
  "scope": "profile email offline_access"
}

Key failure modes:

Authorization Code with PKCE

Use for public clients—mobile apps, SPAs, and browser-based apps—where the client cannot keep secrets secure.

GET /authorize?
  client_id=spa-app-123
  &redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
  &response_type=code
  &scope=profile email
  &state=abc123
  &code_challenge=7m2J6yqkCkVn5x0dZ1YwU3eCp0sYbPZxN5sQ7oQaJ1c
  &code_challenge_method=S256
HTTP/1.1
Host: auth.example.com

After user authentication, the provider redirects to:

https://app.example.com/callback?code=abc123xyz&state=abc123

The client then exchanges the code using:

POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=abc123xyz
&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
&code_verifier=7m2J6yqkCkVn5x0dZ1YwU3eCp0sYbPZxN5sQ7oQaJ1c

Critical details:

Implicit Flow

Use when the client needs the access token immediately after login, with minimal round trips—ideal for SPAs and static web apps.

GET /authorize?
  client_id=spa-app-123
  &redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
  &response_type=token id_token
  &scope=profile email
  &state=abc123
HTTP/1.1
Host: auth.example.com

The redirect returns:

https://app.example.com/callback#
  access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJh bGljZSIsImV4cCI6MTcxMjM0NTYwMCwiaWF0IjoxNzEyMzQ1MjAwLCJpc3MiOiJhY3RpdmUiLCJzdWIiOiJh bGljZSJ9.XYq1rKj9W0j5Qh6a9N4r3u1h8o5vZg5ZmFk5s1b2kC8
&token_type=Bearer
&expires_in=3600
&id_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJh bGljZSIsImV4cCI6MTcxMjM0NTYwMCwiaWF0IjoxNzEyMzQ1MjAwLCJpc3MiOiJhY3RpdmUiLCJzdWIiOiJh bGljZSJ9.XYq1rKj9W0j5Qh6a9N4r3u1h8o5vZg5ZmFk5s1b2kC8
&state=abc123

Common pitfalls:

Managing Identity Across Systems

When a user authenticates once but accesses multiple services, the architecture must coordinate identity across boundaries.

Single Sign-On (SSO) with SAML 2.0

Use when integrating with enterprise systems—especially legacy applications and identity providers like Okta, Azure AD, or Shibboleth.

The identity provider issues a SAML response as an XML document:

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                ID="_a1b2c3d4e5f6"
                Version="2.0"
                IssueInstant="2024-03-15T12:00:00Z"
                Destination="https://app.example.com/saml/acs">
  <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://idp.example.com</saml:Issuer>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <!-- Signature data -->
  </ds:Signature>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
  </samlp:Status>
  <saml:Assertion ID="_a1b2c3d4e5f6g7h8i9j0" IssueInstant="2024-03-15T12:00:00Z" Version="2.0">
    <saml:Issuer>https://idp.example.com</saml:Issuer>
    <saml:Subject>
      <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified">[email protected]</saml:NameID>
      <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <saml:SubjectConfirmationData NotOnOrAfter="2024-03-15T12:15:00Z" Recipient="https://app.example.com/saml/acs"/>
      </saml:SubjectConfirmation>
    </saml:Subject>
    <saml:Conditions NotBefore="2024-03-15T11:59:00Z" NotOnOrAfter="2024-03-15T12:15:00Z">
      <saml:AudienceRestriction>
        <saml:Audience>https://app.example.com</saml:Audience>
      </saml:AudienceRestriction>
    </saml:Conditions>
    <saml:AttributeStatement>
      <saml:Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname:basic">
        <saml:AttributeValue>[email protected]</saml:AttributeValue>
      </saml:Attribute>
      <saml:Attribute Name="givenName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname:basic">
        <saml:AttributeValue>Alice</saml:AttributeValue>
      </saml:Attribute>
    </saml:AttributeStatement>
  </saml:Assertion>
</samlp:Response>

The service provider validates:

Failure modes:

Federated Identity with OpenID Connect (OIDC)

Use when applications need identity, profile, and session management, and want to leverage a common identity layer.

An OIDC provider exposes a discovery document at /.well-known/openid-configuration:

{
  "issuer": "https://auth.example.com",
  "authorization_endpoint": "https://auth.example.com/authorize",
  "token_endpoint": "https://auth.example.com/token",
  "userinfo_endpoint": "https://auth.example.com/userinfo",
  "jwks_uri": "https://auth.example.com/jwks",
  "response_types_supported": ["code", "code id_token", "id_token", "token id_token"],
  "subject_types_supported": ["public", "pairwise"],
  "id_token_signing_alg_values_supported": ["RS256", "ES256"],
  "scopes_supported": ["openid", "profile", "email", "address", "phone"],
  "claims_supported": ["sub", "name", "email", "email_verified", "picture"],
  "grant_types_supported": ["authorization_code", "refresh_token", "implicit"]
}

Clients use this to discover endpoints and validate tokens.

The id_token is a JWT with claims:

{
  "iss": "https://auth.example.com",
  "sub": "[email protected]",
  "aud": "spa-app-123",
  "exp": 1712345600,
  "iat": 1712345200,
  "auth_time": 1712345100,
  "nonce": "abc123xyz",
  "acr": "urn:mace:incommon:iap:tier1",
  "amr": ["pwd", "mfa"]
}

Critical validation steps:

Common configuration mistakes:

Token Management and Renewal

Tokens are the currency of authentication. How they are issued, stored, and refreshed determines system resilience and user experience.

Refresh Token Rotation

Use when clients need long-lived sessions and want to reduce token leakage.

The refresh token flow includes:

POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=f45d3e2b1a0c9b8d7c6e5f4a3b2c1d0e
&scope=profile email offline_access

The response returns a new access_token, a new refresh_token, and updates the refresh_token in the database.

Key points:

Token Binding and Device Binding

Use when clients want to bind a token to a device or session.

Failure modes:

Token Expiration and Validation

Tokens are validated on every request. The following conditions cause failure:

Common errors:

Identity Federation and Cross-Platform Trust

When multiple systems need to trust each other’s identities, a federation pattern must be established.

Trust Between Identity Providers

Use when users authenticate with one provider but services are hosted by another.

The RP validates the IdP’s signature using its jwks_uri and checks the iss claim in the received token.

Key failure modes:

Token Exchange

Use when a service needs to authenticate on behalf of a user to another service.

POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/json

{
  "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
  "subject_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJh bGljZSIsImV4cCI6MTcxMjM0NTYwMCwiaWF0IjoxNzEyMzQ1MjAwLCJpc3MiOiJhY3RpdmUiLCJzdWIiOiJh bGljZSJ9.XYq1rKj9W0j5Qh6a9N4r3u1h8o5vZg5ZmFk5s1b2kC8",
  "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
  "requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
  "scope": "orders:read orders:write",
  "actor_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJh bGljZSIsImV4cCI6MTcxMjM0NTYwMCwiaWF0IjoxNzEyMzQ1MjAwLCJpc3MiOiJhY3RpdmUiLCJzdWIiOiJh bGljZSJ9.XYq1rKj9W0j5Qh6a9N4r3u1h8o5vZg5ZmFk5s1b2kC8",
  "actor_token_type": "urn:ietf:params:oauth:token-type:jwt"
}

The response includes a new access token, optionally with a refresh_token.

Critical details:

Failures:

Authentication architecture is not a one-time design—it is the continuous work of aligning identity across systems, managing tokens, and handling the subtle failures that arise when users log in, devices authenticate, and services trust one another.

This page was rewritten on 16 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.