Skip to content

feat(session): configurable admission verifying a signed grant #295

Closed

Description

@teemow

Problem

A Session volume source must pass a check the installation defines: who may start a Session on which volume. kagent cannot trust the caller's word, and the check must hold for every surface and for a direct API call alike. The platform's check is a short-lived JWT grant signed by the workspace issuer that holds the sign-ins (the workspace-manager): it names the person (sub), the volume (CSI driver and handle), the repositories changed since the workspace's last sync and the providers whose credentials the Session gets (host, audience, scheme, broker name), and it is verified against the issuer's published JWKS. kagent has no admission step today.

Proposed solution

One carried, upstream-ready PR:

  • A SessionAdmission interface in the session service, called by Create whenever volume_source or admission_token is set: Admit(ctx, caller, request) (Admitted, error). No admission configured: refused as in the API PR.
  • The built-in jwt admission, configured by environment and chart values (controller.session.admission.jwt.{jwksURL, issuer, audience}): verifies the signature (JWKS fetched and cached, refetched on an unknown kid), iss, aud, exp and nbf; requires sub to equal the caller's subject as the authenticator identifies it; requires the grant's volume claim to equal the request's volume_source volume and every requested mount to be one the grant allows (its sub-paths and read-only flags).
  • What it admits is stored on the Session and shown on get and list without the token: providers[] (hostname, audience, scheme, username for Basic, broker name) and changed[] (repository paths relative to the working directory). Every refusal is PermissionDenied with its reason (no grant, expired, another person's, a different volume or mount, unknown issuer or key), never key material.
  • Chart values and environment documented in the chart's README and docs/architecture.

Acceptance criteria

  • Unit tests with the test signer: a valid grant is admitted and its providers and changed list land on the Session; expired, wrong sub, wrong volume, a mount the grant does not allow, wrong aud, unknown kid are each refused with the named reason
  • A rotated JWKS (new kid) is accepted without a controller restart; an unreachable JWKS refuses with Unavailable, not PermissionDenied
  • GetSession and ListSessions show the providers and the changed list and never the token
  • The chart renders the environment from the values; with the values unset a volume_source is refused as before
  • FORK.md row for the carried patch

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    • Status
      Done ✅

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions