Reading Time: 27 minutes

This technical guidance details the implementation of secure identity propagation within MuleSoft Flex Gateway. It outlines the use of two specific OAuth 2.0 patterns:

OAuth 2.0 Token Exchange and In-Task Authorization Code patterns

These patterns enable:

  • Gateway-enforced security: Authentication policies applied at the MuleSoft Flex Gateway layer without backend code changes
  • User context preservation: Original user identity Subject (sub) claim maintained across service boundaries
  • Least privilege access: Service-specific tokens with minimal required scopes
  • Step-up authentication: Multi-factor authentication (MFA) enforcement for high-risk operations

The challenge: Identity in multi-service architectures

Modern enterprise architectures including AI agent networks, MCP tools, microservices, and API ecosystems require secure identity propagation across service boundaries. Key challenges include:

  • Identity propagation: User identity must flow through multi-hop service calls (e.g. Frontend → Agent A → Agent B → API) while maintaining audit trails 
  • Service isolation: Each service must receive tokens scoped to its specific permissions. A token for Service A should not grant access to Service B 
  • Dynamic authentication strength: Low-risk operations may require basic authentication, while high-risk operations require MFA
  • Multi-IdP scenarios: Enterprise B2B and regulated industries often require authentication from multiple identity providers, such as corporate SSO for initial access, and banking IdP for transactions 
  • Zero-trust architecture: Every service boundary requires independent token validation with no implicit trust 
  • Regulatory compliance: Financial services, healthcare, and privacy regulations mandate specific authentication methods and audit trails

Where traditional approaches fail 

Let’s take a look at reasons traditional approaches fail. 

Passing user tokens directly (Security risk) 

  • Violates least privilege: Token has audience (aud) claim containing all services, not just the one being called
  • No service isolation: Compromised Agent B can use token to access Agent C without additional authorization
  • Audit trail confusion: Cannot distinguish which service made which call; all appear to come from user
  • Token lifetime risk: Long-lived token increases exposure window if compromised
  • Privilege escalation: Any service with the token can access any other service in the audience list

Service accounts only (No user context) 

  • Lost user context: Cannot determine which user initiated the request; sub (subject) claim is service account, not user
  • No audit trail: All requests appear to come from service account, violating regulatory requirements
  • Authorization failures: Cannot enforce user-specific permissions 
  • Compliance violations: GDPR, HIPAA, SOX require user identity in audit logs
  • Security risk: Service account compromise affects all users

Frontend-managed token exchange 

  • Increased attack surface: Frontend must manage multiple tokens in browser memory/storage
  • Complexity: Frontend must know entire service topology and request tokens for each
  • Latency: Multiple token requests to IdP before making actual API calls
  • Security risk: Tokens exposed in browser memory, vulnerable to XSS attacks
  • Scalability: Frontend logic changes every time service topology changes

Solutions for these approaches 

MuleSoft Flex Gateway provides two policy-based authentication patterns: OAuth 2.0 Token Exchange (OBO) and In-Task Authorization Code for A2A Protocol-Based Agents. 

Pattern 1: OAuth 2.0 Token Exchange (OBO) 

Use caseService-to-service authentication with single IdP; transparent token exchange 
Characteristics Mechanism: Implements RFC 8693 at gateway layer
Transparent: No user interaction required 
Token transformation: Preserves user identity (sub) while changing authorized party (azp) and audience (aud)
Low-latency: Minimal overhead for token exchange
PolicyOAuth 2.0 OBO Credential Injection Policy

Pattern 2: In-Task Authorization Code for A2A Protocol-Based Agents 

Use caseFor A2A protocol-based agents only requiring step-up MFA, cross-organization access, and high-risk operations
Characteristics Mechanism: Challenges client with WWW-Authenticate header, validates secondary token from different IdP
Step-up MFA: Enforces stronger authentication for high-risk operations
PolicyIn-Task Authorization Code Policy

Architecture overview

Flex Gateway’s outbound authentication policies are the optimal interception point for token exchange and step-up authentication because they:

  • Intercept at the right layer: Policies execute after inbound validation but before backend calls, enabling transparent token transformation
  • Have centralized security: Authentication logic enforced at gateway layer, not scattered across services
  • Face zero backend changes: Services receive properly scoped tokens without code modifications

How outbound policies work

