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
    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