Home / OCI

OCIHow-toBeginner

OCI IAM basics: create your first compartment, group and policy

Learn how OCI access works by doing it. Create a compartment and a group, add a user, write readable policy statements with the right verbs and fix the NotAuthorizedOrNotFound error when access doesn't work.

Deepak Bhardwaj6 min read

Applies toOCI IAM, Identity Domains, OCI CLI

The goal

A new teammate can log in to OCI but can't see anything. That's by design: in OCI, everything is denied until a policy allows it. Here you'll give someone access to one compartment, and no more.

You need admin rights for this. Find your tenancy OCID in ~/.oci/config, or in the console under your profile.

export T=ocid1.tenancy.oc1..your-tenancy-id

The parts

Part Purpose
User A person or service account
Group A set of users. Policies grant access to groups
Compartment A logical container for resources
Policy Statements saying which group can do what, and where
Allow group <group> to <verb> <resource-type> in compartment <compartment>

That reads almost like a sentence, which makes policies easy to review.

Step 1: create a compartment

COMP=$(oci iam compartment create \
  --compartment-id "$T" \
  --name lab \
  --description "Lab resources for training" \
  --wait-for-state ACTIVE \
  --query 'data.id' --raw-output)
echo "$COMP"

IAM changes are made in your home region. If you get a region error, add --region with your home region's name. See compartments and OCIDs for more.

Step 2: create a group and add a user

GROUP=$(oci iam group create \
  --name lab-users \
  --description "People who work in the lab compartment" \
  --query 'data.id' --raw-output)

oci iam user list --compartment-id "$T" --all \
  --query 'data[].{name:name, id:id}' --output table

oci iam group add-user --group-id "$GROUP" --user-id ocid1.user.oc1..teammate-id

Tip

In tenancies with identity domains, these oci iam user and oci iam group commands work with the Default domain. Other domains are managed in the console, or with oci identity-domains. If your users don't appear, this is probably why. Your policy then names the group as 'DomainName'/'lab-users'.

Step 3: pick the right verb

Policies use four verbs, each including the one before it:

Verb Allows Typical person
inspect List resources, with limited metadata Auditor
read inspect, plus get details and contents Support engineer
use read, plus work with existing resources Operator
manage Everything, including create and delete Owner

And these are the resource types you'll use most:

Resource type Covers
instance-family Compute instances, images and more
virtual-network-family VCNs, subnets, gateways
volume-family Block and boot volumes
object-family Buckets and objects
all-resources Everything. Use with care

Step 4: write the policy

Start with read access to everything in the compartment, and add write access only for what the team runs:

oci iam policy create \
  --compartment-id "$T" \
  --name lab-users-policy \
  --description "Access for the lab-users group" \
  --statements '[
    "Allow group lab-users to read all-resources in compartment lab",
    "Allow group lab-users to manage instance-family in compartment lab",
    "Allow group lab-users to manage volume-family in compartment lab",
    "Allow group lab-users to use virtual-network-family in compartment lab"
  ]'

Where you attach the policy matters. It must sit in the compartment it names, or in a parent. Here, it's attached at the tenancy root, so it can name lab.

To launch an instance, a person needs more than instance-family: they also need to use the network and volumes. That's a common surprise, and it's why there are multiple statements above. The policy cheat sheet has more examples.

Warning

Avoid Allow group x to manage all-resources in tenancy. It's effectively full admin. Grant at compartment level, and keep tenancy-wide admin to a small, named group with MFA.

Step 5: test it

Have your teammate run these using their own profile. You can't simulate a policy from your side.

oci iam compartment list --compartment-id "$T" --query 'data[].name'
oci compute instance list --compartment-id "$COMP"
oci network vcn list --compartment-id "$COMP"

They should also see an error when trying a compartment that they haven't been given.

When access fails

OCI returns the same error when something doesn't exist and when you can't access it. That's a deliberate choice:

NotAuthorizedOrNotFound: Authorization failed or requested resource not found.

Work through this list:

Check How
Is the OCID right, and in this region? Check the compartment and --region
Is the user really in the group? List the group's members (command below)
Does a statement cover this action? Read the policy
Is the verb strong enough? use can't create, for example
Is the policy at the right level? It must be in that compartment or a parent
Is the group name correct, with the domain? Non-default domains need 'Domain'/'group'

List members and policies:

oci iam group list-users --group-id "$GROUP" --compartment-id "$T" --query 'data[].name'

oci iam policy list --compartment-id "$T" --all \
  --query 'data[].{name:name, statements:statements}'

Note that policies in child compartments won't appear when you list the root. Search those too. Find out who changed what in the audit logs.

Limit access further with conditions

You can narrow a statement with a where clause:

Allow group lab-users to manage instance-family in compartment lab where request.operation != 'TerminateInstance'

Conditions are powerful but easy to get wrong. Test them carefully. See policy conditions and tags when you're ready.

Applications shouldn't use user keys

Scripts on an instance don't need a user's API key. Use an instance principal, which gives the instance its own identity through a dynamic group. See workload identity.

Clean up

oci iam policy delete --policy-id <policy-ocid> --force
oci iam group remove-user --group-id "$GROUP" --user-id ocid1.user.oc1..teammate-id
oci iam group delete --group-id "$GROUP" --force
oci iam compartment delete --compartment-id "$COMP" --force

A compartment can only be deleted when it's empty. If it won't go, see compartment won't delete.

Caution

Deleting a policy takes access away from everyone who relied on it, and there's no undo. Copy the statements first. If you've already removed one, see deleted policy recovery.

Prevent it next time

  • Grant to groups, never one person at a time.
  • Keep policies short, with one owner each, and store them as code.
  • Use a separate compartment for each environment, and see the landing zone guide.
  • Review who is in your admin groups every quarter.