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 (RFC 8693): Used for service-to-service authentication
- In-Task Authentication: Used for step-up authentication, integrating secondary identity providers
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 case | Service-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 |
| Policy | OAuth 2.0 OBO Credential Injection Policy |

Pattern 2: In-Task Authorization Code for A2A Protocol-Based Agents
| Use case | For 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 |
| Policy | In-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 does | OAuth 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 |
| Policy | Outbound 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
| Claim | Description | Security significance |
|---|---|---|
| iss | Issuer – IdP that issued the token | Validates token origin; must match expected IdP |
| sub | Subject – Unique user identifier | Preserved across all tokens for audit trail |
| azp | Authorized party – Client that requested token | Changes per service; validates token recipient |
| aud | Audience – Services token is valid for | Restricts token usage; prevents cross-service attacks |
| exp | Expiration time (Unix timestamp) | Limits exposure window; shorter for OBO tokens |
| iat | Issued at time | Helps detect token replay attacks |
| auth_time | Time user authenticated | Used for session management |
| jti | JWT ID – Unique token identifier | Enables token revocation and replay detection |
| acr | Authentication Context Class Reference | Indicates authentication strength (1 = basic, 2 = MFA) |
| amr | Authentication Methods References | Lists methods used (pwd, mfa, otp, etc.) |
| scope | OAuth scopes granted | Defines 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
| Claim | User token | OBO Token | Transformation reason |
|---|---|---|---|
| azp | web-application | service-a | Identifies new token recipient |
| aud | [“service-a”, “service-b”] | [“service-a”] | Restricts to single service |
| exp | 1705262400 (1 hour) | 1705259700 (15 min) | Reduces exposure window |
| scope | openid profile email | data:read openid profile | Service-specific permissions |
Why this approach?
| Security properties | Operational 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
| Scenario | Flow | Benefit |
|---|---|---|
| AI agent network | User → Web App → Gateway (OBO) → Orchestrator → Gateway (OBO) → Recommendation Agent | User identity (sub) preserved through entire chain; complete audit trail |
| Microservices | Mobile App → Gateway (OBO) → Order Service → Gateway (OBO) → Inventory Service | Each service receives scoped token; compromised service cannot access others |
| Partner API | Partner App → Gateway (OBO) → Partner API → Gateway (OBO) → Internal CRM | Partner 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
| Scenario | Description | Compliance benefit |
|---|---|---|
| High-value financial transactions | User transfers $50K+ → Gateway challenges for MFA → User completes banking IdP auth → Transfer proceeds | PSD2 SCA compliance; dual authentication proof |
| Cross-organization B2B access | Partner authenticates with their IdP → Accesses your resources → Must also authenticate with your IdP | Both organizations maintain authentication control |
| Risk-based step-up | Low-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
| Criteria | Use OBO | Use In-Task |
|---|---|---|
| Identity providers | Single IdP | Multiple IdPs required |
| User interaction | None (transparent) | Required (step-up MFA) |
| Latency requirements | Low latency critical | User interaction acceptable |
| Trust domain | Same organization | Cross-organization (B2B) |
| Compliance | Standard audit trails | Explicit MFA proof required (PSD2, FFIEC) |
| Throughput | High throughput scenarios | Lower throughput acceptable |
Implementation guide
Let’s go over the prerequisites you’ll need for implementation.
Identity provider
| OBO Pattern | In-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
| Provider | OBO support | In-Task support | Notes |
|---|---|---|---|
| Keycloak 18+ | Native | Native | Full RFC 8693 support |
| Okta | Via Token Exchange API | Native | Requires API access token |
| Azure Entra ID | Native (OBO flow) | Via Conditional Access | Use microsoft-entra-obo flow |
| Auth0 | Via Token Exchange | Native | Requires M2M application |
| Ping Identity | Native | Native | PingFederate 10.3+ |
| ForgeRock | Native | Native | AM 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 practices | JWT Validation Best Practices OAuth 2.0 Security Best Current Practice |
Flex Gateway policy configuration
| Parameter | Description |
|---|---|
| Token Exchange Flow | Token exchange flow: OAuth2 Token Exchange (RFC 8693) or Microsoft Entra OBO |
| Client ID | The OAuth2 client ID for token exchange |
| Client secret | The OAuth2 client secret for token exchange |
| Token endpoint | The OAuth2 token endpoint URL for token exchange |
| Scope | OAuth 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 value | The target audience URI or resource URI for the exchanged token. Required for OAuth2 Token Exchange flow |
| Target type | Parameter 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
| Parameter | Description |
|---|---|
| Secondary auth provider | Name of the IdP provider. Used for informational purposes in the authentication card |
| Authorization endpoint | OAuth2 authorization endpoint URL. Required for generating the authentication challenge |
| Token endpoint | OAuth2 token endpoint URL. Required for generating the authentication challenge |
| Scopes | Space or comma separated list of OAuth2 scopes required for step-up authentication |
| Redirect URI | OAuth2 redirects URI that the client will use in the authorization flow |
| Response type | OAuth2 response type. Typically ‘code’ for authorization code flow |
| Code challenge method | PKCE code challenge method. Typically ‘S256’ for SHA-256 |
| Token audience | OAuth2 token audience. The intended recipient of the token |
| Body encoding | Encoding format for token request body. Typically ‘form’ for application/x-www-form-urlencoded. |
| Token timeout | Token timeout in seconds for token requests |
| Challenge response status code | HTTP 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.