Request Flow:

  • Client → ingress gateway: Client sends request with user token
  • Inbound validation: Gateway validates user token (signature, expiration, audience)
  • Broker processing: Agent broker receives validated request, determines which downstream services to call
  • Outbound interception: Before calling downstream services, outbound policy intercepts the request
  • Token transformation:
    • OAuth2 OBO Credential Injection Policy: Exchanges incoming bearer tokens using the OAuth 2.0 Token Exchange (RFC 8693) or Microsoft Entra ID On-Behalf-Of protocols
    • A2A In-Task Authorization Code Policy: Ensures secondary credentials are present for in-task authentication using OAuth 2.0 Authorization Code flow
  • Backend call: Service receives properly scoped token with preserved user identity
  • Response: Service response flows back through gateway to client

Token exchange between services

When services call other services (service-to-service communication), the outbound policy ensures proper token scoping:

User Token (aud: broker) 
  → Broker receives request
    → Calls Agent A
      → Outbound Policy: Exchange for Agent A token (aud: agent-a, sub: user-id)
    → Calls Agent B  
      → Outbound Policy: Exchange for Agent B token (aud: agent-b, sub: user-id)
    → Calls API
      → Outbound Policy: Exchange for API token (aud: api, sub: user-id)

Pattern 1: OAuth 2.0 Token Exchange (On-Behalf-Of) 

What it doesOAuth 2.0 Token Exchange (RFC 8693) enables the gateway to exchange an incoming user token for a service-specific token while preserving user identity. The Flex Gateway policy handles this exchange transparently, acting as an OAuth client to the IdP.
Concepts Subject token: Incoming user token from authorization header 
Grant type: urn:ietf:params:oauth:grant-type:token-exchange (RFC 8693 standard)Entra: urn:ietf:params:grant-type:jwt-bearer
Token transformation: Changes authorized party (azp) and audience (aud) while preserving user identity (sub)
Token type: Supports urn:ietf:params:oauth:token-type:access_token 
PolicyOutbound Authentication – OAuth 2.0 Token Exchange

User token structure

The user token is issued by the Primary IdP to client: 

{
  "iss": "https://idp.example.com",
  "sub": "user-123-unique-id",
  "azp": "web-application",
  "aud": ["service-a", "service-b"],
  "exp": 1705262400,
  "iat": 1705258800,
  "auth_time": 1705258800,
  "jti": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "acr": "1",
  "amr": ["pwd"],
  "session_state": "8f7e6d5c-4b3a-2918-7654-321098fedcba",
  "preferred_username": "john.doe",
  "email": "john.doe@example.com",
  "email_verified": true,
  "name": "John Doe",
  "given_name": "John",
  "family_name": "Doe",
  "scope": "openid profile email",
  "sid": "8f7e6d5c-4b3a-2918-7654-321098fedcba",
  "typ": "Bearer"
}

Claim explanations

ClaimDescriptionSecurity significance
issIssuer – IdP that issued the tokenValidates token origin; must match expected IdP
subSubject – Unique user identifierPreserved across all tokens for audit trail
azpAuthorized party – Client that requested tokenChanges per service; validates token recipient
audAudience – Services token is valid forRestricts token usage; prevents cross-service attacks
expExpiration time (Unix timestamp)Limits exposure window; shorter for OBO tokens
iatIssued at timeHelps detect token replay attacks
auth_timeTime user authenticatedUsed for session management
jtiJWT ID – Unique token identifierEnables token revocation and replay detection
acrAuthentication Context Class ReferenceIndicates authentication strength (1 = basic, 2 = MFA)
amrAuthentication Methods ReferencesLists methods used (pwd, mfa, otp, etc.)
scopeOAuth scopes grantedDefines permissions; narrowed in OBO tokens

OBO Token 

The OBO Token is issued by Primary IdP for Service A: 

{
  "iss": "https://idp.example.com",
  "sub": "user-123-unique-id",
  "azp": "service-a",
  "aud": ["service-a"],
  "exp": 1705259700,
  "iat": 1705258800,
  "auth_time": 1705258800,
  "jti": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "acr": "1",
  "amr": ["pwd"],
  "scope": "agent:read openid"
}

Key claim transformations

ClaimUser tokenOBO TokenTransformation reason
azpweb-applicationservice-aIdentifies new token recipient
aud[“service-a”, “service-b”][“service-a”]Restricts to single service
exp1705262400 (1 hour)1705259700 (15 min)Reduces exposure window
scopeopenid profile emaildata:read openid profileService-specific permissions

Why this approach? 

Security propertiesOperational benefits
Token scoping: Each service receives a token with minimal required permissions (principle of least privilege)

