Skip to content

feat: support provider-managed Cross-App Access (XAA) token flows #2637

Description

@afourniernv

Problem Statement

OpenShell can safely custody provider credentials and inject a final bearer token only into approved sandbox egress requests, but it has no supported way to perform a Cross-App Access (XAA) flow end to end.

XAA lets a requesting application act on a user's behalf against a separately administered resource application without passing a long-lived credential or final API token through the sandbox. The closed experimental proof of concept in #1682 demonstrated this with Okta and xaa.dev, but there is no replacement or tracking issue.

The currently merged NemoClaw reference, NVIDIA/NemoClaw#7265, covers the narrower protected-API case: provider-managed refresh plus endpoint-scoped bearer injection. It does not perform OBO or XAA.

Proposed Design

Provide a provider-managed XAA grant chain that keeps all subject material, client authentication material, intermediate assertions, and final API tokens outside the sandbox.

  1. Obtain a fresh user subject token through a generic dynamic identity source.
  2. At the identity provider token endpoint, exchange that subject token using RFC 8693 for an Identity Assertion JWT Authorization Grant (ID-JAG). The requesting application authenticates with its own registered client relationship.
  3. At the resource authorization server token endpoint, redeem the ID-JAG through the RFC 7523 JWT bearer grant. The resource application authenticates with its independent client relationship.
  4. Store/cache the resulting resource access token under provider custody and inject it only for L7-approved destinations and processes.

The provider contract should model the two stages explicitly: distinct token endpoints, grant types, audiences/resources/scopes, and client authentication material or platform identity. It should also define rotation, caching, expiry, revocation/cleanup, and fail-closed behavior. A blueprint or sandbox may name a provider and credential placeholder, but must not contain OAuth client secrets, subject tokens, ID-JAGs, or final bearer tokens.

Alternatives Considered

  • Reuse feat(provider): support for SPIFFE backed token exchange #1970 unchanged. feat(provider): support for SPIFFE backed token exchange #1970 is useful related work, but its current two-stage flow uses RFC 8693 at one token endpoint with SPIFFE JWT-SVID client assertions. XAA requires an RFC 8693 ID-JAG issuance step followed by an RFC 7523 JWT-bearer step, usually at a separate resource authorization server with separate client registration.
  • Handle XAA in a middleware. Egress middleware intentionally cannot read or replace supervisor-owned Authorization headers, so it is not a credential custody or exchange layer.
  • Give the sandbox the subject token or resource token. This bypasses OpenShell's provider boundary and makes refresh, revocation, and destination restriction harder to enforce.
  • Reopen feat(xaa): add sample xaa provider flow #1682 as-is. That branch was an Okta/xaa.dev-specific proof of concept; the supported surface should be a generic provider capability.

Agent Investigation

Related Work

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