Skip to content

feat(auth): bind sandbox credential RPCs to the running sandbox #3654

Description

@pierzchalski

User Story

As a gateway operator, I want credential RPCs to identify the running sandbox, so its bearer alone cannot grant credential access or refresh.

Problem Statement

GetSandboxProviderEnvironment and RefreshSandboxToken check bearer validity, sandbox scope, persisted runtime generation, and token lineage, not whether the caller is the running sandbox. Another bearer holder satisfying gateway reachability and configured TLS client authentication can pass these checks.

The token is held by the sandbox's supervisor process, not the workload; "the running sandbox" below means that process. This is defense in depth for any exposure of a current bearer, which architecture/gateway.md:359-361 accepts as bounded by the token TTL. Merged #3562 removed the legacy non-expiring admission path, and open #3110 separates sandbox identity from TLS; neither adds caller binding, and this work should be sequenced after #3110. #1955 plans to retire GetSandboxProviderEnvironment, so this request covers credential RPCs and their replacements.

Impact / Why This Matters

An accepted caller can read provider credentials or refresh the token. Short lifetimes and rotation limit exposure but do not identify the presenter.

Proposed Design

After startup and initial credential acquisition, require the gateway to establish that subsequent credential reads and refreshes come from the running sandbox. Leave the mechanism open.

Acceptance Criteria

  • Tests allow bound-sandbox credential reads and refreshes, including replacement paths, but reject the same valid bearer presented elsewhere despite satisfying other transport requirements.
  • Authorized restart and reconnection work; bindings that no longer identify a live sandbox fail.

Alternatives Considered

Shorter expiry, rotation, and network restrictions limit exposure or access, not caller binding.

Agent Investigation

Read credential handlers and session authentication at main a8f98ec, including merged #3562; nothing executed.

  • crates/openshell-server/src/grpc/policy.rs:3355-3374: sandbox scope checked before environment loading.
  • crates/openshell-server/src/auth/sandbox_jwt.rs:273-307: session JWT validation and persisted authorization except for refresh.
  • crates/openshell-server/src/auth/sandbox_session.rs:248-300, :309-333: sandbox phase, runtime generation, auth epoch, and token lineage checks; refresh replay window.
  • crates/openshell-server/src/grpc/auth_rpc.rs:151-237: refresh accepts the current token or a previous token within the replay window with a matching request hash, not caller-origin evidence.

Checklist

  • I've reviewed existing issues and the architecture docs
  • This is a design proposal, not a "please build this" request

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:needs-infoAssessment needs specific evidence or reproduction detailsstate:triage-neededOpened without agent diagnostics and needs triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions