Session
A session is a workload-facing concept. From the workload’s perspective, a “session” is a stable identity (an app, a user, a session ID) that needs to persist across worker pod changes - because the actor it lives in might migrate at any moment.
Why this needs a special concept
A long-running actor will move between worker pods many times (every suspend/resume cycle is potentially a new pod). The pod’s own ServiceAccount-issued credentials change with each pod. But the workload’s identity to external services - the LLM API key, the user’s OAuth token, the application’s identifier - must not.
Sessions solve this: ateapi mints session-scoped credentials that the workload uses to talk to external services. JWTs carry a stable subject of the form:
apps/<appid>/users/<userid>/sessions/<sessionid>MintCert issues an X.509 cert whose SPIFFE URI uses the singular form
spiffe://substrate-session.local/app/<appid>/user/<userid>/session/<sessionid>.
The substrate-specific metadata is also exposed via an extension claim keyed
ate.dev.
The SessionIdentity gRPC service
Two RPCs on ateapi, on the SessionIdentity service:
| RPC | Output |
|---|---|
MintJWT | JWT with sub=apps/<appid>/users/<userid>/sessions/<sessionid>, 15-min TTL, NotBefore back-dated 5 min, issuer https://broker.agentic-substrate-session-id-broker.svc. Requires at least one requested audience. The substrate metadata (appID/userID/sessionID) is in a JWT extension claim keyed ate.dev. |
MintCert | X.509 cert whose SPIFFE URI is spiffe://substrate-session.local/app/<appid>/user/<userid>/session/<sessionid> (singular), signed from a CSR, with the same 15-min TTL. |
The two RPCs authenticate their callers differently:
MintJWTrequires a bearer token in theauthorizationmetadata - the pod’s K8s ServiceAccount token, verified against the configured OIDC issuer/audience.MintCertrequires a client certificate: it reads the peer’s TLS state and fails authentication if no peer certificate is present. ateapi’s gRPC server verifies a client cert only if one is given, so a client cert is optional at the transport level but mandatory forMintCert.
Session vs. actor
| Actor | Session | |
|---|---|---|
| Scope | Substrate internals | Workload’s identity to external services |
| Identifier | (atespace, name) tuple | app/user/session triple |
| Persisted in | Redis | The credentials’ issued JWTs/certs |
| Lifetime | Until DeleteActor | Defined by app logic; survives worker moves |
One actor may host many sessions over its lifetime. One session may outlive many actors (rare but possible).
Related
- Actor - the substrate-internal lifecycle.
- ateapi internals - the SessionIdentity service.