Audience restriction: aud claim prevents token reuse across services

Authorized party validation: azp claim enables services to verify token was issued for them

User context preservation: sub claim maintains audit trail

Centralized policy: No backend code changes required
Zero application changes: Agents/APIs only validate tokens

Consistent security: Policy enforced uniformly across all services

Simplified token management: Gateway handles token lifecycle

Use cases

ScenarioFlowBenefit
AI agent networkUser → Web App → Gateway (OBO) → Orchestrator → Gateway (OBO) → Recommendation AgentUser identity (sub) preserved through entire chain; complete audit trail
MicroservicesMobile App → Gateway (OBO) → Order Service → Gateway (OBO) → Inventory ServiceEach service receives scoped token; compromised service cannot access others
Partner APIPartner App → Gateway (OBO) → Partner API → Gateway (OBO) → Internal CRMPartner receives limited scope; user context maintained for compliance

Pattern 2: In-task authentication with secondary IdP

In-Task Authorization Code enables step-up authentication with a secondary identity provider for A2A agentic scenarios. This policy is specifically designed for the A2A Protocol’s In-Task Authentication pattern, where agents pass secondary credentials in the request body using the A2A message format. 

When an agent attempts to access a protected resource, the gateway challenges the agent with a WWW-Authenticate challenge, prompting the agent to obtain a secondary token via Authorization Code Flow with PKCE. This policy is designed exclusively for A2A agentic workflows. 

The token extraction path (params.message.parts[].data.auth_credentials.accessToken) follows the A2A Protocol message structure. 

  • A2A protocol compliance: Follows A2A In-Task Authentication specification for secondary credentials
  • WWW-authenticate challenge: Returns auth challenge if no token found in request
  • Token extraction: Extracts token from A2A message body at params.message.parts[].data.auth_credentials.accessToken
  • Header injection: Sets Authorization header with Bearer <token> format for upstream services
  • Credential removal: Removes credentials from body to prevent token leakage

The policy trusts that the agent obtained a valid token through the OAuth2 flow and injects it into the Authorization header. Authentication Context Class Reference (ACR) and Authentication Methods Reference (AMR) enforcement is not performed by the policy itself. These claims should be validated by the upstream service or a separate inbound validation policy if required.

Token structure

Secondary token:

{
  "iss": "https://secondary-idp.example.com",
  "sub": "user-secondary-id",
  "azp": "sensitive-service",
  "aud": ["sensitive-service"],
  "acr": "urn:okta:loa:2fa:any",
  "amr": ["pwd", "mfa", "otp"],
  "scope": "transfer:execute openid"
}

Claims:

  • iss: Different issuer (IdP1 vs IdP2)
  • sub: User identity from secondary IdP
  • aud: Target service audience

While tokens may contain acr and amr claims indicating authentication strength, the In-Task policy does not validate these claims. If ACR/AMR enforcement is required, implement validation in the upstream service or use a separate inbound policy.

Use cases

ScenarioDescriptionCompliance benefit
High-value financial transactionsUser transfers $50K+ → Gateway challenges for MFA → User completes banking IdP auth → Transfer proceedsPSD2 SCA compliance; dual authentication proof
Cross-organization B2B accessPartner authenticates with their IdP → Accesses your resources → Must also authenticate with your IdPBoth organizations maintain authentication control
Risk-based step-upLow-risk (read): primary token only.
High-risk (write/PII): In-Task policy challenges for secondary token
Selective MFA enforcement; reduced user friction

Pattern selection guide 

CriteriaUse OBOUse In-Task
Identity providersSingle IdPMultiple IdPs required
User interactionNone (transparent)Required (step-up MFA)
Latency requirementsLow latency criticalUser interaction acceptable
Trust domainSame organizationCross-organization (B2B)
ComplianceStandard audit trailsExplicit MFA proof required (PSD2, FFIEC)
ThroughputHigh throughput scenariosLower throughput acceptable

Implementation guide 

Let’s go over the prerequisites you’ll need for implementation. 

Identity provider 

OBO PatternIn-Task Pattern
OAuth 2.0 Token Exchange (RFC 8693) grant type

Token endpoint accepting grant_type=urn:ietf:params:oauth:grant-type:token-exchange

Client credentials authentication (confidential client)

JWKS endpoint (RFC 7517) for public key distribution

Support for subject_token, audience, and scope parameters

Ability to configure token exchange permissions (which clients can exchange for which audiences)
OpenID Connect Core 1.0 with Authorization Code FlowPKCE (RFC 7636) for enhanced security

