Summary
On an OBO (on-behalf-of) run, the STS token-exchange uses subject=<human token> + actor=<agent pod ServiceAccount token>. The actor token's audience is the cluster default, and nothing lets it carry a specific audience. An STS broker that validates the actor against the cluster ServiceAccount OIDC issuer and pins an audience rejects it.
This is runtime-agnostic — it affects Go declarative, Python declarative, and BYO agents alike, because the pod's SA-token mount is built by the controller, not the runtime.
Current state
- The controller projects exactly one SA token,
aud="kagent" at /var/run/secrets/tokens/kagent-token (go/core/internal/controller/translator/agent/manifest_builder.go). It is consumed by the kagent platform token service (read from KAGENT_TOKEN_PATH), not by the actor reader.
- Every runtime therefore falls back to the cluster-default automounted token (
/var/run/secrets/kubernetes.io/serviceaccount/token — automount is on, so it is present):
- Go ADK passes
"" for the actor path (go/adk/pkg/runner/adapter.go) and defaults to it (go/adk/pkg/sts/actor.go).
- The Python CLI constructs the STS integration with only the well-known URI and never passes
service_account_token_path (python/packages/kagent-adk/src/kagent/adk/cli.py), so agentsts-core defaults to the same token (python/packages/agentsts-core/src/agentsts/core/_actor_service.py).
- BYO agents inherit the same pod mount.
- The default token's audience is the cluster default and cannot be set per-pod without a projected volume. The exchange request's
audience/resource parameter shapes the output token, not the actor's intrinsic aud.
Problem
The actor token's audience is not configurable, so it cannot be made to match a broker that pins an audience — regardless of which runtime (or BYO image) the agent uses.
Option A — purpose-bound actor token (controller-level, agnostic)
The controller projects an additional ServiceAccountToken volume whose audience is configurable (Agent CR field and/or chart value) at a well-known path; runtimes read the actor from that path via a shared env/path convention that BYO images can also honor. Purpose-bound, kubelet-rotated, no broker-side audience changes.
Option B — path-only
The controller still projects an audience-bound token; make just the actor-token path configurable so runtimes/BYO point at it; the broker accepts that audience. Smaller change, but reuses a token minted for another relying party and requires broker-side audience acceptance.
Asks
Opt-in; default behavior unchanged.
Summary
On an OBO (on-behalf-of) run, the STS token-exchange uses
subject=<human token>+actor=<agent pod ServiceAccount token>. The actor token's audience is the cluster default, and nothing lets it carry a specific audience. An STS broker that validates the actor against the cluster ServiceAccount OIDC issuer and pins an audience rejects it.This is runtime-agnostic — it affects Go declarative, Python declarative, and BYO agents alike, because the pod's SA-token mount is built by the controller, not the runtime.
Current state
aud="kagent"at/var/run/secrets/tokens/kagent-token(go/core/internal/controller/translator/agent/manifest_builder.go). It is consumed by the kagent platform token service (read fromKAGENT_TOKEN_PATH), not by the actor reader./var/run/secrets/kubernetes.io/serviceaccount/token— automount is on, so it is present):""for the actor path (go/adk/pkg/runner/adapter.go) and defaults to it (go/adk/pkg/sts/actor.go).service_account_token_path(python/packages/kagent-adk/src/kagent/adk/cli.py), soagentsts-coredefaults to the same token (python/packages/agentsts-core/src/agentsts/core/_actor_service.py).audience/resourceparameter shapes the output token, not the actor's intrinsicaud.Problem
The actor token's audience is not configurable, so it cannot be made to match a broker that pins an audience — regardless of which runtime (or BYO image) the agent uses.
Option A — purpose-bound actor token (controller-level, agnostic)
The controller projects an additional
ServiceAccountTokenvolume whose audience is configurable (Agent CR field and/or chart value) at a well-known path; runtimes read the actor from that path via a shared env/path convention that BYO images can also honor. Purpose-bound, kubelet-rotated, no broker-side audience changes.Option B — path-only
The controller still projects an audience-bound token; make just the actor-token path configurable so runtimes/BYO point at it; the broker accepts that audience. Smaller change, but reuses a token minted for another relying party and requires broker-side audience acceptance.
Asks
Opt-in; default behavior unchanged.