Repository navigation
Proposal: Oracle Cloud Infrastructure request signing and principal minting (credential_signing: oci, oci_* refresh strategies) #5311
fede-kamel
started this conversation in
Design Discussion
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Summary
Add first-class Oracle Cloud Infrastructure (OCI) support to the credential proxy in two
steps that follow existing precedent exactly:
credential_signing: ocion REST endpoints: the sandbox supervisor's proxy signsrequests with OCI's RSA-SHA256 HTTP
Signaturescheme using credentials resolved fromthe endpoint-bound provider, so the sandbox never holds a key. Sibling of
sigv4,sigv4:bodyandsigv4:no_body.oci_instance_principal,oci_resource_principalandoci_oke_workload_identity, that mint a security token(
OCI_KEY_ID = ST$<token>) and co-mint an ephemeral RSA session key(
OCI_PRIVATE_KEY) throughadditional_outputs. Counterpart ofaws_sts_assume_role.Issues: #3960 (signing), #3961 (minting). Implementation: #3962 and #3975 (stacked).
Umbrella and history: #3879. Merged precedent for OCI in the repository:
providers/oci-genai.yaml(#3904), which only covers the bearer-authenticatedOpenAI-compatible endpoint.
Motivation
OpenShell replaces secrets with placeholders in the sandbox and resolves them in HTTP
headers at the proxy. That works for bearer and basic auth, and it is why
oci-genaiworks today. Every other OCI API (native Generative AI at
/20231130, Object Storage,Vault, Compute, Functions, OKE control plane) is request-signed: an RSA-SHA256 signature
over
date (request-target) host, pluscontent-length content-type x-content-sha256for requests with a body, with
keyIdeither<tenancy>/<user>/<fingerprint>(API key)or
ST$<security-token>(session, instance, resource or workload principal). Headersubstitution cannot repair a signature made with a placeholder key.
The workarounds are the ones the project already rejects for AWS: inject the real
private key into the sandbox as a plain value, or run a signing bridge per service
outside the sandbox and grant the sandbox egress to it. SigV4 (#1631) and STS (#1576)
solved this for AWS; OCI needs the same two pieces. Oracle Cloud is a launch partner of
the Open Agent Safety Platform and hosts a growing share of NVIDIA GPU capacity, so
agents running there are an expected population.
Non-goals
region-scoped, so no
signing_serviceis needed).review than a shared one.
safe to source a passphrase).
controls.
extensions that need no upstream change.
Proposal, part 1:
credential_signing: ociBehaviour when an endpoint sets
credential_signing: oci(policy YAML or a providerprofile endpoint):
protocol: rest.authorization,date,x-date,x-content-sha256and
expectheaders before the fail-closed placeholder scan, so a client-side attemptnever leaks upstream.
OCI_KEY_IDandOCI_PRIVATE_KEYfrom the endpoint-bound providerthrough the existing
SecretResolver.date(RFC 7231), computesx-content-sha256forPOST,PUTandPATCHbodies, builds the signing string in the OCI SDK's header order, and signs RSA PKCS#1
v1.5 SHA-256.
Authorization: Signature algorithm="rsa-sha256",headers="...",keyId="...",signature="...",version="1"and forwards. The
hostthat is signed is the exact host the proxy forwards to.Design decisions, including the points raised by the triage review on #3960:
OCI_PRIVATE_KEYisstandard base64 of the PEM file (
base64 -w0 < oci_api_key.pem), the documented form.Base64 of raw PKCS#8 or PKCS#1 DER and
\n-escaped PEM are also accepted.Passphrase-protected keys are rejected; the issue's optional
OCI_PRIVATE_KEY_PASSPHRASEis dropped so issue and PR agree.OCI_KEY_IDis the API-key triple or anST$token,so the same signer serves API keys today and minted principals later. Debug output
never prints the key id, because for principals it is the token.
signing_servicebecomes optional foroci. Policy validation and the runtimecheck require it only for the
sigv4*values. The server-side credential-sourceprecondition is keyed by scheme (
OCI_KEY_ID+OCI_PRIVATE_KEYforoci, the AWSnames for
sigv4*).bodies are rejected before anything reaches upstream. OCI's own SDKs omit the body
headers for Object Storage
PutObjectandUploadPart(enforce_content_headers=Falsein the Python SDK), so an
oci:no_bodymode mirroringsigv4:no_bodyis the naturalfollow-up for large uploads. It is left out of feat(sandbox): proxy-side OCI request signing for CONNECT tunnels #3962 to keep the first PR reviewable;
happy to include it if the community prefers one PR.
openshell_crypto::pki::KeyPair::from_pkcs8_der(PKCS#1 input is wrapped in a PKCS#8envelope first), signs through the facade key, and hashes bodies with
openshell_crypto::sha256. No directaws-lc-rsorsha2use, so the OpenSSL andFIPS backend selections apply to OCI signing too. Tests use a fixture RSA key like the
existing fixtures in
openshell-cliandopenshell-server.oci.yaml(endpointless, pairswith
credential_binding),oci-object-storage.yaml,oci-genai-native.yaml. Docs:ocilisted next tosigv4in thecredential_signingfield docs and the policyskill.
Proposal, part 2: OCI principal refresh strategies
Three strategies added to the
ProviderCredentialRefreshStrategyenum afterAWS_STS_ASSUME_ROLE = 6, dispatched in the gateway's provider refresh code next tomint_aws_sts_assume_role:oci_instance_principalauth.<region>.oraclecloud.com/v1/x509oci_resource_principaloci_oke_workload_identity:12250/resourcePrincipalSessionTokens)Each mints
OCI_KEY_ID = ST$<token>as the primary credential and co-mintsOCI_PRIVATE_KEY(for the two strategies where the gateway generates the session key)through
additional_outputs. Expiry is the token's JWTexp, capped bymax_lifetime_seconds. The sandbox sees placeholders only, and the signing path frompart 1 consumes the pair unchanged.
Responses to the triage review on #3961, to be adopted in #3975 before it leaves draft:
metadata,
auth.<region>.<realm>/v1/x509, the OKE proxymux) from the environment andrejects endpoint material through the configure API (CWE-918, mirroring the STS
sts_endpoint_urlrule); loopback overrides exist only undercfg(test). Theremaining gap is the resource-principal file paths (
rpst_file,private_key_file),which move from provider material to gateway configuration before the PR leaves draft.
principal to any provider configured with them, and IAM dynamic-group scoping applies
to the gateway, not to sandboxes. Operators will enable principal minting explicitly
in gateway configuration; the default is off.
oci_resource_principalthe session key comes fromthe platform; the issue text is corrected.
is added to
openshell-cryptofor the AWS-LC backend (the OpenSSL backend alreadygenerates RSA keys), and the session key, signing and hashing all go through the
facade, so the strategies respect backend selection and the dependency guardrail. The
one non-facade hash is the SHA-1 fingerprint of the instance certificate that OCI
requires in the
<tenancy>/fed-x509/<fingerprint>key id; it is a protocolidentifier, not an authenticity proof, and is documented as such in
CRYPTO.md, likethe existing WebSocket SHA-1 exception.
Security model
hostis the forwarded host; policy decides which hosts exist.configuration.
openshell-cryptoowns all cryptographic operations.Implementation state and verification
2026-11-04. Verified: 16 unit and proxy tests; live signer tests against Object Storage
and native Generative AI with an API-key principal and a session-token principal; a
full end-to-end run through a gateway and supervisor built from the branch (bucket and
object lifecycle, native chat, multimodal chat, denials by preset, placeholders only in
the sandbox). Table in the PR.
suites of six crates pass locally. Not yet verified: a live mint on OCI Compute, OKE or
Functions, because the development gateway runs on a laptop. The token-plus-key
transport it produces was proven live in the signing work.
/ok to test.What we ask the community to decide
state:accepted), together, since minted credentials have noconsumer without signing.
document using
rfc/0000-template.oci:no_bodybelongs in feat(sandbox): proxy-side OCI request signing for CONNECT tunnels #3962 or in a follow-up.All reactions