You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Security] Missing Control Plane Authorization across ate-api RPCs #2074
This is a result of an internal vuln finding run. Many of these are known issues, but don't appear to have tracking issues, so I'm filing them anyway.
[Security] Missing Control Plane Authorization across ate-api RPCs
Severity: CRITICAL (5.12) | CWE: CWE-862
Problem Description
The ate-api interceptor chain only performs caller authentication (ateapiauth.UnaryServerInterceptor, server.go:71-80), verifying token validity without enforcing authorization or tenancy checks across RPC handlers.
Affected RPCs & Vulnerabilities
Actor Management (CreateActor, DeleteActor, ResumeActor, SuspendActor, StopActor):
Validates only that caller is authenticated.
Does not enforce atespace ownership or RBAC policies, allowing callers from one atespace/tenant to create, read, suspend, or terminate actors belonging to any other tenant.
Callers can register or modify worker pools without administrative role checks.
Credential & Secret Access:
RPCs that return actor tokens or status allow cross-tenant inspection.
Attack Vector
A low-privileged authenticated tenant holding credentials for atespace A can issue gRPC requests targeting atespace B:
Call SuspendActor or StopActor against actors in B, causing cross-tenant denial of service.
Call CreateActor or ResumeActor in B to consume the victim's resource quota.
Manipulate actor definitions and runtime configurations across tenants.
Impact
Complete loss of tenant isolation across the Substrate control plane. Any authenticated user can perform unauthorized reads, mutations, deletions, and resource hijacking against all tenants in the cluster.
Greg Castle (@destijl) I wanted to flag an already discussed detail that we are accepting ABA problem since we are storing "resource name" in OpenFGA table.
Please note, we solve this at DB level by making sure to delete policies along side resources. However, ABA is only an issue if we enable caching in OpenFGA since key is (user, relation, target). To mitigate this, we already discussed to enforce a min length of resource name.
Gregbot: Looking at the missing authorization across ateapi, I want to flag two RPCs that have a distinct security boundary requirement beyond general atespace-scoped RBAC:
Both currently carry // TODO(authz) and execute with no caller check beyond transport authentication. MintActorJWT allows any authenticated caller to sign an ES256 actor JWT for any actor in any atespace with arbitrary audiences. MintActorCertificate allows any holder of a pod-identity client certificate to obtain an actor SPIFFE certificate for any actor.
Critical distinction from standard tenant RBAC:
These RPCs must never be accessible to regular atespace tenants or editors. An atespace editor who can mint arbitrary actor JWTs or SPIFFE certs can forge downstream identities and impersonate any actor.
Access must be restricted strictly to authorized system principals:
The proto states MintActorJWT is intended for atenet-egress for outbound credential injection. However, egress JWT injection is currently unfulfilled (501 NotImplemented in cmd/atenet/internal/router/egress/credentials.go:76-78), so no production component calls this today. We should consider disabling or unpublishing MintActorJWT from Control until egress JWT injection is implemented.
MintActorCertificate should strictly require an allowlisted system identity (e.g. atenet-router or node atelet).
Activity
destijl commentedon Oct 1, 2026
I assume this is because we're not quite done building the authorization yet, but it's not bad to have a tracking issue.
SHRUTI6991 commentedon Oct 5, 2026
Greg Castle (@destijl) I wanted to flag an already discussed detail that we are accepting ABA problem since we are storing "resource name" in OpenFGA table.
Please note, we solve this at DB level by making sure to delete policies along side resources. However, ABA is only an issue if we enable caching in OpenFGA since key is (user, relation, target). To mitigate this, we already discussed to enforce a min length of resource name.
destijl commentedon Oct 6, 2026
Gregbot: Looking at the missing authorization across
ateapi, I want to flag two RPCs that have a distinct security boundary requirement beyond general atespace-scoped RBAC:Control.MintActorJWT(cmd/ateapi/internal/controlapi/actor.go:545-555)Control.MintActorCertificate(cmd/ateapi/internal/controlapi/actor.go:600-620)Both currently carry
// TODO(authz)and execute with no caller check beyond transport authentication.MintActorJWTallows any authenticated caller to sign an ES256 actor JWT for any actor in any atespace with arbitrary audiences.MintActorCertificateallows any holder of a pod-identity client certificate to obtain an actor SPIFFE certificate for any actor.Critical distinction from standard tenant RBAC:
These RPCs must never be accessible to regular atespace tenants or editors. An atespace editor who can mint arbitrary actor JWTs or SPIFFE certs can forge downstream identities and impersonate any actor.
Access must be restricted strictly to authorized system principals:
MintActorJWTis intended foratenet-egressfor outbound credential injection. However, egress JWT injection is currently unfulfilled (501 NotImplementedincmd/atenet/internal/router/egress/credentials.go:76-78), so no production component calls this today. We should consider disabling or unpublishingMintActorJWTfromControluntil egress JWT injection is implemented.MintActorCertificateshould strictly require an allowlisted system identity (e.g.atenet-routeror nodeatelet).SHRUTI6991 commentedon Oct 16, 2026
Hi Greg Castle (@destijl), the authorization is now being enforced across ate-api RPCs.
zlammerts-svg commentedon Oct 16, 2026
Thanks Shruti Nair (@SHRUTI6991)!! Greg Castle (@destijl) Given that the authorization is now being enforced across ate-api RPCs, can we close this issue now? : )
LiorLieberman commentedon Oct 16, 2026
I think this is pending #2736
Shruti Nair (@SHRUTI6991) Julian Gutierrez Oschmann (@juli4n) can you review?
SHRUTI6991 commentedon Oct 16, 2026
Status:
ControlServicedoes all authz checks at rpc interception.WorkerServiceis currently doing at handler level. Shumiao Wang (@shumiao) is doing the work to bring the authz check at the interceptor.zlammerts-svg commentedon Oct 19, 2026
Shruti Nair (@SHRUTI6991) Thanks for the updates! Are we waiting for #2853 to be merged to clsoe this one?
SHRUTI6991 commentedon Oct 19, 2026
No, node isolation is a good to have for us. It's not P0.
We have all the authz in place for
ControlServiceandWorkerService. I think we can close this issue.SHRUTI6991 commentedon Oct 21, 2026
Tracked separately: #3031