-
Notifications
You must be signed in to change notification settings - Fork 2
Authentication Reference
If you are new to OCI or OCInferno, read Getting Started first.
This page is the canonical auth reference for OCInferno. It covers what each auth mode is, how to set it up, and where to retrieve credential material.
- Auth Modes at a Glance
- OCInferno Startup Commands
- Config Profile (Profile Reuse)
- API Key
- Session Token
- Instance Principal
- Resource Principal
- Special Cases
- Auth Operational Notes
- Common Auth Errors
- Source References
| Auth Type | Supported in OCInferno | Typical Credential Source | Rotation Model | Common Use |
|---|---|---|---|---|
| Config Profile | Yes (profile) |
~/.oci/config profile entries (for example DEFAULT, MYPROFILE) |
Depends on backing profile type (API key static or session token refresh) | Fastest way to reuse existing OCI CLI/SDK auth setup |
| API Key | Yes (profile, api-key) |
~/.oci/config + private key PEM, or direct CLI flags |
Long-lived unless manually rotated | Human/operator auth and automation |
| Session Token | Yes (profile, session-token) |
~/.oci/config + security_token_file, or direct CLI flags |
Auto-refreshed by OCInferno when within 10 min of expiry; signed POST to auth service, no CLI needed | Human/browser-backed temporary auth |
| Instance Principal | Yes (instance-principal) |
IMDS or local cert/key reference file | Automatically refreshed STS token | Running as an OCI compute instance principal |
| Delegation Token / OBO — Instance Principal | Yes (instance-principal --delegation-token[-file]) |
Cloud Shell /etc/oci/delegation_token (+ instance-principal cert material) |
Token source re-read each load; instance STS auto-refreshed | Acting on behalf of the Console user from Cloud Shell / off-box |
| Resource Principal | Yes (resource-principal) |
Explicit CLI values and/or reference-file RPST + private key | Token rotation handled by runtime source and reload | OCI Functions / managed workload identity (Data Science, Data Flow, OKE WI, etc.) |
At startup, add credentials with one of the following patterns:
profile
profile <credential_name> --filepath <file_path> [--profile <profile_name>]
api-key
api-key <credential_name> \
--user <user_ocid> \
--fingerprint <fingerprint> \
--tenancy-id <tenancy_ocid> \
--region <oci_region> \
(--private-key <pem_or_path> | --private-key-file <path>) \
[--passphrase <passphrase>] [--passphrase-file <path>]
session-token
session-token <credential_name> \
(--token <token_or_path> | --token-file <path>) \
--region <oci_region> \
[--tenancy-id <tenancy_ocid>] \
(--private-key <pem_or_path> | --private-key-file <path>) \
[--passphrase <passphrase>] [--passphrase-file <path>]
instance-principal
instance-principal <credential_name> \
(--reference-file <reference_file> | --on-host) \
[--region <oci_region>] [--imdsv1|--imdsv2] \
[--proxy <host:port|url>] [--debug-http] \
[--delegation-token <obo_or_path> | --delegation-token-file <path>]
resource-principal
resource-principal <credential_name> \
[--reference-file <reference_file>] \
[--token <rpst_or_path>] [--token-file <path>] \
[--private-key <pem_or_path>] [--private-key-file <path>] \
[--region <oci_region>] [--tenancy-id <tenancy_ocid>] \
[--passphrase <passphrase>] [--passphrase-file <path>] \
[--proxy <host:port|url>] [--debug-http] \
[--delegation-token <obo_or_path> | --delegation-token-file <path>]
Quick startup examples:
profile MY_PROFILE --filepath ~/.oci/config --profile MY_PROFILE
api-key TEST_API_KEY --user ocid1.user.oc1..aaaa... --fingerprint 12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef --tenancy-id ocid1.tenancy.oc1..aaaa... --region us-phoenix-1 --private-key-file ~/.oci/oci_api_key.pem
After startup:
-
creds/creds me/creds me-full -
creds list/creds list-full creds db-row [<credname>]creds swap [<credname>]
Input handling note:
- For
--token,--private-key, and similar fields, OCInferno accepts either:- an inline value (JWT / PEM string), or
- a file path (including
file://...) that it will read.
- If a value points to an existing file path, the file content is loaded automatically.
- Startup credential parsing uses shell-style tokenization, so quoted values are supported.
- OCID values must be valid OCI IDs (for example,
ocid1.user...,ocid1.tenancy...).
If you already maintain OCI CLI profiles, this is the fastest path for OCInferno.
In practice, profile <credname> --filepath <config> [--profile <name>] lets you reuse the same ~/.oci/config profiles used by OCI CLI and SDK tooling.
API key backed profile:
[DEFAULT]
user=ocid1.user.oc1..example
fingerprint=11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00
tenancy=ocid1.tenancy.oc1..example
region=us-phoenix-1
key_file=/home/user/.oci/oci_api_key.pemSession-token backed profile:
[SESSION]
fingerprint=aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99
key_file=/home/user/.oci/sessions/SESSION/oci_api_key.pem
tenancy=ocid1.tenancy.oc1..example
region=us-phoenix-1
security_token_file=/home/user/.oci/sessions/SESSION/token| Profile Signal | Effective Auth Path |
|---|---|
security_token_file present |
Session token profile logic |
security_token_file absent |
API key profile logic |
Command pattern:
profile mycred --filepath ~/.oci/config --profile DEFAULT
API key auth uses an OCI user key pair (public key uploaded to the user, private key kept locally). This is typically static and does not expire by default.
- Generate a key pair and protect the private key file.
- Upload the public key to OCI IAM user credentials.
- Build or update a profile in
~/.oci/config.
Example ~/.oci/config profile:
[DEFAULT]
user=ocid1.user.oc1..aaaa...
fingerprint=12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef
tenancy=ocid1.tenancy.oc1..aaaa...
region=us-phoenix-1
key_file=/home/user/.oci/oci_api_key.pemYou can also gather these values directly from OCI Console during API key generation:
tenancyuserfingerprintregion- local private key file path (
key_file)
Profile-based (reuse existing ~/.oci/config profile):
profile my-api-profile --filepath ~/.oci/config --profile DEFAULT
Direct API-key mode (no profile required):
api-key my-api-direct \
--user ocid1.user.oc1..aaaaexampleuser \
--fingerprint 12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef \
--tenancy-id ocid1.tenancy.oc1..aaaaexampletenancy \
--region us-phoenix-1 \
--private-key-file ~/.oci/oci_api_key.pem
Direct API-key mode with inline private key value:
api-key my-api-inline \
--user ocid1.user.oc1..aaaaexampleuser \
--fingerprint 12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef \
--tenancy-id ocid1.tenancy.oc1..aaaaexampletenancy \
--region us-phoenix-1 \
--private-key "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
| Field | Required | Source |
|---|---|---|
user |
Yes | OCI user OCID |
tenancy |
Yes | Tenancy OCID |
fingerprint |
Yes | Uploaded API key fingerprint |
Private key (key_file or inline key content) |
Yes | Local PEM file or inline PEM |
region |
Yes for direct api-key mode; recommended for profile mode |
Profile region or CLI flag |
Example IAM/API-key UI flow (adapted from OCISigner wiki):
- Open your identity domain and user details.
- Use the API key action on the user.
- Capture generated config values and key files.
Reference:
Session token auth is temporary user auth. In practice, you authenticate interactively and the OCI CLI writes a profile that references a token file in the background on your system. To use session based auth you just need to point to the config entry or the specific token and private key on disk.
Generate session credentials:
oci session authenticateThis writes:
- A profile entry in
~/.oci/config - A token file under
~/.oci/sessions/<profile>/token
Example ~/.oci/config session profile:
[MYPROFILE]
fingerprint=8e:50:1d:be:cc:2e:66:6d:b3:b5:e5:4a:1c:f4:f5:03
key_file=/home/user/.oci/sessions/MYPROFILE/oci_api_key.pem
tenancy=ocid1.tenancy.oc1..aaaa...
region=us-phoenix-1
security_token_file=/home/user/.oci/sessions/MYPROFILE/tokenProfile-based session token:
profile mysession --filepath ~/.oci/config --profile MYSESSIONPROFILE
Direct session-token mode (token + key files):
session-token mysession-direct \
--token-file ~/.oci/sessions/MYSESSIONPROFILE/token \
--private-key-file ~/.oci/sessions/MYSESSIONPROFILE/oci_api_key.pem \
--region us-phoenix-1
Direct session-token mode (inline token string):
session-token mysession-inline \
--token "<JWT_TOKEN_VALUE>" \
--private-key-file ~/.oci/sessions/MYSESSIONPROFILE/oci_api_key.pem \
--region us-phoenix-1 \
--tenancy-id ocid1.tenancy.oc1..aaaaexampletenancy
Notes:
-
--tenancy-idis optional if tenancy can be extracted from the token claims. - If tenancy cannot be extracted,
--tenancy-idis required.
| Field | Required | Source |
|---|---|---|
Session token (security_token_file or inline token content) |
Yes | Token file path or --token value |
Private key (key_file or inline key content) |
Yes | Key file path or --private-key value |
tenancy |
Yes (explicit or auto-extracted from token claims) |
--tenancy-id or JWT claims |
region |
Yes for direct session-token mode; recommended for profile mode |
Profile region or CLI flag |
fingerprint |
Profile mode only | Session profile fingerprint |
OCInferno refreshes session tokens automatically — no manual oci session refresh needed while the tool is running.
How it works:
Before every module dispatch, OCInferno checks the JWT exp claim of the active session token. If the token is within 10 minutes of expiry it performs a signed POST directly to the OCI auth service's refresh endpoint:
POST https://auth.<region>.oraclecloud.com/v1/authentication/refresh
{"currentToken": "<current_jwt>"}
The request is signed with the profile's own private key (same mechanism oci session refresh uses internally — no CLI process or shell-out involved). On success the new token is written back to the DB and optionally mirrored to the on-disk security_token_file if one was configured. The in-memory signer is rebuilt immediately so the next API call uses the fresh token.
Rate limiting: refresh is attempted at most once per minute per running session to avoid hammering the endpoint during bursts of module calls.
When auto-refresh fails:
-
401from the refresh endpoint means the token has expired past its refresh window — re-authenticate withoci session authenticateand re-add the credential. - Missing
key_contentorregionin stored credentials (can happen with partially configured profiles) — OCInferno prints a warning and skips the refresh.
Manual refresh (outside OCInferno):
oci session refresh --profile MYPROFILEExample session token UI flow (adapted from OCISigner wiki):
- Start browser-based auth from
oci session authenticate.
- Complete callback and profile creation.
Reference:
Instance principal auth lets code call OCI APIs as a compute instance identity. Effective permissions come from dynamic-group membership and IAM policy grants for that dynamic group. Note all other resources fall under resource principal auth, instance principal is just a unique workflow SPECIFICALLY for compute instance resources.
Note: We currently support commercial OCI accounts only; government region support is planned for a future release.
Use one of two modes:
- On-host mode (
--on-host): run on OCI compute and it will query all relevant IMDS endpoints and auto-configure the auth profile. - Reference-file mode (
--reference-file): Run on one's local filesystem using the cert/key/intermediate material from the compute instance (gathered via SSRF, command execution, SSH access, etc.).
The following shows how to retrieve metadata and identity material endpoints (cert, key, intermediate files) from the compute instance itself. Note that IMDSv2 requires the hardcoded "Authorization: Bearer Oracle" header while v1 does not. To use the cert/intermediate/key PEM files locally, copy the stdout output to your local machine:
# Metadata
curl -s -H "Authorization: Bearer Oracle" http://169.254.169.254/opc/v2/instance/
curl -s -H "Authorization: Bearer Oracle" http://169.254.169.254/opc/v2/instance/regionInfo/
curl -s -H "Authorization: Bearer Oracle" http://169.254.169.254/opc/v2/instance/tenantId
# Identity Material (IMDSv2 — Authorization header required)
curl -sSL -H "Authorization: Bearer Oracle" http://169.254.169.254/opc/v2/identity/cert.pem -o cert.pem
curl -sSL -H "Authorization: Bearer Oracle" http://169.254.169.254/opc/v2/identity/intermediate.pem -o intermediate.pem
curl -sSL -H "Authorization: Bearer Oracle" http://169.254.169.254/opc/v2/identity/key.pem -o key.pemMinimal JSON example for --reference-file:
{
"leaf_cert_file": "./certs/leaf_cert.pem",
"leaf_key_file": "./certs/leaf_key.pem",
"intermediate_cert_file": "./certs/intermediate.pem",
"region": "us-phoenix-1",
"tenancy_id": "ocid1.tenancy.oc1..aaaaexampletenancy"
}JSON example with multiple intermediates and TLS bundle for reference-file:
{
"leaf_cert_file": "./certs/leaf_cert.pem",
"leaf_key_file": "./certs/leaf_key.pem",
"intermediate_cert_files": [
"./certs/intermediate_1.pem",
"./certs/intermediate_2.pem"
],
"passphrase_file": "./certs/leaf_key.passphrase",
"ca_bundle_file": "./certs/ca_bundle.pem",
"region": "us-phoenix-1",
"tenancy_id": "ocid1.tenancy.oc1..aaaaexampletenancy",
"log_requests": true
}key=value example:
# instance principal reference file
leaf_cert_file=./certs/leaf_cert.pem
leaf_key_file=./certs/leaf_key.pem
intermediate_cert_file=./certs/intermediate.pem
region=us-phoenix-1
tenancy_id=ocid1.tenancy.oc1..aaaaexampletenancy
ca_bundle_file=./certs/ca_bundle.pemOn-host mode:
instance-principal myip --on-host --region us-phoenix-1 --imdsv2
Reference-file mode:
instance-principal myip-ref --reference-file ./auth/instance_principal.json --region us-phoenix-1
Reference-file mode with proxy + debug:
instance-principal myip-ref --reference-file ./auth/instance_principal.env --proxy http://127.0.0.1:8080 --debug-http
--debug-http note:
- Enables additional federation debug logging during auth setup (for example endpoint/preflight diagnostics).
| Field | Required | Source |
|---|---|---|
leaf_cert_file |
Yes for reference-file mode | Local file (often sourced from IMDS cert.pem) |
leaf_key_file |
Yes for reference-file mode | Local file (often sourced from IMDS key.pem) |
intermediate_cert_file / intermediate_cert_files
|
Yes for reference-file mode | Local file(s) (often sourced from IMDS intermediate.pem) |
region |
Required unless auto-detected via IMDS | CLI --region, reference file, or IMDS |
tenancy_id |
Required unless auto-detected via IMDS | Reference file or IMDS |
- Signer reads leaf cert/key/intermediate material.
- Signer sends signed request to
https://auth.<region>.oraclecloud.com/v1/x509(Note Gov support is on the Roadmap for v1.0) - OCI returns short-lived federation token in tool.
- Subsequent module requests use that token-backed signing context.
Note: You can use the --proxy flag as shown in the example command above to observe the certificate exchange for the JWT used in future module requests. This is one of the few APIs not covered by the workspace proxy configuration. During instance-principal federation setup, OCInferno temporarily sets HTTP_PROXY, HTTPS_PROXY, http_proxy, and https_proxy in the process environment while initializing signer traffic, then restores the previous values immediately after setup completes.
Example instance-principal flow (adapted from OCISigner wiki):
- Start from a compute instance host.
Reference:
Resource principal auth is identity for OCI-managed runtimes (for example, Functions). Credentials are generally supplied to the runtime via environment variables and exchanged for temporary tokens. You can pull the private key and token (Resource Principal Session Token - RPST) from the environment variables and feed them into ocinferno to call things as that resource.
In OCI workloads, configure runtime and policy so the resource principal can assume required permissions.
OCInferno supports resource-principal credential loading. You can provide material directly (--token, --private-key) or via --reference-file.
A practical setup path is OCI Data Science notebook sessions (or other OCI managed runtimes) where RPST and key material are exposed to the workload environment.
Accepted file formats:
- JSON object
- plain
key=valuelines (#comments allowed)
Minimal JSON example:
{
"rpst_file": "./token/rpst.jwt",
"private_pem_file": "./keys/rp_private.pem",
"region": "us-phoenix-1",
"tenancy_id": "ocid1.tenancy.oc1..aaaaexampletenancy"
}Inline JSON example:
{
"rpst_content": "<JWT_TOKEN_VALUE>",
"private_pem_content": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
"region": "us-phoenix-1"
}key=value example:
# resource principal reference file
token_file=./token/rpst.jwt
private_key_file=./keys/rp_private.pem
region=us-phoenix-1
tenancy_id=ocid1.tenancy.oc1..aaaaexampletenancy
passphrase_file=./keys/rp_key.passphraseReference-file driven:
resource-principal myrp --reference-file ./auth/resource_principal.json
Direct values/paths only (no reference file):
resource-principal myrp-direct \
--token-file /etc/ssl/security.token \
--private-key-file /etc/ssl/rp_key.pem \
--region us-phoenix-1 \
--tenancy-id ocid1.tenancy.oc1..aaaaexampletenancy
Mixed mode (file + CLI override):
resource-principal myrp-mixed \
--reference-file ./auth/resource_principal.env \
--region us-ashburn-1
| Field | Required | Source |
|---|---|---|
| RPST | Yes |
--token / --token-file or reference-file token keys |
| Private key | Yes |
--private-key / --private-key-file or reference-file key keys |
| Region | Recommended |
--region or reference-file region
|
| Tenancy ID | Optional |
--tenancy-id or reference-file tenancy_id; auto-extracted from RPST if omitted |
In OCI-managed runtimes, resource-principal material is often exposed through environment variables and/or mounted files. Use those values as input sources, then pass them explicitly to OCInferno via CLI flags or a reference file.
Example resource-principal flow (adapted from OCISigner wiki):
- Create/open a managed runtime (example: Data Science notebook session).
- Open terminal on the workload host and inspect RP env vars/files.
- Observe the token and key values from the env variables
(base) bash-4.4$ env | grep Resource -i
OCI_RESOURCE_PRINCIPAL_PRIVATE_PEM=/etc/ssl/rp_key.pem
OCI_RESOURCE_PRINCIPAL_RPT_PATH=/20190101/notebookSessions/{id}/actions/getResourcePrincipalToken
OCI_RESOURCE_PRINCIPAL_RPST=/etc/ssl/security.token
OCI_RESOURCE_PRINCIPAL_REGION=us-phoenix-1
OCI_RESOURCE_PRINCIPAL_RPT_ID=ocid1.datasciencenotebooksession.oc1.phx.amaaa[REDACTED]
OCI_RESOURCE_PRINCIPAL_RPT_ENDPOINT=https://datascience.us-phoenix-1.oci.oraclecloud.com
(base) bash-4.4$ cat /etc/ssl/security.token
eyJraWQ...[RPST_JWT_CONTENT]...
(base) bash-4.4$ cat /etc/ssl/rp_key.pem
-----BEGIN RSA PRIVATE KEY-----
[PRIVATE_KEY_CONTENT]
-----END RSA PRIVATE KEY-----Reference:
This section covers two distinct patterns that don't fit cleanly under a single auth mode:
-
Instance Principal Delegation Token (OBO) — an optional add-on that layers a Console user's permissions on top of an instance-principal signer. Cloud Shell is the primary use case; Oracle automatically drops an OBO token at
/etc/oci/delegation_tokenthat elevates the session to the full Console user's permissions. -
OKE Workload Identity — a different way to acquire the RPST that
resource-principalalready consumes. Not a delegation token: noopc-obo-tokenheader, no user impersonation — just a Kubernetes ServiceAccount JWT exchanged for an OCI RPST via the in-cluster proxymux endpoint.
A delegation token (a.k.a. an on-behalf-of / OBO token) is an OPTIONAL add-on to instance-principal auth — it does not replace the signer, it rides on top of it. The instance-principal signer still produces the actual request signature; the delegation token is attached as a signed opc-obo-token header on every outbound API request. That header tells OCI: "this principal is acting on behalf of the user named in the token." The model is two layers: instance-principal signing = who is calling, delegation token = who they are acting as.
Cloud Shell is the primary scenario where delegation tokens are encountered in the wild. Oracle automatically mints an OBO token inside Cloud Shell and makes it available at /etc/oci/delegation_token (also exported as OCI_DELEGATION_TOKEN_FILE, alongside OCI_CLI_AUTH=instance_obo_user). It is short-lived (~1h) and rotated in place. OCInferno stores the token source (the file path) rather than the token content and re-reads it on every credential load, so rotation is handled automatically with no intervention required.
To retrieve the token from inside Cloud Shell:
cat "${OCI_DELEGATION_TOKEN_FILE:-/etc/oci/delegation_token}"Add --delegation-token (or --delegation-token-file) to a normal instance-principal command. Two modes are supported:
-
--on-host: the SDK bootstraps the instance principal automatically from the environment and OCInferno attaches the token. Use this when running in the same environment where the delegation token is available (e.g. directly inside Cloud Shell). -
--reference-file(off-box): reconstruct the instance-principal signer from harvested cert material and attach the token, so you can operate with the delegated user's permissions from your own machine.
For off-box use, harvest the instance-principal cert material in addition to the delegation token:
curl -sSL http://169.254.169.254/opc/v2/identity/cert.pem -o cert.pem
curl -sSL http://169.254.169.254/opc/v2/identity/intermediate.pem -o intermediate.pem
curl -sSL http://169.254.169.254/opc/v2/identity/key.pem -o key.pemCloud Shell / on-host (simplest, no cert harvesting needed):
instance-principal mydeleg --on-host --region us-phoenix-1 --delegation-token-file /etc/oci/delegation_token
Off-box (reference-file cert material + the delegation token, from your own machine):
instance-principal mydeleg-ref --reference-file ./auth/instance_principal.json --delegation-token-file ./auth/delegation_token
Inline token value instead of a file:
instance-principal mydeleg --on-host --region us-phoenix-1 --delegation-token <PASTE_OBO_TOKEN>
| Field | Required | Source |
|---|---|---|
--delegation-token-file |
One of token-file / token | Path to the OBO token file; re-read each load so rotation is handled automatically |
--delegation-token |
One of token-file / token | The OBO token value directly (or a path to it) |
| instance-principal fields | Yes | Same as Instance Principal above (--on-host or --reference-file + region/tenancy) |
Notes:
- Without a delegation flag, the identical command is a plain instance principal.
- Effective permissions = the delegated Console user's, evaluated in their tenancy (the token's
tenantclaim). - The underlying instance-principal federation must succeed for the OBO header to be honored.
Note: For a bash-only extraction flow (no OCI SDK required), see
scripts/oke_wi_extract.shand the Exploit Module Reference → Manual Extraction Reference.
This is not a separate OCInferno auth mode -- it is a second way to acquire the RPST +
private key that the resource-principal credential type above already consumes. OKE
Workload Identity (Enhanced clusters only) is OCI's equivalent of AWS IRSA / GCP Workload
Identity: a pod's normal Kubernetes ServiceAccount token gets exchanged for an OCI
resource-principal session token, scoped to request.principal.type='workload' (see
request.principal.type).
Unlike the Data Science notebook case above, there is no static token file waiting on
disk -- the exchange is performed live, and it needs nothing special: a plain pod with
serviceAccountName: <sa> and automountServiceAccountToken: true (the default) already
has everything required, no annotation or opt-in needed on the pod itself.
How it works under the hood:
- Kubelet auto-mounts a standard, cluster-signed ServiceAccount JWT at
/var/run/secrets/kubernetes.io/serviceaccount/token-- this is a generic Kubernetes feature, not OCI-specific, and it exists on essentially every pod by default. - The OCI SDK's
oci.auth.signers.get_oke_workload_identity_resource_principal_signer()generates a fresh, in-memory-only RSA keypair, thenPOSTs to an in-cluster endpoint reachable at the cluster's internal Kubernetes service IP on port12250(theproxymuxcomponent, also visible inkube-systemand as theKUBERNETES_SERVICE_PORT_PROXYMUXenv var on every pod):https://<k8s-service-ip>:12250/resourcePrincipalSessionTokens, withAuthorization: Bearer <service-account-jwt>and body{"podKey": "<PEM public key>"}. -
proxymuxvalidates the JWT and returns a signed RPST (issued byauthService.oracle.com) whose claims embed the calling pod's namespace, service account, and cluster OCID (var_namespace,var_service_account,var_cluster_id-- these map 1:1 onto therequest.principal.*conditionals a policy checks), plus the caller's freshly-generated public key. The matching private key never leaves the pod's memory and is never written to disk -- the RPST alone cannot sign requests without it. - Nothing is cached to disk; the signer keeps the token/key pair in memory for its process lifetime and refreshes it as it nears expiry.
Retrieving it and feeding it back into OCInferno. From inside a pod with code
execution (webshell, RCE, kubectl exec, or any other way to run code in that pod's
context), install the OCI SDK and run the exchange yourself, then export the two values
resource-principal needs. If the OCI SDK is not available, use the bash-only script
scripts/oke_wi_extract.sh
(see also Exploit Module Reference → Manual Extraction Reference).
import oci
from cryptography.hazmat.primitives import serialization
signer = oci.auth.signers.get_oke_workload_identity_resource_principal_signer()
rpst = signer.rpst
private_pem = signer.session_key_supplier.private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
).decode()
print("RPST:", rpst)
print("PRIVATE_PEM:\n", private_pem)Then load it the same way as any other resource-principal credential -- this is not a
new auth mode, it is the exact same resource-principal type covered above.
add_resource_profile_token builds an oci.auth.signers.SecurityTokenSigner straight
from whatever RPST + PEM text you give it (load_pem_private_key(...) then
SecurityTokenSigner(token, private_key_obj)) -- it has no idea, and does not care,
whether the token came from a Data Science notebook or an OKE pod:
resource-principal oke-wi-pod \
--token <rpst_value> \
--private-key <private_pem_value> \
--region us-phoenix-1
This is a startup-time command (the credential-add flow when you launch ocinferno and
create/select a workspace) -- the runtime creds REPL command only exposes
me/list/db-row/swap for already-loaded credentials, not adding a new one, so you
add the workload identity credential the same way you'd add any other, then swap to it.
Three things worth calling out:
-
No auto-refresh once loaded. Unlike a live pod (which can re-run the exchange any
time), OCInferno just stores the RPST/PEM text you gave it and rebuilds the same signer
on reload -- there is no refresh callback for
resource-principalthe way there is for instance-principal or session-token. The RPST we minted live had roughly a 12-hour TTL (exp-iatin the JWT claims); once it expires, calls start failing and you need to re-run the exchange from inside a pod and re-add the credential with a fresh token. -
This only proves out whatever the matched policy actually grants -- the RPST is
scoped to the exact
(namespace, service_account, cluster_id)triple it was minted for, so it is only useful if some policy in the tenancy actually grantsrequest.principal.type='workload'to that combination (or a broaderany {}match on a subset of those fields). -
It is bound to the pod's process, not portable as a static secret -- because the
private key is ephemeral and in-memory-only, you cannot grab a previously-minted
RPST from disk or logs the way you can the Data Science
/etc/ssl/security.tokenfile above. What IS durably retrievable is the ServiceAccount JWT itself (a plain file read); turning that into a usable OCI credential still requires reaching the in-clusterproxymuxendpoint, either by running the exchange from inside the cluster network (any pod, or a pivot such askubectl port-forward/--proxy) or by running it directly inside the compromised pod as shown above.
- Startup supports
ocinferno --auth-proxy <host:port|url>(orpython -m ocinferno --auth-proxy <host:port|url>) for credential auth exchanges during startup add/load. -
--silentstarts OCInferno without printing the initial help banner. -
--workspace <name> --cred <credname>(aliases:--credname) drive a non-interactive startup: load the named credential in the named workspace directly, skipping the workspace/credential picker menus. Combine with--module <module_name>to run one module non-interactively and exit (see Orchestration Module Reference).
Use this section to quickly map startup auth failures to likely causes and fixes.
| Error Message (or prefix) | Likely Cause | Quick Fix |
|---|---|---|
[X] Loaded profile config failed validation: {'tenancy': 'malformed', 'fingerprint': 'malformed'} |
Tenancy OCID and/or fingerprint format is invalid (for example typo like cid1... instead of ocid1..., or copied extra characters). |
Re-copy values from OCI config/console. Confirm OCIDs start with ocid1. and fingerprint is colon-delimited hex. |
[X] Failed to parse credentials. Check for unmatched quotes. |
Startup command has unbalanced quotes. | Close/remove stray quotes and retry. |
[X] Missing user OCID for api-key auth... (or missing fingerprint/tenancy/region/private key variants) |
Required api-key argument missing. |
Supply all required fields: --user, --fingerprint, --tenancy-id, --region, and key (--private-key or --private-key-file). |
[X] Could not initialize api-key credentials from supplied settings. |
Input passed basic checks but signer/profile validation failed (bad key file, wrong passphrase, malformed IDs, invalid fingerprint). | Validate key file content/permissions, passphrase, OCIDs, and fingerprint formatting. |
[X] Missing session token... / [X] Missing private key for session-token auth...
|
Direct session-token mode missing token or key material. | Provide token (--token or --token-file) and key (--private-key or --private-key-file). |
[X] Missing tenancy for session-token auth... |
Tenancy was not supplied and could not be extracted from JWT claims. | Add --tenancy-id <tenancy_ocid>. |
[X] Missing instance-principal mode. Use --on-host or --reference-file. |
Neither mode selector supplied. | Provide exactly one: --on-host or --reference-file. |
[X] Failed loading instance-principal reference file: ... |
Reference file path invalid, unreadable, or missing required keys/cert files. | Check path and required keys: leaf_cert_file, leaf_key_file, and intermediate cert (intermediate_cert_file or intermediate_cert_files). |
[X] Missing region. Provide --region when using --on-host. |
Region not set and metadata lookup failed. | Pass --region explicitly. |
[X] Failed loading resource-principal reference file: ... |
Resource-principal reference file path invalid or unreadable. | Confirm file exists and is readable. |
[X] Missing resource principal token (RPST)... |
No RPST found from CLI args or reference file. | Provide --token / --token-file / --reference-file. |
[X] Missing resource principal private key... |
No private key found from CLI args or reference file. | Provide --private-key / --private-key-file / --reference-file. |
[X] Use only one resource-principal reference file path. |
Multiple reference-file paths were provided with conflicting values. | Provide only one reference file source for the command. |
OCISigner wiki pages (structure and workflows):
- https://github.com/NetSPI/OCISigner/wiki/Auth-API-Key
- https://github.com/NetSPI/OCISigner/wiki/Auth-Security-Token
- https://github.com/NetSPI/OCISigner/wiki/Auth-Instance-Principal
- https://github.com/NetSPI/OCISigner/wiki/Auth-Resource-Principal
Oracle docs:
Home | Getting Started | Auth | Workspace | Orchestration Modules | Downloads to Disk | Data View/Export | Operator Runbook | Troubleshooting and FAQ | OpenGraph - Node/Edge Tables | OpenGraph - Default Priv Escalation Mode | OpenGraph - IAM Conditionals | OpenGraph - Inheritance & IncludeAll | ConfigChecker - Static Config Checks | Module Development Guide
- Authentication Reference
- Workspace Instructions
- Orchestration Module Reference
- Enumeration Module Reference
- Exploit Module Reference
- Downloads to Disk
- Data View/Export
- Troubleshooting and FAQ