Skip to content

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 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, defined at pkg/proto/ateapipb/ateapi.proto:187-197:

RPCOutput
MintJWTJWT 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. The substrate metadata is in a JWT extension claim keyed ate.dev.
MintCertX.509 cert whose SPIFFE URI is app/<appid>/user/<userid>/session/<sessionid> (singular) with the same 15-min TTL.

Two auth modes are supported:

  • Bearer token: the pod’s K8s ServiceAccount token, accepted by either RPC.
  • mTLS client cert: required by MintCert, optional on MintJWT. The server is configured with VerifyClientCertIfGiven so callers may present one or not.
cmd/ateapi/internal/sessionidentity/sessionidentity.go:42-100

Session vs. actor

ActorSession
ScopeSubstrate internalsWorkload’s identity to external services
Identifieractor_idapp/user/session triple
Persisted inRedisThe credentials’ issued JWTs/certs
LifetimeUntil DeleteActorDefined by app logic; survives worker moves

One actor may host many sessions over its lifetime. One session may outlive many actors (rare but possible).