Skip to content

Support namespace scoping via JWT claims #2217

@angel-manuel

Description

@angel-manuel

Problem

When running sqld with --enable-namespaces in a multi-tenant setup, there's no way to restrict a JWT token to a specific namespace (or set of namespaces) using claims. Currently:

  • A valid JWT grants access to all namespaces at the specified access level (rw or ro)
  • The namespace is selected by the client via the x-namespace header
  • A compromised token can access any namespace

Existing Work

Issue #500 proposes per-namespace signing keys, which solves key isolation but requires managing N keys for N namespaces. This proposal is complementary — it uses a single signing key with claim-based scoping.

Proposal

Add support for an optional ns (or namespace) claim in the JWT payload that restricts which namespace(s) the token can access:

// Token scoped to a single namespace
{
  "a": "rw",
  "ns": "workspace-abc123",
  "exp": 1710200000
}

// Token scoped to multiple namespaces
{
  "a": "ro",
  "ns": ["workspace-abc123", "workspace-def456"],
  "exp": 1710200000
}

// Token with no ns claim = current behavior (access all namespaces)
{
  "a": "rw",
  "exp": 1710200000
}

When ns is present, sqld would validate that the requested namespace (from x-namespace header, host header, or gRPC metadata) matches the claim. Mismatches return 403.

Use Case

We're building a platform where ephemeral VMs each own a workspace backed by a sqld namespace. An orchestrator mints short-lived JWTs for each VM. Without namespace scoping in the JWT, a compromised VM could push/pull to any workspace. With this feature, each VM's token is locked to its own namespace.

This is simpler to operate than per-namespace keys (#500) when there's a single trusted token issuer (our orchestrator) but many namespaces.

Backward Compatibility

Fully backward compatible — tokens without the ns claim behave exactly as today.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions