Skip to content

RFC: Identity propagation — credential delegation via AgentCore Identity Token Vault #249

@theagenticguy

Description

@theagenticguy

Summary

Propose identity propagation as a credential, not just as data — completing the identity story that #245 starts on the attribution side. #245 propagates {task_id, user_id, repo, trace_id} so actions are traceable; this RFC makes outbound calls (GitHub, Linear, future Jira/Slack) carry an enforceable per-task, per-repo, short-lived identity via AgentCore Identity Token Vault, so attribution becomes cryptographic rather than advisory.

This is the "Delegation chain propagation" item #245 explicitly defers as out-of-scope follow-up, combined with ROADMAP's "Per-repo GitHub credentials" and "Layered credential derivation."

Drafted by Bonk, reviewed and filed by Laith Al-Saadoon.

Why this is mostly resume, not greenfield

ABCA already runs on AgentCore Runtime, and the identity-propagation plumbing exists end-to-end but is dormant (parked at Phase 2.0a due to a USER_FEDERATION service-side bug; fell back to direct Secrets Manager):

  • Orchestrator already sets runtimeUserId on InvokeAgentRuntimeCommandcdk/src/handlers/shared/strategies/agentcore-strategy.ts:56
  • Orchestrator role already holds bedrock-agentcore:InvokeAgentRuntimeForUsercdk/src/constructs/task-orchestrator.ts:288-289
  • Agent already reads the WorkloadAccessToken header and re-injects it across the pipeline thread (the per-thread ContextVar workaround is already solved) — agent/src/server.py:283-310, 387-413
  • The bedrock-agentcore dep is kept as "vestigial" specifically so this path imports cleanly when resumed — agent/pyproject.toml

Current credential gap

Surface Today Risk
GitHub One shared PAT in Secrets Manager (agent/src/config.py:resolve_github_token) One token, all repos; no per-user/repo scoping (tracked SECURITY.md limitation)
Linear Per-workspace OAuth token in SM, manual refresh (linear-oauth-resolver.ts) Workspace-scoped, not user-scoped; no act-claim audit chain
AgentCore Identity Parked (Phase 2.0a) — fell back to direct Secrets Manager Outbound identity collapses to a shared service credential

Why now

The AgentCore deep-dive (v1.2, 2026-05-13) records OBO (ON_BEHALF_OF_TOKEN_EXCHANGE) GA'd April 2026 across 14 regions and re-grounds the oauth2Flow enum against current API refs. The Phase 2.0a blocker was a USER_FEDERATION service bug; the platform side that parked us has materially changed. Phase 0 below re-validates before we commit.

Design

Shared binding key with #245. AgentCore Identity binds tokens to (workload_identity, user_id). user_id MUST be the same IdP-namespaced value #245 standardizes (e.g. cognito+<sub>, avoiding sub collisions across IdPs). One identity, two planes: #245 stamps it in logs/spans; this RFC stamps it in tokens.

Flow selection (deep-dive §12 decision tree):

Integration Inbound Downstream Flow
GitHub (commit/PR as user) Cognito github.com (different ecosystem) USER_FEDERATION (3LO)
Linear Cognito/webhook linear.app (different) USER_FEDERATION (3LO), replacing manual SM refresh
Headless / webhook-no-user none n/a M2M (client_credentials) under a manual workload identity
Future AWS-native downstream Cognito same ecosystem OBO with act-claim delegation

The honest webhook caveat: webhook-triggered tasks (Linear/Slack/GitHub) authenticate the tenant via HMAC, not the user. The real OAuth consent moment is when the agent calls back out. Read-only triage → M2M service account; write-back → gated on fresh per-user consent.

Token Vault providers replace direct Secrets Manager reads: a GithubOauth2 provider (GitHub App → repo-scoped, short-lived, auto-refreshing installation tokens) retires the shared PAT; AtlassianOauth2/SlackOauth2 follow the same pattern as those integrations land.

Delegation chain (the #245 deferral): where downstream can consume it, use OBO delegation mode (actorTokenContent=M2M) so the issued token carries an act claim recording user → orchestrator → agent — per-action accountability, feeding #237's abca.audit.v1 correlation block.

Backend-agnostic: per SECURITY.md, SessionRole + agent code already serve both AgentCore and the parked ECS backend. Deep-dive §15 documents the raw-boto3 equivalent for ECS, so the agent keeps a single resolve_<integration>_token() seam regardless of how the WAT arrives.

Phasing

  • Phase 0 — Re-validate (spike, no prod change). Confirm USER_FEDERATION/OBO works post-GA for our Cognito→GitHub shape in a throwaway provider. Record go/no-go with date + region.
  • Phase 1 — GitHub via Token Vault (3LO). Stand up GithubOauth2 provider; switch resolve_github_token() to the vault path behind a flag, PAT fallback retained; retire the shared PAT once green. Resolves the SECURITY.md "Shared GitHub PAT" limitation.
  • Phase 2 — Linear onto the vault. Move per-workspace OAuth to the vault provider; delete manual-refresh code.
  • Phase 3 — Delegation chain. OBO act-claim where supported; emit the actor chain into RFC: Governance planes — analytics and compliance export #237's correlation block.

Acceptance criteria

Out of scope

Open questions

  1. Re-validate USER_FEDERATION/OBO post-GA — is the Phase 2.0a service bug resolved for our region/shape? (Phase 0 gate.)
  2. GitHub App vs. per-user 3LO OAuth App — App gives repo-scoped installation tokens (matches "per-repo" ROADMAP item) but is org-installed, not per-user; 3LO gives per-user attribution but coarser repo scope. Leaning App for scoping + commit trailers/act claim for user attribution — decide here.
  3. Consent UX for webhook-triggered tasks with no live user — confirm M2M-service-account-for-read, consent-gate-for-write split.
  4. Token Vault cost — ~$0.010/1k GetResourceOauth2Token fetches; negligible at current volume, noted for feat: Bedrock cost attribution — session tags, request metadata, and operator FinOps guidance #215 forecasting.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Priority 1 — high priorityRFC-proposalRequest for Comments: design proposalenhancementNew feature or requestsecurityCedar/HITL, IAM least-privilege, secrets, PII/DLP, guardrails, supply-chain/CVE

    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