How-to guide

Apply least privilege to Oracle Cloud identities

Learn how to scope Oracle Cloud IAM policies by compartment, group and condition so people and workloads get only the access they need.

By the Cloudverg engineering team · · 4 min read

Why this matters

Oracle Cloud IAM policies are allow only. There is no deny statement. Every grant adds up, and a policy attached high in the compartment tree reaches every child compartment. One loose statement can open the whole tenancy.

Least privilege in Oracle Cloud is mostly a design job. Compartments organize resources. Groups hold people. Dynamic groups hold workloads. Policies join them. When those three line up, a developer can restart an instance in the dev compartment without touching production, and an app can read one secret without holding a user API key.

Broad access hurts operations too. It hides who changed what, makes audit logs noisy, and turns a small mistake into an outage. Narrow grants make reviews shorter and incident response calmer.

Before you start

Export current state. In the Console, go to Identity and Security, then Identity, then Policies. Use the OCI CLI to list policies, groups and dynamic groups with oci iam policy list --compartment-id , oci iam group list and oci iam dynamic-group list. Save the output in version control. Search for manage all-resources, use all-resources, any-user, all-resources and in tenancy.

Draw the compartment tree and the job roles. Mark shared services: network hub, logging, backups, security. Decide which team owns each compartment. If a team needs read only access across the tenancy, treat that as a separate named role, not a default.

Check identity domains. Oracle Cloud can have more than one identity domain, and group names can repeat. Confirm which domain each group belongs to before writing policy statements. Also decide how workloads authenticate. Use instance principals or resource principals, not long lived user API keys.

How to do it

Change one layer at a time. Start with a test compartment and a test group. Write the policy in a file, apply it with Terraform or the CLI, then test with a real user and a real workload. Keep the old policy text so you can roll back.

Use the narrowest verb that works: inspect to list, read to view details, use to work with existing resources, manage to create and delete. Scope by compartment and resource family before you add conditions. Conditions are useful for bucket names, network ranges and tags, but they do not replace a tight compartment boundary.

  1. Map compartments to teams and apps. Put each app in its own compartment under a shared parent. Grant access at that app compartment, not at the tenancy root.
  2. Create job groups. Name groups after the work, such as app-prod-readers or network-operators. Put people in groups through your identity domain or federation, and do not create a new group for every one off request.
  3. Replace broad statements with resource families. Use instance-family, volume-family, object-family or virtual-network-family instead of all-resources. Keep manage only for the small group that truly creates and deletes those resources.
  4. Add conditions where they help. A bucket grant can include where target.bucket.name='app-prod-assets'. An admin grant can include where request.network.source.ip in ('203.0.113.0/24') for API and CLI traffic, but test console behavior before you rely on it.
  5. Use dynamic groups for workloads. Match instances by compartment, for example instance.compartment.id = 'ocid1.compartment...'. Grant that dynamic group only the secrets, buckets or queues the app needs.
  6. Attach policies at the lowest useful compartment. A child policy cannot undo a parent grant. If a parent policy says manage all-resources in tenancy, fix that first.
  7. Review and remove old statements. Keep policy text in Git and run a diff on every change. Delete statements for retired apps, because a stale grant is still a live grant.

How to check it worked

Test both sides. Log in as a member of each group and try an allowed action and a denied one. Denied calls should fail with an authorization or not found response. Repeat from an instance using its instance principal, not your user credentials.

Read the Audit log. In the Oracle Cloud Console, open Observability and Management, then Audit. Filter by principal, compartment and event name. Confirm that read only users only call read APIs and that admins act inside their compartment.

Walk the policy tree. List every policy up from the compartment to the tenancy root and look for broad statements that leak down. Check dynamic group rules to see which instances qualify. Recheck after every reorg, because moving a resource to a new compartment changes which policies apply.

Mistakes to avoid

Treating compartments as a security boundary. They are not. A policy at the parent still applies to the child. Another mistake is using manage for read only work because it is easier than testing verbs.

Using any-user to make an integration work. That grants every principal in the tenancy, and often more. Use a dynamic group or a dedicated group with a network source condition.

Forgetting that Oracle Cloud policies do not have deny rules. You cannot carve an exception out of a broad grant. You must remove or narrow the grant itself.

Leaving the default administrator group full. Keep the number of tenancy administrators small, and give application teams compartment scoped admin groups instead. If you want an outside read before a customer security review, the Cloud security review from Cloudverg is a fixed price $6,500 engagement that checks identity, exposure, encryption and logging across up to five cloud accounts. It is one option among others.

Frequently asked questions

Does Oracle Cloud IAM support deny policies?

No. OCI policies are allow only. To remove access, delete or narrow the statement that grants it. You cannot add a deny rule to override a broad allow.

Should I use compartments or groups for least privilege?

Use both. Compartments set the resource boundary and groups set who gets access. Policies connect them, and the narrowest useful pair is a job group plus a single app compartment.

How do dynamic groups fit least privilege?

Dynamic groups give workloads an identity without stored keys. Write a matching rule that limits membership by compartment or resource type. Then grant only the services the workload calls.

Fixed price

Want help with this? Cloud security review

$6,500 fixed price

2 to 3 weeks · Starts within 10 business days

A read-only review of identity, network exposure, encryption and logging across your cloud accounts, with a prioritized fix list.

What is included

Related guides

More cloud security guides   Security and compliance

Smallest way to start

Get a senior architect on your problem this week

Ninety minutes on the cloud, AI or security question that is blocking you, a pre-read of your material and a written summary within two business days.

$450 one-time