Skip to content

Add Entra OBO token acquisition to the credential broker #1754

@dbora-nv

Description

@dbora-nv

Problem Statement

OpenShell should support Entra On-Behalf-Of token acquisition at the gateway so user-principal identity can propagate to downstream APIs such as Microsoft Graph, SharePoint, and Outlook without placing the user access token inside the sandbox.
The current options are either service-account access, which loses user attribution and increases confused-deputy risk, or user-token exposure inside the sandbox, which weakens credential isolation. OBO at the gateway preserves both attribution and isolation.

Proposed Design

  1. Accept a validated user-context assertion at the agent session boundary, with the original user token remaining gateway-side.
  2. Allow policy to declare Entra resources, scopes, tenants, and client apps that each agent/tool/binary may request.
  3. When an agent calls a brokered downstream host such as graph.microsoft.com, perform Entra OBO at the gateway and inject the downstream-scoped token on egress.
  4. Cache, refresh, and revoke downstream tokens gateway-side; never expose token material through sandbox environment variables, files, /proc, process memory, or command-line arguments.
  5. Return structured errors for consent missing, MFA required, scope denied, tenant mismatch, and token exchange failure so the agent can surface the right user action.

Acceptance criteria:

  • An agent can call Microsoft Graph as the invoking user without readable token material inside the sandbox.
  • Failed OBO returns a structured error that distinguishes consent, MFA, scope denial, tenant/client mismatch, and transient IdP failures.
  • OBO exchanges log user_principal, agent_id, requested_scope, granted_scope, resource, outcome, and correlation ID.
  • Token refresh and revocation do not require sandbox restart.
  • Sandbox-supplied Authorization headers are rejected for hosts configured for gateway-brokered Entra tokens.

Alternatives Considered

  • Use a service account for downstream APIs: simpler, but loses user attribution and broadens privilege.
  • Pass the user token into the sandbox: preserves user attribution, but breaks credential isolation.
  • Use per-tool local helpers such as gh or SDK credential caches: reduces custom gateway work, but still leaves tokens or refresh material reachable by the agent.
  • Defer until a broader broker exists: delays the most concrete enterprise blocker.

Agent Investigation

  • PR Feat microsoft provider v2 #1424 ("Feat microsoft provider v2", Draft, by @afourniernv) adds a microsoft-agent-s2s provider for Microsoft runtime-agent S2S identity with audience-specific short-lived bearer tokens. The PR's own Design Notes state: "Delegated / OBO user flows are intentionally out of scope for this PR and should likely live under a separate provider later." This issue is that separate provider.
  • PR Feat microsoft provider v2 #1424 delivers credentials to the sandbox via environment variables (A365_TOKEN_PROVIDER_URL, OPENSHELL_MICROSOFT_AGENT_S2S_TOKEN_PROVIDER_URL, OPENSHELL_MICROSOFT_AGENT_S2S_TOKEN_URL). For app-S2S tokens this is acceptable. For user-context tokens it is not, since the user token must never be readable from inside the sandbox. The OBO broker therefore requires a non-env-var delivery contract.
  • Providers v2 documents credential placeholder rewrites and runtime injection behavior, but not gateway-side Entra OBO exchange for user-principal downstream access.
  • The inference.local model already demonstrates a gateway-mediated credential path for LLM providers; this issue asks for the analogous user-principal flow for Entra-backed APIs.

References:

Checklist

  • I've reviewed existing issues and the architecture docs
  • This is a design proposal, not a "please build this" request

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:triage-neededOpened without agent diagnostics and needs triage

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions