Repository navigation
Open
Labels
area/apiUser-facing API changesUser-facing API changesarea/identityarea/securitySecurity related issue/prSecurity related issue/prkind/featureAn enhancement / feature request or implementationAn enhancement / feature request or implementationprio/P0Highest priority / required for next milestoneHighest priority / required for next milestone
Description
Summary
ateapi mints actor JWTs that nothing outside the cluster can verify. The issuer is a hardcoded string, no OpenID Connect discovery document or JWK set is served, and there is no way to rotate the signing key. Finalize the token contract and serve discovery and JWKS so that the egress gateway can inject the token (#1660) and exchange it (#1661), and so operators can federate actors into cloud IAM.
Design: Actor JWT Schema + OIDC (shared with ate-dev@).
Motivation
- Credential Injection - Support Actor JWT #1660 and Credential Injection - Support RFC 8693 token exchange of the Actor JWT #1661 both name a configurable issuer and published discovery plus JWKS as the ateapi prerequisite. No relying party can trust the token until it exists.
- Once an IAM policy names a subject or a verifier binds to an issuer, changing either breaks federation. The contract has to be settled before the first consumer ships, which puts it ahead of the M3 feature cutoff.
Current state
Control.MintActorJWTsigns with the pool from--actor-id-jwt-pool.issis the literalhttps://api.ate-system.svc; the header carriesalgandkidbut notyp.- Both installers create an ES256 pool with
kid"1".make-jwt-poolcan only create a single-authority Secret; there is no add, activate, or remove. Pool.VerificationKeysexists but has no caller. ateapi exposes gRPC on 443 and plaintext metrics on 9090; neither serves HTTP discovery or JWKS.- The RPC logging interceptor writes the full
MintActorJWTResponse, token included, at Info.
Proposal
The design doc has the detail. In short:
- Token: keep
subasatespaces:<atespace>:actors:<name>,audalways an array,ate.devclaims stable. Addtyp: JWT. New authorities default to RS256 with an RFC 7638 thumbprint askid; existing"1"keys are grandfathered. A single--actor-jwt-issuervalue feedsiss, the discoveryissuer, andjwks_uri. - API:
MintActorJWTRequestaccepts a requested lifetime clamped to [5m, 1h], with zero meaning the current 15m default; the response returnsexpires_at. - Discovery:
/.well-known/openid-configurationand/openid/v1/jwks, shaped like the Kubernetes service account issuer, with noauthorization_endpoint. The JWKS carries every authority in the pool, so rotation is add, publish, activate, wait, remove. - Serving: a small read-only
ate-oidc-serverbehind an operator-supplied Ingress, serving public key material reconciled from the pool Secret into a ConfigMap. ateapi gains no public listener.
Work
- Contract:
typheader, algorithm on verification keys, issuer flag, requested duration andexpires_at, redactactor_jwtfrom RPC logs. - Keys: RS256 generation and thumbprint kids as the default in
kubectl ate admin make-jwt-poolandate-setup; add, activate, and remove subcommands for rotation. - Serving: shared discovery and JWKS package, ConfigMap reconciler,
ate-oidc-serverbinary and manifests, issuer plumbing through both installers, and an e2e that verifies a minted token against the served JWKS. - Docs: fix
docs/api-guide.mdsection 7 anddocs/authentication.md, which describe anActorIdentityservice and checks that do not exist; add the contract, federation recipes for GCP, AWS, and Azure, and a
rotation runbook.
Out of scope
- Injecting or exchanging the token at the egress gateway (Credential Injection - Support Actor JWT #1660, Credential Injection - Support RFC 8693 token exchange of the Actor JWT #1661).
- In-guest token delivery (Add a SystemInfo volume source to ActorTemplate for delivering per-actor generated files #802). Add actorIdentityToken as a SystemInfo volume data source #1114 mints through its own path today and will need to ad
- Caller authorization for
MintActorJWT(OpenFGA-based authorization - basic #1563, OpenFGA-based authorization - atelet/ateom authorizer #1564). - Ingress, DNS, and certificate provisioning. Nothing in the install path creates them; the Ingress only.
- Any OpenID Provider functionality beyond what a relying party needs to verify a token.
Metadata
Metadata
Assignees
Labels
area/apiUser-facing API changesUser-facing API changesarea/identityarea/securitySecurity related issue/prSecurity related issue/prkind/featureAn enhancement / feature request or implementationAn enhancement / feature request or implementationprio/P0Highest priority / required for next milestoneHighest priority / required for next milestone
Activity
ateapi: make the actor JWT issuer configurable and add typ to the hea…
ateapi: require an actor JWT lifetime and align the subject with the …
oidcdiscovery: build the OpenID discovery document (agent-substrate#1963
localjwtauthority: thumbprint key IDs and a configurable signing algo…
AGENTS.md: keep JWT and JWK code on the standard library (agent-subst…
Build the JWK set that publishes actor JWT verification keys (agent-s…
kubectl ate admin can rotate the actor JWT signing key (agent-substra…
ate-setup sets the actor JWT issuer (ACTOR_JWT_ISSUER), and ate-api-s…
Sync upstream sandbox, snapshot, and HTTPS egress updates (#69)
Add ate-idp-server to serve the discovery document and key set for ac…
Deploy ate-idp-server with every install (agent-substrate#2599)
Add ate-idp-server to serve the discovery document and key set for ac…
docs,examples: a Substrate actor on the mesh through a credential pro…
Drop the unused actorIdentityJWTProvider setting and fix the actor id…
ate-api-server accepts actor JWT issuers with a path (agent-substrate…
thompsonmax commentedon Oct 22, 2026
These are the remaining PRs I plan to merge before closing this (All E2E testing and docs):
ignaciojaneiro commentedon Oct 22, 2026
Hi — coming from the Agent Mesh side. The
development/examples/substrate-actorexample there puts Substrate actors on the mesh under their own identity; it still uses a stand-inCredentialProvider, and a first iteration (a second actor plus an isolation check) just merged as google/agentmesh#806.The natural next step on the agentmesh side is to drop that stand-in and validate native actor-JWT federation, which depends on the discovery/JWKS server tracked here (
ate-idp-server, currently onmainbut not yet in a release). Before I start anything, two questions:ate-idp-server?subformat (actor/<atespace>/<name>), the issuer and TLS-trust config a relying party needs to reachate-idp-server, or the contract doc in Document the actor JWT contract and how relying parties verify it #2605?Happy to coordinate however suits; I just don't want to duplicate work already under way.
Document the actor JWT contract and how relying parties verify it (ag…
Document federating actor JWTs and rotating the signing key (agent-su…
Document federating actor JWTs and rotating the signing key (agent-su…
Document the actor JWT contract and how relying parties verify it (#2605
Document federating actor JWTs and rotating the signing key (#2911)