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
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
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
GetSandboxProviderEnvironmentandRefreshSandboxTokencheck 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-361accepts 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 retireGetSandboxProviderEnvironment, 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
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