Supported identity providers 

ProviderOBO supportIn-Task supportNotes
Keycloak 18+NativeNativeFull RFC 8693 support
OktaVia Token Exchange APINativeRequires API access token
Azure Entra IDNative (OBO flow)Via Conditional AccessUse microsoft-entra-obo flow
Auth0Via Token ExchangeNativeRequires M2M application
Ping IdentityNativeNativePingFederate 10.3+
ForgeRockNativeNativeAM 7.0+

MuleSoft Flex Gateway:

  • Version 1.11.4 or higher
  • CH2 Runtime
  • Access to API Manager

Backend services:

  • JWT validation capability
  • JWKS endpoint access for signature verification
  • TLS/HTTPS support
  • Ability to extract and validate claims: sub, iss, aud, azp, exp, nbf

Identity Provider configuration

IdP configuration is provider-specific. Refer to your IdP’s documentation for detailed setup instructions: 

OAuth 2.0 Token Exchange (OBO Pattern)Keycloak Token Exchange
Okta Token Exchange
Azure Entra ID On-Behalf-Of Flow
Auth0 Token Exchange
In-Task Authorization Code (Step-Up MFA)Okta MFA and Step-Up Authentication
Azure Entra ID Conditional Access
Auth0 Step-Up Authentication
Keycloak Authentication Flows 
For backend token validation patterns and best practicesJWT Validation Best Practices
OAuth 2.0 Security Best Current Practice

Flex Gateway policy configuration

