OCI IAM policies control who can access which resources, how, and under what conditions. All resources have an implicit deny by default — access must be explicitly granted via policy statements. Policies are collections of one or more statements written in a human-readable language.
Allow <subject> to <verb> <resource-type> in <location> [where <condition>]
Every standard policy statement begins with Allow. The where clause is optional.
| Element | Description |
|---|---|
subject |
Who is being granted access (group, dynamic group, etc.) |
verb |
Level of access (inspect, read, use, manage) |
resource-type |
The OCI resource being targeted |
location |
A compartment or the full tenancy |
condition |
Optional filter to further restrict access |
Note: Policy syntax is case-insensitive.
Allow,allow, andALLOWare all valid.
The subject defines who the policy applies to.
# Named group (default identity domain)
Allow group Developers to ...
# Group with spaces in name (use single quotes)
Allow group 'Dev Team' to ...
# Group by OCID
Allow group id ocid1.group.oc1..aaaaaaaaqjihfhvxmumrl3isyrjw3n6c4rzwskaawuc7i5xwe6s7qmnsbc6a to ...
# Multiple groups (comma-separated)
Allow group A-Admins, B-Admins to ...
# Group in a non-default identity domain
Allow group FederatedDomain/Engineers to ...
# Dynamic group (for compute instances / service principals)
Allow dynamic-group MyInstanceGroup to ...
# Dynamic group in a specific identity domain
Allow dynamic-group MyDomain/MyInstanceGroup to ...
# All users in the tenancy (use sparingly)
Allow any-user to ...
# All groups in the tenancy
Allow any-group to ...Tip: Use single quotes around group names that contain spaces.
Verbs are cumulative — each level includes all permissions from the level below it.
| Verb | Access Level | Typical Capabilities |
|---|---|---|
inspect |
Lowest | List resources, get basic metadata |
read |
Low | All of inspect + get full resource details/contents |
use |
Medium | All of read + modify/work with existing resources |
manage |
Highest | All of read + use + create and delete resources |
# Read-only: list and view instances
Allow group Auditors to read instances in tenancy
# Use: work with existing volumes (but not create/delete)
Allow group AppTeam to use volumes in compartment Production
# Full control
Allow group StorageAdmins to manage buckets in tenancyAllow group Developers to manage instances in compartment Dev
Allow group Developers to manage volumes in compartment Dev# instance-family covers: instances, images, volume attachments, console connections
Allow group Developers to manage instance-family in compartment Dev
# virtual-network-family covers: VCNs, subnets, security lists, route tables, etc.
Allow group NetAdmins to manage virtual-network-family in tenancy
# volume-family covers: volumes, volume attachments, volume backups
Allow group StorageOps to manage volume-family in compartment Prod
# object-family covers: buckets and objects
Allow group StorageAdmins to manage object-family in tenancyAllow group ProjectAdmins to manage all-resources in compartment Project-ASpecifies the compartment or tenancy the policy applies to. Policies inherit downward — access granted at a parent compartment applies to all child compartments.
# Entire tenancy
Allow group Admins to manage all-resources in tenancy
# Specific compartment by name
Allow group Developers to manage instance-family in compartment Dev
# Compartment by OCID
Allow group Developers to manage instance-family in compartment id ocid1.compartment.oc1..aaaaaaaaexampleocid
# Nested compartment path (colon separator)
Allow group TeamA to use object-family in compartment Prod:TeamA:StorageNote: IAM resources (users, groups, policies) live in the tenancy (root compartment), so their policies reference
tenancynotcompartment.
Curly braces {} serve two distinct purposes in OCI IAM policy language, and understanding when to use each form is critical to writing correct policies.
Curly braces replace a verb with a named set of specific atomic permissions. Instead of granting all the permissions bundled into inspect, read, use, or manage, you can list exactly which individual permissions are granted.
Permissions are always written in ALL_CAPS_WITH_UNDERSCORES.
Allow <subject> to {PERMISSION_ONE, PERMISSION_TWO, ...} <resource-type> in <location>
# Grant ONLY the ability to inspect and read vault details — not create/delete
Allow any-user to {VAULT_INSPECT, VAULT_READ} vaults in compartment open-vault
# Grant update permission on load balancers without granting full "use" access
Allow group NetOps to {LOAD_BALANCER_UPDATE} load-balancers in compartment Production
# Grant specific secret permissions (without granting all "use" permissions)
Allow group AppGroup to {SECRET_INSPECT, SECRET_READ} secrets in compartment Prod
# Creating a secret also requires permission on the vault itself
Allow group SecretCreators to {SECRET_CREATE} secrets in compartment Prod
Allow group SecretCreators to use vaults in compartment Prod| Approach | Use When |
|---|---|
verb (e.g., use) |
General access for a role — simpler and maintainable |
{PERMISSION_SET} |
Auditor/security requirements demand least-privilege with surgical precision |
Note: Some API operations require multiple permissions, and those permissions may span different resource types. For example,
CreateSecretneedsSECRET_CREATEon secrets andVAULT_CREATE_SECRETon vaults. Always check the service-specific policy reference.
Curly braces are used to group multiple conditions when combined with all or any. This is the where clause equivalent of AND / OR logic.
where all { condition1, condition2, ... } -- ALL must be true (AND)
where any { condition1, condition2, ... } -- ANY must be true (OR)
# AND: both conditions must be true
Allow group Contractors to use instances in compartment Dev
where all {request.region = 'us-ashburn-1', request.utcHours >= 8}
# OR: either condition grants access
Allow dynamic-group AppInstances to read objects in compartment Prod
where any {target.bucket.name = 'logs-bucket', target.bucket.name = 'config-bucket'}
# Nested: AND of (two OR conditions)
Allow any-user to manage network-family in compartment Network
where all {
any {
request.principal.group.tag.Operations.lifecycle = target.resource.tag.Operations.lifecycle,
request.principal.group.tag.Operations.lifecycle = target.resource.compartment.tag.Operations.lifecycle
},
request.user.domain.name = 'Default'
}Dynamic group membership rules (not policy statements) also use this syntax:
# Instance belongs to dynamic group if it is in EITHER of these compartments
Any {
instance.compartment.id = 'ocid1.compartment.oc1..aaaaaaaacompartment1',
instance.compartment.id = 'ocid1.compartment.oc1..aaaaaaaacompartment2'
}
# Instance must be tagged AND in a specific compartment
All {
instance.compartment.id = 'ocid1.compartment.oc1..aaaaaaaaxxx',
tag.Operations.Env.value = 'Production'
}| Context | Syntax | Meaning |
|---|---|---|
| Verb position | to {PERM_A, PERM_B} resource-type |
Grant only these specific atomic permissions |
Condition all |
where all {cond1, cond2} |
ALL conditions must be true (AND) |
Condition any |
where any {cond1, cond2} |
ANY condition must be true (OR) |
| Dynamic group rule | Any {rule1, rule2} |
Membership matches if ANY rule is true |
| Variable | Description | Example Value |
|---|---|---|
request.region |
Region of the API call | 'us-phoenix-1' |
request.ad |
Availability domain | 'US-ASHBURN-AD-1' |
request.networkSource.name |
Named IP allowlist | 'CorpNetwork' |
request.user.id |
OCID of the requesting user | 'ocid1.user.oc1...' |
request.user.domain.name |
Identity domain name | 'Default' |
request.utcHours |
Current UTC hour (0–23) | 9 |
request.utcTimestamp |
Full UTC timestamp | '2025-01-01T09:00:00Z' |
request.principal.type |
Type of principal making the request | 'instance', 'service' |
request.operation |
Specific API operation name | 'GetObject' |
request.permission |
The permission being requested | 'PAR_MANAGE' |
| Variable | Description |
|---|---|
target.compartment.id |
OCID of the target compartment |
target.compartment.name |
Name of the target compartment |
target.group.name |
Name of the target group |
target.bucket.name |
Name of an Object Storage bucket |
target.resource.tag.<namespace>.<key> |
A defined tag on the target resource |
target.domain.name |
Identity domain name of target |
| Operator | Meaning |
|---|---|
= |
Equals (case-sensitive) |
!= |
Not equals |
=~ |
Case-insensitive equals |
in ('a', 'b') |
Matches any value in the list |
/glob*/ |
Wildcard/glob pattern match |
# Restrict to a specific region
Allow group PHX-Admins to manage all-resources in tenancy
where request.region = 'us-phoenix-1'
# Exclude a specific compartment
Allow group NetAdmins to manage virtual-network-family in tenancy
where target.compartment.id != 'ocid1.compartment.oc1..aaaaaaaaexampleocid'
# Wildcard group name match
Allow group GroupAdmins to manage groups in tenancy
where target.group.name = /A-Users-*/
# Multiple AND conditions
Allow group GroupAdmins to manage groups in tenancy
where all {target.group.name = /A-*/, target.group.name != 'A-Admins'}
# Time-based access window (9am–5pm UTC)
Allow group Contractors to use instances in compartment Dev
where all {request.utcHours >= 9, request.utcHours < 17}
# Specific timestamp range
Allow group AuditTeam to read audit-events in tenancy
where all {
request.utcTimestamp > '2025-01-01T00:00:00Z',
request.utcTimestamp < '2025-12-31T23:59:59Z'
}
# IP allowlist via network source
Allow group CorpUsers to manage all-resources in tenancy
where request.networkSource.name = 'CorpNetwork'
# Tag-based access control (ABAC)
Allow group TeamA to manage instances in tenancy
where target.resource.tag.Operations.Project = 'Alpha'
# Restrict to user's own resources (tag must match group tag)
Allow any-user to manage network-family in compartment Network
where request.principal.group.tag.Operations.lifecycle = target.resource.tag.Operations.lifecycle
# Restrict to a specific OCI service making the call
Allow any-user to read instances in tenancy
where request.principal.type = 'vnpa-service'
# Restrict a policy to only apply to one specific user within a group
Allow group groupA to manage compartments in tenancy
where request.user.id = 'ocid1.user.oc1..aaaaaaxxx'Cross-tenancy policies use three special statement keywords instead of Allow. Both tenancies must define matching policies — one side alone grants nothing.
| Keyword | Where it lives | Purpose |
|---|---|---|
Endorse |
Source tenancy | Declares what your group can do in other tenancies |
Admit |
Destination tenancy | Grants access to an external group from another tenancy |
Define |
Either tenancy | Creates a local alias for an OCID (for readability) |
Source tenancy (the group trying to access another tenancy's resources):
Define tenancy DestinationTenancy as ocid1.tenancy.oc1..<unique_ID>
Endorse group StorageAdmins to manage object-family in tenancy DestinationTenancyDestination tenancy (the tenancy granting access):
Define tenancy SourceTenancy as ocid1.tenancy.oc1..<unique_ID>
Define group StorageAdmins as ocid1.group.oc1..<unique_ID>
Admit group StorageAdmins of tenancy SourceTenancy to manage object-family in tenancySource tenancy:
Define tenancy DestCompanyABC as ocid1.tenancy.oc1..aaaaaaaaabc
Endorse dynamic-group oci_la_dg to manage loganalytics-resources-family in tenancy DestCompanyABC
Endorse dynamic-group oci_la_dg to read compartments in tenancy DestCompanyABCDestination tenancy:
Define tenancy VendorA as ocid1.tenancy.oc1..aaaaavendora
Define dynamic-group oci_la_dg as ocid1.dynamicgroup.oc1..aaaaaaaavendora
Admit dynamic-group oci_la_dg of tenancy VendorA to manage loganalytics-resources-family in tenancy
Admit dynamic-group oci_la_dg of tenancy VendorA to read compartments in tenancy# Source tenancy: allow StorageAdmins to manage objects in ANY tenancy
Endorse group StorageAdmins to manage object-family in any-tenancyDefine tenancy SourceTenancy as ocid1.tenancy.oc1..<unique_ID>
Define group StorageAdmins as ocid1.group.oc1..<unique_ID>
Admit group StorageAdmins of tenancy SourceTenancy to manage object-family in compartment SharedBucketsNote: Cross-tenancy policies must be attached at the root (tenancy) level on both sides. Both tenancies must also be subscribed to the same regions.
Use single quotes around any name containing spaces.
Allow group 'Dev Team', 'Ops Team' to use instances in compartment ProductionUse : as a path separator to traverse the hierarchy.
# Policy attached to tenancy, targeting a deeply nested compartment
Allow group TeamA to manage instances in compartment Root:Project-A:SubTeamThere is no multi-value syntax for location — write one statement per compartment.
Allow group Developers to manage instance-family in compartment Project-A
Allow group Developers to manage instance-family in compartment Project-BYou can replace any name with id <ocid> for robustness against renames.
Allow group id ocid1.group.oc1..aaaaaaaagroupocid to manage instance-family
in compartment id ocid1.compartment.oc1..aaaaaaaacompartmentocidany-user— covers all users, resource principals, instance principals, and service principals in the tenancy. Use with caution.any-group— covers all users and instance principals, but not service principals.
# Prefer any-group over any-user for least privilege
Allow any-group to inspect all-resources in tenancy
# Carve out a specific service using request.principal.type to safely use any-user
Allow any-user to read instances in tenancy
where request.principal.type = 'vnpa-service'OCI services can be authorized to act on resources. This is done using any-user with a condition that scopes the principal to the specific service type.
# Authorize the Virtual Network Path Analyzer to read instances
Allow any-user to read instances in tenancy
where request.principal.type = 'vnpa-service'
# Authorize a Data Integration workspace (disworkspace) to access objects
Allow any-user to manage objects in compartment XYZData
where all {request.principal.type = 'disworkspace'}When groups exist in a non-default identity domain, prefix the group with the domain name.
# Group in a named domain
Allow group FederatedDomain/Engineers to manage instances in compartment Dev
# Group in a domain with spaces
Allow group 'My Domain'/'Dev Group' to use buckets in compartment Staging
# Works with Endorse too
Endorse group domainA/xt_db_users to use database-connections in tenancy DestinationTenancyThis is a powerful ABAC (Attribute-Based Access Control) pattern — access is determined by comparing a tag on the requesting group against a tag on the target resource or compartment.
# Users can only manage resources that share their group's lifecycle tag
Allow any-user to manage network-family in compartment Network
where request.principal.group.tag.Operations.lifecycle = target.resource.tag.Operations.lifecycleUse UTC timestamps in ISO 8601 format. Allow for a ~5 minute clock skew.
# Allow access only during business hours (UTC)
Allow group Contractors to use instances in compartment Dev
where all {request.utcHours >= 9, request.utcHours < 17}
# Allow access within a specific date range
Allow group AuditTeam to read audit-events in tenancy
where all {
request.utcTimestamp >= '2025-06-01T00:00:00Z',
request.utcTimestamp <= '2025-06-30T23:59:59Z'
}You can combine permission sets and conditions in the same statement.
# Allow vault inspection only to users from a specific group tag
Allow any-user to {VAULT_INSPECT, VAULT_READ, VAULT_CREATE_SECRET} in compartment open-vault
where request.principal.group.tag.users_ts.user_role = 'admin-users'A policy attached to compartmentA but with in compartment compartmentB only applies to compartmentB. The attachment determines who can modify the policy, not where it applies.
For network resources, inspect returns not just metadata but the full contents of security lists, route tables, and VCN configurations — not just names and OCIDs. For policies, inspect returns the full text of all policy statements.
When using manage with a condition that targets a named resource (like target.group.name), list operations don't carry the target value, so the condition always evaluates as "not applicable" and denies the list. You must add a separate inspect statement without the condition.
# Without this, GroupAdmins can't list groups to find "A-Users-*" ones
Allow group GroupAdmins to manage groups in tenancy
where target.group.name = /A-Users-*/
Allow group GroupAdmins to inspect groups in tenancy -- Required!Allow group ProjectA-Admins to manage all-resources in compartment Project-AAllow group Auditors to inspect all-resources in tenancy
Allow group Auditors to read instances in tenancy
Allow group Auditors to read audit-events in tenancyAllow group HelpDesk to manage users in tenancy
Allow group HelpDesk to manage groups in tenancyAllow group NetAdmins to manage virtual-network-family in tenancyAllow group StorageAdmins to manage buckets in tenancy
Allow group StorageAdmins to manage objects in tenancyAllow group Developers to manage instance-family in compartment Dev
Allow group Developers to use volume-family in compartment Dev
Allow group Developers to use virtual-network-family in compartment DevAllow dynamic-group AppServers to read secret-family in compartment ProductionAllow group LogShippers to inspect buckets in compartment Logging
Allow group LogShippers to manage objects in compartment Logging
where all {
target.bucket.name = 'app-logs',
any {request.permission = 'OBJECT_CREATE', request.permission = 'OBJECT_INSPECT'}
}- Policies always start with
Allow(orEndorse/Admit/Definefor cross-tenancy). There is no explicitDeny. - Implicit deny: if no policy grants access, access is denied.
- A policy can only be attached to one compartment. Attachment determines who can edit/delete the policy.
- Changes take effect within ~10 seconds in the home region, but can take several minutes to replicate across all regions.
- The built-in Administrators group policy cannot be changed or deleted.
- Users can always change their own password and API signing keys without any policy.
- When referencing IAM resources (users, groups, policies), use
tenancyas the location. - Policy names must be unique within a compartment and are immutable after creation.
- Deleting and recreating a policy with the same name produces a different OCID — they are treated as different policies.
- Policies attached to a parent compartment apply to all child compartments via inheritance. There is no way to block inheritance.
any-userincludes service and resource principals — preferany-groupor scope withrequest.principal.typeconditions.