Skip to content

feat(auth): authenticate Substrate actor calls to the control plane - #3282

Open
EItanya wants to merge 4 commits into
mainfrom
feat/runtime-actor-jwt
Open

EItanya wants to merge 4 commits into
mainfrom
feat/runtime-actor-jwt

Conversation

@EItanya

@EItanya EItanya commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Actors now authenticate to the controller with Substrate-issued JWTs in the standard Authorization header. A separate runtime listener (:8084 by default) requires Actor JWTs and allows only TaskStore and Memory. The user listener keeps its configured authentication mode and rejects Actor JWTs as user credentials.

TaskStore checks the session, atespace, and current Actor UID. Actor memory access derives its agent and user scope from that persisted binding. Users can also list and delete their own memories through the user listener, using their authenticated identity rather than a request-supplied user ID. This works without a live actor or session. Actors do not inherit their session owner's general API permissions.

Substrate egress replaces a placeholder with a five-minute JWT for the kagent-runtime audience. The controller verifies it through Substrate OIDC discovery/JWKS using the existing JWT dependencies. This works with the pinned Substrate v0.6.0-alpha3. config.substrate.actorJwtIssuer defaults to https://idp.ate-system.svc.

Controller and runtime images must upgrade together; older runtime snapshots must be recreated. Actor memory now uses the stored namespace/name agent reference as its key. Existing entries keyed by runtime display names are not migrated, but users can still list and delete them using those keys.

Validated real JWT injection, credential rejection, and checkpoint/fork restoration on kagent, Codex, Claude, and BYO ADK. Focused Go tests cover user memory ownership through gRPC and actor session scoping. Affected-package lint, Python tests, 52 Helm checks, and protobuf checks also passed. Full gRPC and repository lint reruns were limited by local temporary-volume exhaustion and envtest/etcd startup failures.

@github-actions github-actions Bot added the enhancement New feature or request label Oct 19, 2026
@EItanya EItanya changed the title feat(auth): verify runtime calls with Substrate Actor JWTs feat(auth): authenticate Substrate actor calls to the control plane Oct 19, 2026
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 19, 2026
@EItanya
EItanya marked this pull request as ready for review October 19, 2026 18:48
@EItanya
EItanya requested review from a team and supreme-gg-gg as code owners October 19, 2026 18:48
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
runtimev1.MemoryService_AddSessionBatch_FullMethodName: auth.AccessRuntime,
runtimev1.MemoryService_Search_FullMethodName: auth.AccessRuntime,
runtimev1.MemoryService_List_FullMethodName: auth.AccessRuntime,
runtimev1.MemoryService_Delete_FullMethodName: auth.AccessRuntime,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

users lose any way to delete their own memory

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great point, it needs to be OR'd

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or'd user path must ignore request user_id too

}
return publicKey, nil
}, jwt.WithValidMethods([]string{"ES256", "RS256", "RS384", "RS512"}),
jwt.WithIssuer(v.issuer), jwt.WithAudience(runtimeJWTAudience), jwt.WithExpirationRequired(), jwt.WithIssuedAt())

@moezdil moezdil Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would a small clock skew reject tokens here? (m not sure, kust asking)

Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
@EItanya
EItanya force-pushed the feat/runtime-actor-jwt branch from 6edf900 to 757770f Compare October 19, 2026 20:35
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants