Imagine your school has a big library with thousands of books, computers, and a printer room. 📚
Not everyone is allowed everywhere! Students can only borrow books. Teachers can also use the printer room. Only the librarian can add or remove books from the shelves.
That's exactly how OCI Policies work! They are the rules that decide who can do what inside your Oracle Cloud account.
What is an OCI Policy?
A Policy is a simple written rule that tells Oracle Cloud: "This person (or group) is allowed to do THIS with THAT resource."
Every OCI policy follows this exact pattern:
Allow <who> to <what action> <which resource> in <where>
That's it! Four parts. Let's break each one down: 🎯
- who → A user, a group, or a special service (e.g.
group Developers) - what action → What they're allowed to do (e.g.
read,manage,use) - which resource → What kind of thing they can touch (e.g.
instances,buckets) - where → Which compartment (folder) in your cloud (e.g.
tenancy,compartment Dev)
💡 Think of it like: A school permission slip! "Alice is allowed to borrow books from the Science section in Room 3." Same structure — who, what, which thing, where! 📝
The 4 Verb Levels — How Much Power to Give?
The "what action" part of a policy uses special verbs. Each verb gives a different level of power — from almost nothing to full control!
Verb What it means Example
─────────────────────────────────────────────────────────────────────
inspect → Can only LIST resources (see names) → "I see 3 buckets exist"
read → Can LIST + READ contents → "I can open and read files"
use → Can LIST + READ + do limited actions → "I can start/stop a server"
manage → Full power — create, edit, delete, all! → "I can do anything"
💡 Think of it like library access cards:
inspect→ You can see the book titles on the shelf (but can't open them) 👀read→ You can open and read books (but can't take them home) 📖use→ You can borrow books and use the reading room 📚manage→ You're the librarian — you can add, remove, rearrange everything! 🔑
Where Do Policies Live? — Compartments Explained
Before we write policies, we need to understand Compartments. Think of your Oracle Cloud account like a big office building. 🏢
- The whole building = your Tenancy (your entire OCI account)
- Each floor = a Compartment (a logical folder for your resources)
- Rooms on each floor = your actual resources (servers, databases, etc.)
Policies can be placed at the tenancy level (applies to the whole building) or at a compartment level (applies to just one floor). 🏗️
💡 Real example: You might have compartments called Production, Development, and Testing. Developers get full access to Development but only read access to Production — keeping live systems safe! ✅
How a Policy Is Evaluated in Real Time 🕐
When someone tries to do something in OCI — like starting a server — Oracle checks policies instantly. Here's exactly what happens behind the scenes:
Developer clicks "Start Instance" in OCI Console
|
▼
OCI asks: "Who is this person?"
|
▼
OCI finds their Groups (e.g. group "Developers")
|
▼
OCI scans ALL policies for a matching rule
e.g. "Allow group Developers to use instances in compartment Dev"
|
┌────┴────┐
▼ ▼
Match found? No match found?
| |
▼ ▼
✅ ALLOWED ❌ DENIED
(Action runs) ("Authorization failed" error)
This whole check happens in milliseconds — every single time someone takes an action! There is no caching of old decisions. Every click = a fresh policy check. ⚡
Key things to know about how evaluation works:
- OCI uses a deny-by-default model — if no policy says yes, the answer is always NO ❌
- Policies are additive — multiple matching policies all contribute their permissions
- There is no "Deny" statement in OCI — you control access by simply not writing an Allow rule
- Policies apply to Groups, not individual users directly (users must be in a group!)
💡 Think of it like: A bouncer at a club. Every time you try to enter (every action), the bouncer checks your ID against the guest list. Not on the list? You're not getting in — even if you were let in yesterday! 🚪
Writing Your First OCI Policy — Step by Step
Let's write real policies together, starting from the simplest and building up! 👇
Example 1: Let a Group Read Object Storage
Scenario: Your team DataAnalysts needs to read files from storage buckets. Nothing else.
Allow group DataAnalysts to read buckets in compartment DataLake
Allow group DataAnalysts to read objects in compartment DataLake
What this does:
- Line 1 → DataAnalysts can see the list of buckets and their settings
- Line 2 → DataAnalysts can open buckets and read the files inside
- They cannot upload, delete, or create anything — read only! 🔒
Example 2: Let Developers Manage Compute in One Compartment
Scenario: Developers need full control of servers — but only in the Dev compartment.
Allow group Developers to manage instances in compartment Dev
Allow group Developers to manage instance-family in compartment Dev
Allow group Developers to use virtual-network-family in compartment Dev
What this does:
- Line 1 → Developers can create, start, stop, delete instances in Dev
- Line 2 → Also covers instance-related resources (configs, console connections)
- Line 3 → Lets them use the network — needed to actually launch instances
- They have zero access to the Production compartment! 🛡️
Example 3: Admin Gets Full Tenancy Access
Scenario: Your cloud admin needs to manage everything everywhere.
Allow group Administrators to manage all-resources in tenancy
What this does:
- One single line gives the
Administratorsgroup complete control all-resources= every single resource type in OCIin tenancy= across the entire cloud account, all compartments- ⚠️ Only give this to people you fully trust! It's the master key 🗝️
How to Create a Policy in OCI Console — Step by Step
Let's actually create a policy in Oracle Cloud right now! Follow these steps: 👇
Step 1: Open the Policies Section
- Log in at cloud.oracle.com
- Click the ☰ menu (top left)
- Go to: Identity & Security → Policies
Step 2: Click "Create Policy"
- Click the blue "Create Policy" button
- Give it a meaningful name like
developer-access-policy - Add a description:
Allows Developers group to manage resources in Dev compartment - Choose which compartment this policy will live in
Step 3: Write Your Policy Statements
- Toggle on "Show manual editor" (much easier than the wizard!)
- Type your policy rules one per line
- Click "Create"
- ✅ Your policy is now live — instantly!
🎉 That's it! No restart needed. Policies take effect the moment you save them.
How to Assign a Policy to a User — The Right Way
Here's something very important that confuses many beginners! In OCI, you never assign policies directly to a user.
Instead, the correct flow is:
WRONG WAY ❌ CORRECT WAY ✅
────────────────────── ──────────────────────────────
User → Policy User → Group → Policy
|
Step 1: Create a Group
|
Step 2: Add the User to the Group
|
Step 3: Write a Policy for the Group
💡 Think of it like: A company badge system. You don't give each employee custom keys. Instead, you put them in a team (group) and give the whole team access to certain rooms (policy). Much easier to manage! 🏢
Step-by-Step: Add a User to a Group
Step 1: Create a Group
- Go to: Identity & Security → Groups
- Click "Create Group"
- Name it something clear like
DevelopersorDataAnalysts - Click "Create"
Step 2: Add a User to the Group
- Open your newly created group
- Click "Add User to Group"
- Search for the user by name or email
- Click "Add"
- ✅ The user is now part of the group — and inherits all its policies!
Step 3: Write the Policy for That Group
- Go to: Identity & Security → Policies
- Create a new policy with your rules referencing
group Developers - Done! The user immediately gets the permissions from that policy ✅
The moment you add a user to a group, all that group's policies apply to them — instantly! 🚀
Managing Policies with OCI CLI
You can also create and manage policies from your terminal using the OCI CLI. This is much faster once you get comfortable with it!
List All Policies in a Compartment
📌 What the command below does: It prints a list of all the policies that exist in your chosen compartment — their names, descriptions, and the actual rule statements inside them. Like asking "what are all the rules for this floor of our building?" 📋
# Replace YOUR_COMPARTMENT_ID with your compartment OCID
oci iam policy list \
--compartment-id YOUR_COMPARTMENT_ID \
--output table
Output:
+------------------------------+------------+----------------------------------------+
| name | state | description |
+------------------------------+------------+----------------------------------------+
| developer-access-policy | ACTIVE | Developers access to Dev compartment |
| readonly-analysts-policy | ACTIVE | DataAnalysts read access to DataLake |
| admin-tenancy-policy | ACTIVE | Full admin access across tenancy |
+------------------------------+------------+----------------------------------------+
All your policies listed clearly! 🎯
Create a New Policy via CLI
📌 What the command below does: It creates a brand new OCI policy from your terminal — no clicking in the console needed! You give it a name, description, and the actual rule statements. Oracle activates it immediately. Like emailing a new rule to the building security team — it's enforced right away! 📨
oci iam policy create \
--compartment-id YOUR_COMPARTMENT_ID \
--name "developer-access-policy" \
--description "Allows Developers group to manage compute in Dev compartment" \
--statements '["Allow group Developers to manage instances in compartment Dev",
"Allow group Developers to use virtual-network-family in compartment Dev"]'
Output:
{
"data": {
"name" : "developer-access-policy",
"lifecycle-state" : "ACTIVE",
"statements" : [
"Allow group Developers to manage instances in compartment Dev",
"Allow group Developers to use virtual-network-family in compartment Dev"
]
}
}
Policy is live! ✅ Developers can now manage instances in Dev — nothing else!
How to Protect Resources via Policies 🛡️
Policies aren't just about giving access — they're your primary tool for protecting resources too! Here are the most important protection patterns used:
Pattern 1: Protect Production from Developers
Developers should never be able to touch Production servers accidentally. The protection is simple — just don't write a policy that allows it!
# Developers get full access to Dev compartment only
Allow group Developers to manage all-resources in compartment Dev
# No policy for Production = Developers are blocked from it automatically ✅
# OCI's deny-by-default takes care of it — no extra rule needed!
💡 Think of it like: A hotel key card. Your card opens Room 305. It automatically doesn't open Room 405 — you don't need a separate "block Room 405" rule. Not programmed in = no access! 🗝️
Pattern 2: Read-Only Access for Auditors
Auditors need to see everything but must never change anything.
# Auditors can inspect (see names) and read all resources across the whole tenancy
Allow group Auditors to inspect all-resources in tenancy
Allow group Auditors to read all-resources in tenancy
# They CANNOT use, manage, create, or delete anything — read-only! 🔒
Pattern 3: Lock Down Sensitive Data with Conditions
OCI supports Conditions in policies — extra rules that must also be true. This is powerful for fine-grained protection!
# Only allow access if the request comes from a specific IP range (your office network)
Allow group Developers to manage instances in compartment Dev
where request.networkSource.name = 'office-network'
# Only allow a group to read objects in a specific bucket — not all buckets!
Allow group DataAnalysts to read objects in compartment DataLake
where target.bucket.name = 'approved-data-bucket'
How conditions work:
- The
whereclause adds an extra check on top of the basic allow - Both the main rule AND the condition must be true for access to be granted
- If the condition fails (e.g. wrong IP, wrong bucket) → access is denied ❌
Pattern 4: Protect Critical Resources with Dynamic Groups
Sometimes you want your OCI resources (like an instance) to access other OCI resources (like a storage bucket). For this, you use a Dynamic Group — a special group for resources, not people!
# Step 1: Create a Dynamic Group that matches your compute instances
# (In OCI Console → Identity → Dynamic Groups → Create)
# Matching Rule:
All {instance.compartment.id = 'ocid1.compartment.oc1..xxxxx'}
# Step 2: Write a policy allowing that Dynamic Group to access storage
Allow dynamic-group my-compute-instances to read objects in compartment DataLake
What this achieves:
- Your OCI servers can read files from storage — without storing any passwords in code! 🔐
- The server's identity is verified by OCI automatically — much safer than API keys
- This is the recommended pattern for secure service-to-service access
💡 Think of it like: A company car has a special badge on the windshield. When it enters the car park, the barrier automatically opens — no human needed, the car itself is recognized! 🚗
Real-World Policy Setup — A Complete Example 🏢
Let's put it all together! Here's a complete, realistic policy setup for a small company with 3 teams — exactly like you'd do it..
The company has 3 compartments: Production, Development, DataLake
# ── ADMINISTRATORS ──────────────────────────────────────────
# Full control over everything
Allow group Administrators to manage all-resources in tenancy
# ── DEVELOPERS ──────────────────────────────────────────────
# Full access to Dev compartment, read-only on Production
Allow group Developers to manage all-resources in compartment Development
Allow group Developers to read all-resources in compartment Production
# ── DATA ANALYSTS ───────────────────────────────────────────
# Read-only access to the DataLake, nothing else
Allow group DataAnalysts to read buckets in compartment DataLake
Allow group DataAnalysts to read objects in compartment DataLake
# ── AUDITORS ────────────────────────────────────────────────
# Read-only view across the entire account (for compliance)
Allow group Auditors to inspect all-resources in tenancy
Allow group Auditors to read all-resources in tenancy
# ── AI COMPUTE INSTANCES (Dynamic Group) ────────────────────
# Servers in Production can read AI models from DataLake
Allow dynamic-group production-servers to read objects in compartment DataLake
where target.bucket.name = 'ai-models-bucket'
Each team has exactly the access they need — nothing more, nothing less. That's least-privilege access — the golden rule of cloud security! 🏆
Common Policy Mistakes to Avoid
Here are the mistakes beginners make all the time — and how to avoid them:
Mistake 1: Writing Policies for Users Instead of Groups
# ❌ Wrong — OCI doesn't support policies on individual users like this
Allow user john.doe@company.com to manage instances in compartment Dev
# ✅ Correct — always use groups!
Allow group Developers to manage instances in compartment Dev
Mistake 2: Forgetting Network Policies When Creating Instances
# ❌ Incomplete — instance policy alone isn't enough to launch a server
Allow group Developers to manage instances in compartment Dev
# ✅ Complete — also need network access to actually launch!
Allow group Developers to manage instances in compartment Dev
Allow group Developers to use virtual-network-family in compartment Dev
Allow group Developers to use subnets in compartment Dev
Mistake 3: Using "manage all-resources in tenancy" Too Freely
# ❌ Dangerous — giving full admin power to the wrong group!
Allow group Developers to manage all-resources in tenancy
# ✅ Safer — scope it to just the compartment they need
Allow group Developers to manage all-resources in compartment Development
Always follow the rule: give the minimum access needed to do the job. Nothing more! 🔒
Do's and Don'ts ✅❌
- Always assign policies to Groups, never to individual users directly
- Use the least-privilege principle — give only the minimum access needed
- Use compartments to separate environments (Dev, Staging, Production)
- Use Dynamic Groups for service-to-service access instead of API keys
- Add conditions (IP ranges, bucket names) for extra protection on sensitive resources
- Give Auditors
inspect+readonly — neveruseormanage
- Don't give
manage all-resources in tenancyto any group except true admins - Don't forget that OCI is deny-by-default — if there's no Allow rule, access is blocked
- Don't write policies for individual users — always use groups
- Don't put all resources in one compartment — use separate compartments per environment
- Don't store API keys in code to allow service access — use Dynamic Groups instead
- Policy format is always:
Allow <who> to <verb> <resource> in <location> - Verbs in order of power:
inspect<read<use<manage - Policies take effect instantly — no restart or wait time needed
- No "Deny" keyword exists in OCI — you protect by simply not writing an Allow
- Dynamic Groups let OCI resources (servers) access other OCI resources securely
- Adding a user to a group instantly gives them all that group's policy permissions
Quick Summary 📝
What we learned :
- Policy → A written rule:
Allow <group> to <verb> <resource> in <compartment> - Verbs →
inspect(see) →read(open) →use(do limited things) →manage(full power) - Deny-by-default → No matching policy = access denied. Always! ❌
- Compartments → Logical folders to scope and isolate your resources
- Groups → You assign policies to groups, then add users to those groups
- Conditions → Add
whereclauses for extra checks (IP range, bucket name, etc.) - Dynamic Groups → Let OCI resources (servers) access other resources without passwords
- Least privilege → Always give the minimum access needed. Nothing more! 🔒
Comments
Post a Comment