Skip to content

Attribution (AWS half): per-tenant session-broker role with sts:SetSourceIdentity #39

Description

@stxkxs

Part of the agent action attribution roadmap — the AWS half. Companion to
the K8s-half impersonate-RBAC issue and to #38 (direct runtime).

Blocked on Phase 0 — settling the standing hub cluster. Don't start this
until the hub is validated + stable; the role lands on that substrate and can
only be validated against a live cluster + its CloudTrail. Tracking now so the
gap is visible.

What

Add a per-tenant session-broker IAM role that can carry a human/session
sts:SourceIdentity, so agent actions become attributable in CloudTrail.

The runtime (the attributable path — see #38, runs on AgentSandbox/direct) assumes
this role per session with sts:AssumeRole --source-identity=<id> (or
AssumeRoleWithWebIdentity with a custom JWT carrying the
https://aws.amazon.com/source_identity claim). Once set, SourceIdentity is
immutable for the session, survives role chaining, and AWS stamps it into
userIdentity.sessionContext.sourceIdentity on every downstream call — incl.
Bedrock InvokeModel on that session.

Why this shape (not Pod Identity, not plain IRSA)

Verified against AWS docs:

  • Plain IRSA (the EKS-managed OIDC token used today) can't inject a dynamic
    SourceIdentity — the token emits a fixed claim set (sub=system:serviceaccount:…,
    aud=sts.amazonaws.com), no source_identity claim, no hook.
  • EKS Pod Identity can't carry SourceIdentity either (no param; "can't add
    custom tags") — it only auto-attaches infra session tags.
  • sts:SourceIdentity is only reachable via the AssumeRole family with
    sts:SetSourceIdentity in the trust policy. Hence a deliberate broker role, not
    a config flip on the existing tenant IRSA role.

Current state (the gap)

  • Tenant IRSA trust conditions only on :sub / :aud, no sts:SetSourceIdentity,
    no SourceIdentity — operators/internal/controller/platform_iam.go:88-104
    (assumeRolePolicyForOIDC); terraform/components/agent-iam/main.tf:27-40.
  • No STS session role with a SetSourceIdentity trust exists anywhere
    (landing-zone / eks-fleet agent-iam grep is empty).
  • fab already implements the client half (assume-with-source-identity) —
    fab/src/attribution.ts, fab/docs/attribution.md:62-85. This issue is the
    substrate role it assumes into.

Shape of the change

  1. New per-tenant session role in the IRSA factory (agent-iam): trust policy
    principal = the tenant tenant-runtime IRSA role, actions sts:AssumeRole +
    sts:SetSourceIdentity; grants the runtime its model/k8s permissions. Optionally
    a trust condition requiring SourceIdentity be set (so crossbearing's trust
    check scores it attribution-capable rather than anonymous-by-default).
  2. Publish the role ARN (SSM, mirroring the existing IRSA outputs).
  3. Wire FAB_SESSION_ROLE_ARN onto the dispatcher env (set per session alongside
    the operator — see the K8s-half + per-session-operator issues).

Scope / guardrails

  • Off-by-default; opt-in per tenant. Default tenants keep the authentic
    unattributed path.
  • Identity is a scoped synthetic agent:<tenant>:<session>, not arbitrary
    humans. SourceIdentity charset is [A-Za-z0-9_.,+=@-], 2–64 chars.
  • One-tenant pilot before broad enablement.

Independence

crossbearing consumes platform-emitted logs only; nothing crossbearing-specific
lands here. This is a standalone platform capability.

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