volcano-sh / volcano-sh/agentcube

Clarify AgentCube authentication and authorization model

Open
#441 5 comments 0 reactions 1 assignee View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
167
Forks
88
Avg merge
44m
Merged PRs (30d)
1

Description

Background

AgentCube currently has several authentication and authorization mechanisms at different boundaries: external OIDC at Router, optional Kubernetes ServiceAccount authentication and SPIFFE mTLS between control-plane components, Router-signed identity assertions, Router-signed sandbox JWTs, and session ownership checks.

These mechanisms were introduced at different times, and we do not yet have one shared description of the overall model: who authenticates whom, which identity authorizes an operation, and which Kubernetes identity ultimately executes it.

This became visible in PR #433. Enabling the existing WorkloadManager auth path did more than authenticate Router: WM also started using Router's ServiceAccount token as its Kubernetes client credential. As a result, Router needed create/delete permissions for Sandboxes and SandboxClaims, potentially across namespaces. It was unclear whether this permission expansion matched the intended architecture.

Before addressing #432 or reopening #433, it would be useful to first align on the current and intended auth model.

Current auth flow

Solid arrows are used in the normal request path. Dashed arrows are optional or configuration-dependent.

flowchart LR
    Client["External client / SDK"]
    IdP["OIDC provider"]
    Router["Router"]
    WM["WorkloadManager"]
    K8s["Kubernetes API"]
    Store["Redis / Valkey"]
    Sandbox["Sandbox / PicoD"]

    Client -.->|"OAuth2 token acquisition"| IdP
    IdP -.->|"OIDC access token"| Client

    Client -->|"Bearer OIDC JWT<br/>optional"| Router
    Router -->|"signature + issuer + audience<br/>role + OwnerID"| Router

    Router -->|"Router ServiceAccount token"| WM
    Router -.->|"optional SPIFFE mTLS"| WM
    Router -->|"Router-signed user identity JWT"| WM

    WM -->|"TokenReview when EnableAuth=true"| K8s
    WM -->|"authenticated caller token<br/>used as K8s client credential"| K8s
    WM -.->|"when EnableAuth=false:<br/>WM ServiceAccount credential"| K8s

    Router -->|"Router-signed JWT<br/>session_id + optional user_sub"| Sandbox
    WM -->|"inject Router public key"| Sandbox

    Router <--> Store
    WM <--> Store

Some relevant current behavior:

  • Router OIDC auth is disabled unless an issuer is configured.
  • WorkloadManager supports TokenReview auth, but the base chart does not currently enable it.
  • When WM auth is enabled, authentication and Kubernetes credential delegation happen together.
  • AgentRuntime session creation goes through Router, while the Python CodeInterpreter client creates and deletes sessions by calling WM directly.
  • Router enforces ownership when invoking existing sessions, while other lifecycle operations do not necessarily use the same ownership check.
  • Router-to-WM mTLS and Router-to-sandbox JWT authentication are separate, optional mechanisms with their own identity and key assumptions.

Why this needs discussion

The current implementation leaves multiple reasonable interpretations of the intended architecture. For example, WM could authenticate Router and continue operating with its own ServiceAccount, or it could intentionally execute with a delegated caller credential. Likewise, WM could be an internal service used only by Router, or a supported API for external SDK clients. Those choices lead to very different RBAC, namespace, ownership, and compatibility requirements.

This issue is not intended to propose a complete solution. The goal is to verify whether the diagram above accurately represents the current system and to establish a shared high-level model before making further auth or RBAC changes.

In particular, it would be helpful to align on the external API boundary, the distinction between authenticated identity and Kubernetes execution identity, and where namespace and session ownership authorization should live. Once those boundaries are clear, follow-up changes can be split into focused and independently reviewable issues.

Related: #432, #433.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.