Skip to content

[Security] Missing Control Plane Authorization across ate-api RPCs #2074

Closed

Description

@destijl

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.
  • WorkerPool Registration (RegisterWorkerPool, UpdateWorkerPool):
    • 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:

  1. Call SuspendActor or StopActor against actors in B, causing cross-tenant denial of service.
  2. Call CreateActor or ResumeActor in B to consume the victim's resource quota.
  3. 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.

Proposed Remediation

  1. Implement comprehensive authorization middleware (e.g. RBAC / tenant-scoping interceptor) on ate-api gRPC services.
  2. Enforce strict checks verifying the caller principal matches or has administrative delegation over the requested atespace.
  3. Add automated authorization integration tests verifying cross-atespace calls are rejected with codes.PermissionDenied.

Activity

  1. destijl commented on Oct 1, 2026

    @destijl
    CollaboratorAuthor

    I assume this is because we're not quite done building the authorization yet, but it's not bad to have a tracking issue.

  2. added this to the M3 milestone on Oct 1, 2026
  3. SHRUTI6991 commented on Oct 5, 2026

    @SHRUTI6991
    Collaborator

    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.

  4. destijl commented on Oct 6, 2026

    @destijl
    CollaboratorAuthor

    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. 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:

    1. 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.
    2. MintActorCertificate should strictly require an allowlisted system identity (e.g. atenet-router or node atelet).
  5. SHRUTI6991 commented on Oct 16, 2026

    @SHRUTI6991
    Collaborator

    Hi Greg Castle (@destijl), the authorization is now being enforced across ate-api RPCs.

  6. zlammerts-svg commented on Oct 16, 2026

    @zlammerts-svg
    Collaborator

    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? : )

  7. LiorLieberman commented on Oct 16, 2026

    @LiorLieberman
    Collaborator
  8. SHRUTI6991 commented on Oct 16, 2026

    @SHRUTI6991
    Collaborator

    Status:

    ControlService does all authz checks at rpc interception.

    WorkerService is currently doing at handler level. Shumiao Wang (@shumiao) is doing the work to bring the authz check at the interceptor.

  9. zlammerts-svg commented on Oct 19, 2026

    @zlammerts-svg
    Collaborator

    Shruti Nair (@SHRUTI6991) Thanks for the updates! Are we waiting for #2853 to be merged to clsoe this one?

  10. SHRUTI6991 commented on Oct 19, 2026

    @SHRUTI6991
    Collaborator

    No, node isolation is a good to have for us. It's not P0.

    We have all the authz in place for ControlService and WorkerService. I think we can close this issue.

  11. SHRUTI6991 commented on Oct 21, 2026

    @SHRUTI6991
    Collaborator

    Tracked separately: #3031

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area/securitySecurity related issue/prkind/bugSomething isn't working / bugfixes

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions