Skip to content

Add Entra OBO token acquisition to the credential broker #1754

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions