🧰 The Oracle Cloud CLI (oci): Config File, API Keys, Sessions and Query
How oci is organized, what oci setup config writes (and why that key file matters), profiles and browser sessions, JMESPath queries with the data wrapper and the built-in canned queries, and offline help
💡 How this page was tested. On 6 October 2026 I installed the Oracle Cloud CLI 3.94.2 with pip in a virtual environment, and ran everything that works without a real account: the version, the error when no configuration exists, the whole oci setup config walkthrough (with made-up OCIDs, so the file and the key it creates are real but useless), the oci_cli_rc file, and the offline help. Anything that talks to Oracle is marked from the documentation, not run here. The sibling pages: az, aws, gcloud and the comparison.
What oci is
oci is the Oracle Cloud Infrastructure command-line interface. Its own help explains the shape: "Most commands must specify a service, followed by a resource type and then an action. For example, to list users: oci iam user list --compartment-id $T" (where $T holds the OCID of the tenancy). So: oci compute instance list, oci os bucket create, oci iam compartment create. "Output is in JSON format."
The two things that make oci feel different from the others:
- OCIDs everywhere. Almost every command wants the OCID of a compartment (--compartment-id) or of a resource (see the account page). Keep them in shell variables.
- A key pair, not a login. The classic way to authenticate is an API signing key: a private key on your machine, whose public half you upload to your user in the console.
Getting it
python3 -m venv venv-oci venv-oci/bin/pip install oci-cli
(Oracle also offers an installer script: from the documentation, not run here.) Or skip installing: Cloud Shell in the OCI console has the CLI already authenticated. The version, and what an unconfigured oci says:
user@lab:~$ oci --version
3.94.2
user@lab:~$ oci iam region list
ERROR: Could not find config file at ~/.oci/config
Do you want to create a new config file? [Y/n]: Abort:
user@lab:~$ oci session --help | sed -n 1,10p
Usage: oci session [OPTIONS] COMMAND [ARGS]...
Session commands for CLI
Options:
-?, -h, --help For detailed help on any of these individual commands, enter
<command> --help.
Commands:
authenticate Creates a CLI session using a browser based login flow.
export Exports a CLI session into a zip that can be imported.
import Imports a CLI session from an archive.
refresh Refreshes a CLI session
terminate Terminates a CLI session by removing the entry from the...
validate Tests whether a CLI session is still valid
- oci --version printed 3.94.2.
- oci iam region list found no config file, and asked "Do you want to create a new config file? [Y/n]". (The answer in this test was to stop: Abort.) A missing config file is what a brand-new install says.
- oci session --help shows the session commands (see below).
The config file: oci setup config
oci setup config is an interactive walkthrough. It asks for a location for the config file, your user OCID, your tenancy OCID, a region (it prints a numbered list, and you can type the name), whether to generate a new API signing key pair, where to keep the keys, and a passphrase. I ran it with made-up OCIDs:
user@lab:~$ oci setup config
[...the walkthrough asks for: a location for the config, your user OCID,
your tenancy OCID, a region (it prints a numbered list), whether to generate
a new API signing key pair, where to keep it, and a passphrase ("N/A" for none)...]
Private key written to: ~/.oci/oci_api_key.pem
Fingerprint: 0c:9c:91:c4:cf:6d:65:43:63:2b:02:ca:77:8c:e7:2d
Config written to ~/.oci/config
If you haven't already uploaded your API Signing public key through the
console, follow the instructions on the page linked below in the section
'How to upload the public key':
https://docs.cloud.oracle.com/Content/API/Concepts/apisigningkey.htm#How2
user@lab:~$ cat ~/.oci/config
[DEFAULT]
user=ocid1.user.oc1..aaaaaaaaexampleuser
fingerprint=0c:9c:91:c4:cf:6d:65:43:63:2b:02:ca:77:8c:e7:2d
key_file=~/.oci/oci_api_key.pem
tenancy=ocid1.tenancy.oc1..aaaaaaaaexampletenancy
region=eu-frankfurt-1
user@lab:~$ ls -l ~/.oci
total 12
-rw------- 1 user user 260 Oct 6 16:15 config
-rw------- 1 user user 1715 Oct 6 16:15 oci_api_key.pem
-rw------- 1 user user 451 Oct 6 16:15 oci_api_key_public.pem
- The config file is ~/.oci/config, in an INI format with a [DEFAULT] profile: user, fingerprint (of the key), key_file, tenancy and region.
- The private key oci_api_key.pem is mode 600, like the config. It is the credential. Anyone who has the key file, your user OCID, your tenancy OCID and the fingerprint can act as you. (If you set a passphrase, the key itself is encrypted: a good idea for a laptop.)
- Then upload the public key, as the tool says: in the console, your user profile, API keys, Add API key, and paste oci_api_key_public.pem. Until then every command fails with an authorization error. The fingerprint that the console shows must match the one in the config.
- You can add more profiles by hand ([LAB], [WORK], each with its own user, tenancy, region and key) and choose with --profile NAME on a command. (The OCI_CLI_PROFILE environment variable does the same: it appears in the CLI's own code.) Where the home region is concerned, see the regions page: the region in the profile is the region the commands go to by default.
- A key file is a long-lived secret. Keep it out of backups that others can read, out of repositories and out of chat.
A login without a key: sessions
If you would rather not keep a long-lived key, the CLI has session commands, as the real help shows:
- oci session authenticate: "Creates a CLI session using a browser based login flow." You sign in as you would in the console, and the CLI stores a short-lived session token under a profile name of your choosing.
- oci session validate tests whether a session is still valid, oci session refresh renews it, and oci session terminate removes it. (Import and export are there too.)
- To use the session you pass the profile and the security-token authentication method on commands: --profile NAME --auth security_token. The real oci --help lists the --auth choices: api_key, instance_principal, security_token, instance_obo_user, resource_principal, oke_workload_identity and pkcs11.
- Instance principals (--auth instance_principal, one of the real choices above) let code running on an Oracle Cloud instance use that instance's identity with no key at all: the equivalent of a role on an AWS machine.
Output and query
- Output is JSON by default. The real help says --output [json|table], "the output format, default is json": table is for reading. Another real flag, --raw-output, prints a query result that is a single string without the JSON quotes: the one to use in scripts.
- Results are wrapped in a data key, so queries start with data: --query 'data[*].{id: id, name: "display-name"}'. --query takes JMESPath, the same language as az and aws (the comparison page has a primer).
- Field names have dashes (display-name, lifecycle-state, time-created), so in a query they must be in double quotes.
- Lists are paged: add --all to fetch every page (it is in the real help of oci iam region list).
And Oracle includes ready-made queries. oci setup oci-cli-rc writes a file of aliases and predefined ("canned") queries. This ran for real:
user@lab:~$ oci setup oci-cli-rc
user@lab:~$ head -n 16 ~/.oci/oci_cli_rc
[OCI_CLI_CANNED_QUERIES]
# For list results, this gets the ID and display-name of each item in the list.
get_id_and_display_name_from_list=data[*].{id: id, "display-name": "display-name"}
get_id_and_display_name_from_single_result=data.{id: id, "display-name": "display-name"}
# Filters where the display name contains some text
filter_by_display_name_contains_text=data[?contains("display-name", `your_text_here`)]
# Get the top 5 results from a list operation
get_top_5_results=data[:5]
# List instance public IPs from list vnics response
# Example: oci compute instance list-vnics --instance-id $I --query query://list_public_ips
list_public_ips=data[?"public-ip" != null]."public-ip"
You use one with --query query://NAME. For example (from the file's own comment): oci compute instance list-vnics --instance-id $I --query query://list_public_ips. Read the queries themselves, because they are a good JMESPath lesson: data[*].{id: id, "display-name": "display-name"} builds a small object per item, data[?contains("display-name", 'text')] filters by name, and data[:5] takes the first five.
Help, with no account
- oci --help, oci SERVICE --help, oci SERVICE RESOURCE ACTION --help. The help of a command lists every option and links to the API reference. (oci os bucket create --help and oci iam compartment create --help are real examples: the second explains that the tenancy is simply the root compartment and that a compartment name must be unique across the tenancy.)
- oci -i starts the CLI's interactive mode, which guides you through a command (from the CLI's own help text).
- The long list of services is in oci --help: IAM (oci iam), Object Storage (oci os), Compute (oci compute), Networking (oci network) and more.
Habits that save you
- Put the three OCIDs you need in shell variables: T for the tenancy, C for your lab compartment, and use --compartment-id $C.
- Check the profile and the region. The default region is the one in the profile, and Always Free resources need the home region.
- Use a compartment per experiment, and list it before you delete things.
- Protect ~/.oci: mode 600 on the key and the config, a passphrase on the key, and no copying it around.
- Prefer sessions or Cloud Shell if you do not need a long-lived key.
- Add --all when a list looks too short.
The cheat sheet
- Shape: oci SERVICE RESOURCE ACTION --option. Examples: oci os ns get, oci iam compartment create, oci compute instance list --compartment-id OCID. Help: --help, oci -i.
- Not configured: "Could not find config file ... Do you want to create a new config file?" Run oci setup config (OCIDs, region, API key). Upload oci_api_key_public.pem to your user in the console.
- Files: ~/.oci/config ([DEFAULT], more profiles by hand), ~/.oci/oci_api_key.pem (mode 600, the credential). Profile: --profile NAME.
- Key-less: oci session authenticate (browser, short-lived), --auth instance_principal on an instance, Cloud Shell.
- Output: JSON; --output table; --query 'data[*].{...}' (JMESPath, dashes in quotes); --query query://NAME (canned queries from oci setup oci-cli-rc); --all.
← The Google Cloud CLI (gcloud): Sign In, Configurations, Format and Filter · ↑ All tutorials · Four Cloud CLIs Side by Side: az, aws, gcloud and oci →