You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
OpenShell's credential proxy model replaces real secrets with opaque placeholder tokens in sandbox environment variables, then resolves them in HTTP headers (Bearer, Basic auth) before forwarding upstream. This works for APIs that send credentials directly in headers.
AWS SigV4 is fundamentally incompatible: the SDK uses the secret access key to compute an HMAC signature over the canonical request (method, path, headers, body hash). Placeholder values produce invalid signatures that can't be fixed by simple header replacement. This prevents sandboxed agents from accessing any AWS service (Bedrock, S3, STS, etc.) through the credential proxy.
Add proxy-side SigV4 re-signing in the sandbox supervisor's CONNECT tunnel path. When credential_signing: sigv4 is set on a REST endpoint in the policy YAML, the proxy:
Terminates TLS (as normal for protocol: rest)
Strips the client's invalid Authorization, X-Amz-Date, X-Amz-Security-Token, and X-Amz-Content-Sha256 headers before the fail-closed placeholder scan
Resolves AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and optionally AWS_SESSION_TOKEN from the SecretResolver
Computes a fresh SigV4 signature using the official aws-sigv4 crate with real credentials
Injects the new signed headers and forwards the properly signed request upstream
The signing service name (e.g. bedrock for bedrock-runtime endpoints) is specified explicitly in the policy via a signing_service field, since the aws-sigv4 crate is just signing math — hostname-to-signing-name resolution lives in per-service SDK crates and there is no lightweight alternative.
Minimal signed headers: Only host, content-type, and content-length are included in the SigV4 signature. Signing all request headers causes 403 InvalidSignatureException because the proxy/transport modifies headers like Connection and Accept-Encoding between signing and delivery.
Payload checksum:PayloadChecksumKind::XAmzSha256 is enabled so the x-amz-content-sha256 header is included, which AWS Bedrock requires.
Body buffering: The full request body is buffered before signing to compute the body hash. This is acceptable since Bedrock invoke-model requests have bounded body sizes.
Region inference: Extracted from the hostname pattern <service>.<region>.amazonaws.com.
| Component | Key Files | Change |
|-----------|-----------|--------|
| Proto model | proto/sandbox.proto | Add credential_signing (field 18) and signing_service (field 19) to NetworkEndpoint |
| Policy serde | crates/openshell-policy/src/lib.rs | Add both fields to NetworkEndpointDef and proto conversion |
| SigV4 module | crates/openshell-sandbox/src/sigv4.rs | New — signing via aws-sigv4 crate, header stripping, region extraction |
| L7 config | crates/openshell-sandbox/src/l7/mod.rs | Add CredentialSigning enum and signing_service field to L7EndpointConfig |
| CONNECT relay | crates/openshell-sandbox/src/l7/rest.rs | Hook SigV4 into relay_http_request_with_options_guarded — strip before scan, sign after rewrite |
| OPA data | crates/openshell-sandbox/src/opa.rs | Plumb credential_signing and signing_service through OPA endpoint data |
| Relay options | crates/openshell-sandbox/src/l7/relay.rs | Pass credential_signing and signing_service to RelayRequestOptions |
| Dependencies | crates/openshell-sandbox/Cargo.toml | Add aws-sigv4, aws-credential-types, aws-smithy-runtime-api |
| Providers | crates/openshell-providers/src/profiles.rs | Add signing_service to endpoint_to_proto |
Gateway-side signing (like Vertex AI in feat(providers): add Google Vertex AI inference provider #1568): Vertex uses standard OAuth2 Bearer tokens, so the existing credential proxy handles them. SigV4 signatures depend on the final request content (method + path + headers + body hash), so signing must happen at the proxy where the final request is assembled — not at the gateway.
Exposing real AWS credentials to the sandbox: Defeats the purpose of the credential proxy security model.
IMDS emulation: Complex, and IMDS is hardcoded-blocked in sandboxes for security.
Working implementation on branch sigv4-credential-signing at jhjaggars/OpenShell. Tested end-to-end: Claude Code → OpenShell sandbox → Bedrock (us-east-2) with proxy-side SigV4 re-signing. Sandbox never sees real AWS credentials.
Includes an integration test that exercises the full strip → re-sign → send flow against real Bedrock (#[ignore]'d, requires credentials).
Related: feat(providers): add aws_sts_assume_role refresh strategy (v2 only) #1576 (STS refresh strategy) — the sandbox-side session token support is already implemented, ready for when gateway-side STS rotation lands.
Complements feat(providers): add Google Vertex AI inference provider #1568 (Google Vertex AI) — that PR handles server+router level concerns for a Bearer-token API. This feature handles proxy-level concerns for an HMAC-signature API. No architectural conflicts; both can coexist.
OpenShell's credential proxy model replaces real secrets with opaque placeholder tokens in sandbox environment variables, then resolves them in HTTP headers (Bearer, Basic auth) before forwarding upstream. This works for APIs that send credentials directly in headers.
AWS SigV4 is fundamentally incompatible: the SDK uses the secret access key to compute an HMAC signature over the canonical request (method, path, headers, body hash). Placeholder values produce invalid signatures that can't be fixed by simple header replacement. This prevents sandboxed agents from accessing any AWS service (Bedrock, S3, STS, etc.) through the credential proxy.
Add proxy-side SigV4 re-signing in the sandbox supervisor's CONNECT tunnel path. When
credential_signing: sigv4is set on a REST endpoint in the policy YAML, the proxy:protocol: rest)Authorization,X-Amz-Date,X-Amz-Security-Token, andX-Amz-Content-Sha256headers before the fail-closed placeholder scanAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY, and optionallyAWS_SESSION_TOKENfrom theSecretResolveraws-sigv4crate with real credentialsThe signing service name (e.g.
bedrockforbedrock-runtimeendpoints) is specified explicitly in the policy via asigning_servicefield, since theaws-sigv4crate is just signing math — hostname-to-signing-name resolution lives in per-service SDK crates and there is no lightweight alternative.host,content-type, andcontent-lengthare included in the SigV4 signature. Signing all request headers causes403 InvalidSignatureExceptionbecause the proxy/transport modifies headers likeConnectionandAccept-Encodingbetween signing and delivery.PayloadChecksumKind::XAmzSha256is enabled so thex-amz-content-sha256header is included, which AWS Bedrock requires.invoke-modelrequests have bounded body sizes.AWS_SESSION_TOKENis resolved from the provider when present, enabling STS temporary credentials. Prepares for feat(providers): add aws_sts_assume_role refresh strategy (v2 only) #1576 (aws_sts_assume_role refresh strategy).<service>.<region>.amazonaws.com.| Component | Key Files | Change |
|-----------|-----------|--------|
| Proto model |
proto/sandbox.proto| Addcredential_signing(field 18) andsigning_service(field 19) toNetworkEndpoint|| Policy serde |
crates/openshell-policy/src/lib.rs| Add both fields toNetworkEndpointDefand proto conversion || SigV4 module |
crates/openshell-sandbox/src/sigv4.rs| New — signing viaaws-sigv4crate, header stripping, region extraction || L7 config |
crates/openshell-sandbox/src/l7/mod.rs| AddCredentialSigningenum andsigning_servicefield toL7EndpointConfig|| CONNECT relay |
crates/openshell-sandbox/src/l7/rest.rs| Hook SigV4 intorelay_http_request_with_options_guarded— strip before scan, sign after rewrite || OPA data |
crates/openshell-sandbox/src/opa.rs| Plumbcredential_signingandsigning_servicethrough OPA endpoint data || Relay options |
crates/openshell-sandbox/src/l7/relay.rs| Passcredential_signingandsigning_servicetoRelayRequestOptions|| Dependencies |
crates/openshell-sandbox/Cargo.toml| Addaws-sigv4,aws-credential-types,aws-smithy-runtime-api|| Providers |
crates/openshell-providers/src/profiles.rs| Addsigning_servicetoendpoint_to_proto|Working implementation on branch
sigv4-credential-signingat jhjaggars/OpenShell. Tested end-to-end: Claude Code → OpenShell sandbox → Bedrock (us-east-2) with proxy-side SigV4 re-signing. Sandbox never sees real AWS credentials.Includes an integration test that exercises the full strip → re-sign → send flow against real Bedrock (
#[ignore]'d, requires credentials).Related: feat(providers): add aws_sts_assume_role refresh strategy (v2 only) #1576 (STS refresh strategy) — the sandbox-side session token support is already implemented, ready for when gateway-side STS rotation lands.
Complements feat(providers): add Google Vertex AI inference provider #1568 (Google Vertex AI) — that PR handles server+router level concerns for a Bearer-token API. This feature handles proxy-level concerns for an HMAC-signature API. No architectural conflicts; both can coexist.