Skip to content

fix(security): authenticate extension services - #2638

Draft
pimlock wants to merge 3 commits into
mainfrom
feat/2623-extension-auth/pimlock
Draft

fix(security): authenticate extension services#2638
pimlock wants to merge 3 commits into
mainfrom
feat/2623-extension-auth/pimlock

Conversation

@pimlock

@pimlock pimlock commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Authenticate remote supervisor middleware and gateway-interceptor RPCs with short-lived, exact-audience gateway-signed JWTs. Add a shared extension client foundation so both mechanisms use the same bearer rotation and TLS/custom-CA implementation.

Related Issue

Closes #2623

Security Fix

Remote extension services previously could not cryptographically distinguish OpenShell gateway or sandbox-supervisor calls from direct network callers. This change adds authenticated caller identity and policy-constrained token distribution while preserving the existing Ed25519 signing authority and sandbox refresh API.

Severity Assessment

  • Impact is high for network-reachable extensions that perform privileged transformations or actions, and medium when trusted network isolation is enforced.
  • Exploitability is moderate because exploitation requires extension endpoint reachability but not compromise of gateway signing material.
  • Alpha residual risks remain: bearer replay until short expiry and single-key JWKS rotation. Multi-key overlap, mTLS, and stronger replay resistance remain deferred hardening.

Changes

  • Add openshell-extension-core with shared extension identity, claims, expiry-aware bearer slots, HTTP/HTTPS/Unix channels, and custom-CA primitives.
  • Reuse gateway Ed25519 signing material to mint gateway and supervisor extension JWTs with kind-scoped audiences, caller identity, kid, jti, and bounded expiry.
  • Extend RefreshSandboxToken to return only middleware credentials selected by the authenticated sandbox effective policy.
  • Publish the gateway public key at /.well-known/jwks.json for extension verification.
  • Use the shared authenticated transport for middleware, gateway interceptors, and provider-profile snapshot calls.
  • Rotate credentials from actual expiry without reconnecting, preserve last-known-good slots on failed reconciliation, and clear detached slots only after a successful registry swap.
  • Support platform roots or certificate-only custom CA bundles with normal hostname verification; reject private-key propagation and CA use with plaintext or Unix endpoints.
  • Update architecture, RFC, gateway configuration, middleware, and interceptor documentation plus generated Go bindings.

Testing

  • mise run pre-commit passes
  • Affected Rust unit and integration suites pass, including gateway, sandbox, shared core, middleware, and interceptor crates
  • Workspace and E2E Rust targets pass strict Clippy checks
  • Buf lint and generated Go binding checks pass
  • Private-CA success, wrong CA, and hostname-mismatch tests added
  • Authorization, exact-audience, expiry, rotation, detachment, secret-descriptor, and JWKS tests added or updated
  • Full Docker-backed E2E suite not run; no external extension fixture currently exists in that lane

Checklist

  • Follows Conventional Commits
  • Commit is signed off (DCO)
  • User-facing and architecture documentation updated
  • Agent infrastructure inventory synchronized for the new crate

Example branch

The runnable authenticated middleware example is intentionally kept on the separate 2623-authenticated-middleware-example/pimlock branch. Its service-side JWT verifier is a dedicated example module marked for future extraction into an extension-building SDK, keeping inbound verification concerns out of openshell-extension-core. After this PR lands, the branch can be rebased and merged separately or folded into later work.

Follow-up: JWKS bootstrap

This PR publishes JWKS only after extension registration, so initial key provisioning is still out of band. A follow-up should bind the primary gateway listener immediately after loading TLS/JWT keys, serve only /.well-known/jwks.json (503 for other routes), initialize middleware/interceptors against that trusted URL, then atomically switch the same listener to the full MultiplexService. Compute-driver callback listeners can be added later without rebinding the primary listener. Keep issuer, audience, and gateway TLS trust operator-configured; retain a JWKS-file fallback if useful. Test pre-ready routing, TLS/hostname verification, the ready transition, and cleanup after startup failure.

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
@pimlock pimlock added area:supervisor Proxy and routing-path work topic:security Security issues area:gateway Gateway server and control-plane work labels Aug 6, 2026
@copy-pr-bot

copy-pr-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

pimlock added 2 commits August 6, 2026 14:30
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:gateway Gateway server and control-plane work area:supervisor Proxy and routing-path work topic:security Security issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add shared alpha extension authentication and custom CA transport

1 participant