ParameterDescription
Token Exchange FlowToken exchange flow: OAuth2 Token Exchange (RFC 8693) or Microsoft Entra OBO
Client IDThe OAuth2 client ID for token exchange
Client secretThe OAuth2 client secret for token exchange
Token endpointThe OAuth2 token endpoint URL for token exchange
ScopeOAuth scope to request. Optional for OAuth2 Token Exchange. Required for Microsoft Entra OBO (e.g. ‘api://downstream-client-id/.default’)
Timeout (optional)Request timeout in milliseconds
Target valueThe target audience URI or resource URI for the exchanged token. Required for OAuth2 Token Exchange flow
Target typeParameter type for specifying the target service. Required for OAuth2 Token Exchange flow

Supported values: Audience (logical identifier of the target service) or Resource (physical URI of the target resource)

Notes:

  • The policy automatically handles RFC 8693 token exchange protocol
  • Incoming tokens are extracted from the authorization header by default
  • Exchanged tokens replace the original token in outbound requests

In-Task Authorization Code policy configuration 

ParameterDescription
Secondary auth providerName of the IdP provider. Used for informational purposes in the authentication card 
Authorization endpointOAuth2 authorization endpoint URL. Required for generating the authentication challenge
Token endpointOAuth2 token endpoint URL. Required for generating the authentication challenge
ScopesSpace or comma separated list of OAuth2 scopes required for step-up authentication
Redirect URIOAuth2 redirects URI that the client will use in the authorization flow
Response typeOAuth2 response type. Typically ‘code’ for authorization code flow 
Code challenge methodPKCE code challenge method. Typically ‘S256’ for SHA-256 
Token audienceOAuth2 token audience. The intended recipient of the token 
Body encodingEncoding format for token request body. Typically ‘form’ for application/x-www-form-urlencoded.
Token timeoutToken timeout in seconds for token requests
Challenge response status codeHTTP status code to return for auth-required challenge responses. Typically 200 to maintain JSON-RPC compatibility

Notes:

  • The policy supports both primary and secondary tokens independently
  • When secondary token is missing or invalid, the policy returns a 401 with WWW-Authenticate challenge
  • The client must complete the authorization code flow with the secondary IdP to obtain the secondary token

Agent Network configuration

MuleSoft Agent Fabric uses AgentNetwork YAML files to define brokers, agents, and their connections. Authentication is configured in the connections section using the same authentication patterns we’ve previously described. Authentication is configured per connection in the connections section. The two new authentication types are OAuth2 Token Exchange (OBO) and In-Task Authorization Code.

OAuth2 Token Exchange (OBO): 

connections:
  agent-connection:
    kind: agent
    ref:
      name: my-agent
    spec:
      url: https://api.example.com/agent
      authentication:
        kind: oauth2-obo
        flow: oauth2-token-exchange  # or microsoft-entra-obo
        tokenEndpoint: https://oauth.provider.com/token
        clientId: clientId
        clientSecret: clientSecret
        targetType: audience
        targetValue: https://api.example.com/agents/my-agent
        scope: Read  # Optional for RFC 8693, required for Entra OBO
        timeout: 50000  # Optional, default: 10000ms

In-Task Authorization Code:

connections:
  agent-connection:
    kind: agent
    ref:
      name: my-agent
    spec:
      url: https://api.example.com/agent
      authentication:
        kind: in-task-authorization-code
        secondaryAuthProvider: providerName
        authorizationEndpoint: https://oauth.provider.com/authorize
        tokenEndpoint: https://oauth.provider.com/token
        scopes: Read
        redirectUri: https://oauth.provider.com/callback
        responseType: code
        tokenAudience: https://api.example.com/agents/my-agent
        codeChallengeMethod: S256
        bodyEncoding: form
        challengeResponseStatusCode: 200  # Optional, default: 200
        tokenTimeout: 300  # Optional, default: 300s

To propagate headers from broker to agents, configure headersToPropagate in the broker’s links section:

brokers:
  my-broker:
    spec:
      links:
        - agent:
            ref:
              name: agent-without-auth
        - agent:
            ref:
              name: agent-with-auth
            headersToPropagate: [Authorization, custom-header]
        - agent:
            ref:
              name: another-agent
            headersToPropagate: [Authorization]

Only headers listed in headersToPropagate are forwarded to the agent. This enables fine-grained control over which agents receive authentication tokens.

Complete example:


schemaVersion: 1.0.0
label: Employee Onboarding Network

brokers:
  employee-onboarding-broker:
    spec:
      links:
        - agent:
            ref:
              name: hr-agent
        - agent:
            ref:
              name: badging-agent
            headersToPropagate: [Authorization]
        - agent:
            ref:
              name: transfer-agent
            headersToPropagate: [Authorization]

agents:
  hr-agent:
    label: HR System Agent
  badging-agent:
    label: Badging Agent
  transfer-agent:
    label: Transfer Agent

connections:
  hr-agent-connection:
    kind: agent
    ref:
      name: hr-agent
    spec:
      url: https://hr-agent.example.com/
  
  badging-agent-connection:
    kind: agent
    ref:
      name: badging-agent
    spec:
      url: https://badge-agent.example.com/
      authentication:
        kind: oauth2-obo
        flow: oauth2-token-exchange
        tokenEndpoint: https://oauth.provider.com/token
        clientId: badging-client
        clientSecret: badging-secret
        targetType: audience
        targetValue: https://api.example.com/agents/badging
        scope: Read
        timeout: 50000
  
  transfer-agent-connection:
    kind: agent
    ref:
      name: transfer-agent
    spec:
      url: https://transfer-agent.example.com/
      authentication:
        kind: in-task-authorization-code
        secondaryAuthProvider: bankingIdP
        authorizationEndpoint: https://bank.provider.com/authorize
        tokenEndpoint: https://bank.provider.com/token
        scopes: transfer:execute
        redirectUri: https://oauth.provider.com/callback
        responseType: code
        tokenAudience: https://api.example.com/agents/transfer
        codeChallengeMethod: S256
        bodyEncoding: form
        challengeResponseStatusCode: 200
        tokenTimeout: 300

Achieving secure identity propagation

Secure identity propagation is foundational to building trusted, compliant, and scalable multi-service architectures. OAuth 2.0 Token Exchange (OBO) and In-Task Authorization Code address the core challenges of maintaining user context, enforcing least privilege, and meeting regulatory requirements across service boundaries.

  • Gateway-enforced security: By implementing authentication at the Flex Gateway layer, organizations achieve consistent security enforcement without modifying backend services 
  • User context preservation: Both patterns maintain the original user identity (sub claim) through all service interactions, enabling complete audit trails and user-specific authorization 
  • Pattern selection: Choose OBO for transparent, low-latency service-to-service calls within a single trust domain. Choose In-Task Authorization Code when step-up MFA, multi-IdP scenarios, or explicit user consent is required 
  • Agent Fabric integration: The oauth2-obo and in-task-authorization-code authentication types in AgentNetwork YAML provide seamless integration with existing Agent Fabric deployments 
  • Compliance-ready: These patterns support regulatory requirements including PSD2 SCA, FFIEC, HIPAA, and GDPR by providing verifiable authentication context and comprehensive audit capabilities

For implementation support, refer to the MuleSoft Flex Gateway documentation and Agent Fabric project files documentation.