Skip to main content

Credential mediation — short-lived scoped tokens

The strongest way to shrink an agent's blast radius is to stop handing it ambient, long-lived credentials at all. When a policy decision is scoped_token, Unveilr's broker mints a short-lived credential scoped to the exact action and resource, bound to the decision that authorized it — so the agent proceeds with the least authority the task needs, for as short a time as possible.

This is the runtime companion to Govern: same one decision brain, a new outcome that reduces authority instead of only allowing or denying it.

Added value

Without credential mediationWith scoped_token
Agent runs with a broad, long-lived role (iam:*, hours/days)Broker mints a credential scoped to one action on one resource
A prompt-injected or drifted agent inherits full standing authorityAuthority is the intersection of the role and a per-request session policy
"Who used this key?" is a CloudTrail archaeology projectEvery credential is bound to a sealed decision + request hash
Revocation means rotating a shared keyRevoke one issued credential; the event is sealed

How it works

agent runtime ──POST /v1/govern/check──▶ PDP (one decision brain)
│ decision = scoped_token

scoped-token broker
│ STS AssumeRole
│ + inline session policy
│ { Allow: <action> on <resource> }
│ DurationSeconds ≤ BROKER_MAX_TTL

short-lived credential ◀──────── returned to the caller (secret here only)


credential.issued.v1 sealed into the
hash-chained evidence ledger (no secret)

The effective permission is the intersection of the broker role's identity policy and the per-request session policy, so an issued credential can never exceed the decision that minted it. The credential is returned to the calling agent once; the secret material is never persisted and never sealed — only the non-secret access-key id is retained, so CloudTrail activity correlates back to the exact decision.

A policy that mints scoped tokens

name: prod IAM via scoped token
effect: scoped_token
priority: 100
match:
toolNameGlobs: ["aws.iam.*"]

A call the policy matches returns scoped_token; the agent receives a credential bound to the action (iam:UpdateRole) and the resource ARN it passed:

{
"decision": "scoped_token",
"credential": {
"credentialId": "cred_…",
"accessKeyId": "ASIA…",
"secretAccessKey": "…", // in this response only — never sealed
"sessionToken": "…",
"expiration": "2026-07-27T16:15:00Z",
"action": "iam:UpdateRole",
"resource": "arn:aws:iam::123456789012:role/ProdDeploy",
"scopePolicyHash": "…",
"evidenceId": "evt_…"
}
}

Enforcement points

SurfaceBehavior on scoped_token
POST /v1/govern/check (SDK / CLI wrapper)Mints the scoped credential and returns it, bound to the sealed decision
MCP gateway (proxy)Fails closed — the proxy cannot mint AWS credentials, so it blocks and points the caller at govern/check. It never forwards with the agent's ambient credential

Fail-safe by construction: a scoped_token decision is treated as not forwardable as-is everywhere — the action only proceeds once a scoped credential is issued.

Proof & containment

  • credential.issued.v1 and credential.revoked.v1 are sealed into the same per-tenant, hash-chained ledger as every other decision — the chain still verifies after issuance (see Prove).
  • List issued credentials for audit / CloudTrail correlation: GET /v1/broker/credentials.

Proving bounded authority with CloudTrail

Issuing a scoped credential is a claim; CloudTrail is the proof. Because the broker records each credential's non-secret access-key id, Unveilr can correlate the credential's real AWS activity back to the decision that minted it:

POST /v1/broker/credentials/{id}/correlate

It pulls the credential's CloudTrail events (by access-key id, over the credential's lifetime) and classifies each one against the grant, returning a verdict sealed as credential.activity.v1:

VerdictMeaning
bounded_authority_provenThe granted action ran; any out-of-scope action was denied by AWS — the inline session policy held
scope_violationAn out-of-scope action succeeded — the credential exceeded its grant (alarm; the boundary failed)
no_activityThe credential was issued but never used

An out-of-scope AccessDenied in CloudTrail is not a failure — it is the evidence that the boundary worked. This is REQ-GRD-004's acceptance criterion: CloudTrail and token metadata prove bounded authority. (Read-only; needs cloudtrail:LookupEvents, enabled with CLOUDTRAIL_ENABLED.)

  • Revoke (containment): POST /v1/broker/credentials/{id}/revoke marks the credential revoked and seals the event. (STS session tokens cannot be individually invalidated mid-flight; the durable compensating control is the target role's AWSRevokeOlderSessions policy — recorded on the timeline.)

Configuration

SettingMeaning
BROKER_ENABLEDOff by default; credential mediation only runs when enabled
BROKER_ROLE_ARNThe role the broker assumes to mint scoped credentials
BROKER_MAX_TTL_SECONDSHard cap on credential lifetime (default 900s)
CLOUDTRAIL_ENABLEDEnables CloudTrail correlation (read-only cloudtrail:LookupEvents)

With the broker disabled, a scoped_token decision still stands, but no credential is issued and the call cannot proceed — fail-safe, never fail-open.