Previous slide Next slide Toggle fullscreen Open presenter view
Delegated API access with OAuth on-behalf-of
Optional implementation module
Preserve signed-in user authority across a trusted middle tier.
Control objective
A trusted Python middle tier exchanges the signed-in user's assertion for a delegated token for the
protected downstream API.
The check shows one allowed call and one denial caused by missing downstream user authority.
Why it matters
Problem. A workload identity gives every request the same application authority. That does not
work when the downstream API must decide for the signed-in user.
Solution. OBO carries user context across the middle tier without forwarding the original
bearer token.
Control boundary
In scope: delegated permissions and consent, inbound token checks, the OBO exchange, protected certificate use, and payload-free checks.
Use the existing applications and downstream authorization model. The downstream API owner manages
resource assignments and any new user grants.
Architecture and authority
Certificate custody
What this means
In the OAuth on-behalf-of (OBO) flow, the inbound token stops at the middle tier. Microsoft Entra
ID issues a delegated token for the downstream API. The API can then allow one user and deny
another.
Tradeoffs behind this design
Engineering choice
Route used here
What the team accepts
Authority at the API
OBO delegated token
Consent and separate token audiences
Middle-tier identity
Protected certificate PFX
Rotation; nonexportable HSM keys need another design
Existing registrations
Merge exact entries
Preflight compares live state because Graph has no what-if
Boundary check
Permitted and denied users
Two users with different downstream access
Decision gate 1 - Is user authority required?
Choose OBO only when:
the downstream resource is user-owned or user-scoped;
the downstream API evaluates the signed-in user; and
application-only authority would be too broad or incorrect.
Otherwise, stop here and use a workload identity.
The inbound token stops at the middle tier
The Python component validates:
issuer and tenant;
middle-tier audience;
approved calling client;
lifetime and signature;
signed-in user claim; and
delegated access_as_user scope.
The original bearer token never reaches the downstream API.
OBO creates a new delegated token
The middle tier uses MSAL with the protected PFX and sends:
the validated user assertion;
its own client identity; and
certificate-based client authentication.
Microsoft Entra ID issues a token for the approved downstream delegated scope.
Decision gate 2 - Consent and scope
The identity owner approves:
client to middle tier: access_as_user;
middle tier to downstream API: Policy.Read; and
the approved consent type.
Stop if an existing grant is ambiguous or the requested scope is broader than the read operation.
Downstream authorization still decides
A successful exchange shows that Microsoft Entra ID accepted the trust chain. The downstream API
must still check the delegated scope and that user's resource assignment.
Intended path and failure path
Check
Expected result
Allowed user
2xx plus downstream-authorized
User without downstream access
401/403 plus downstream-denied
No application-only retry. No token or payload logging.
Implement the operational control
Complete the application, permission, and token claim files.
Bind the exportable Key Vault certificate as a protected PFX.
Preview and apply the delegated permissions listed in the module record.
Deploy the Python middle tier through the normal pipeline.
Run the allowed and denied checks.
Stop conditions
Inbound token reaches the downstream API
Application-only token enters the OBO path
Permission or consent is broader than the approved scope
Certificate leaves the approved runtime
Assertion, token, or payload enters diagnostics
Downstream denial is replaced with a workload-authorized retry
Operating ownership
Owner
Operational responsibility
Identity
Delegated scopes, consent, certificate registration
Application
Inbound validation, OBO exchange, error handling
Downstream API
User-specific resource authorization
Operations
Payload-free logs and certificate expiry
Direct prerequisites and authority
Existing Microsoft Entra registrations identify the client, confidential middle tier, and downstream API.
The middle tier exposes its own audience and User access_as_user scope. The downstream API exposes a different audience and narrow delegated read scope.
A named customer identity owner approves the exact delegated permissions and consent.
Choose signed-in user OBO only when the downstream API must authorize each user. Shared or background work uses application-only managed identity and is outside this module.
Notes: This module is selected by architecture need and stays outside the numbered sequence.
Notes: The exchange preserves user authority. The downstream API still makes the resource decision.
Notes: Use this module only for a real per-user authorization requirement.
Notes: The existing client, middle tier, and downstream API are approved inputs.
Notes: The client gets a token for the middle tier. The middle tier validates it, then uses the user assertion and its certificate to request a downstream token from Microsoft Entra ID. Entra issues the token. The downstream API authorizes resource access for each user.
Notes: Keep the PFX in the approved Key Vault integration. The repository stores references, never the key.
Notes: OBO fits only when the API must decide for the signed-in user. Use workload identity for shared or background work.
Notes: Do not add delegated consent to a shared background operation.
Notes: Token forwarding is not OBO.
Notes: The certificate authenticates the middle tier. The assertion identifies the user.
Notes: The configure scripts merge the module entries and preserve unrelated permissions.
Notes: This is why the module needs a denied-user check.
Notes: The two users must differ at the downstream resource boundary.
Notes: Any one of these changes the authority boundary.
Notes: Restore removes exact module-owned permissions and grants, not the applications.
Notes: The authority decision, registrations, API audiences, scopes, and identity owner are direct prerequisites. No numbered session is required.