OCI Governance Policies Should Not Grant Unrestricted
More Info:
Flag any IAM policy statement that grants broad verbs (manage/use) across all-resources to unconstrained groups. Wildcard administrative grants are the most critical vulnerability in identity perimeters.
Risk Level
Critical
Address
Compliance, Security
Compliance Standards
- APRA CPS 234 (Australia)
- BSI C5 (Germany)
- Brazil LGPD
- CCPA / CPRA (California)
- CIS Critical Security Controls v8
- CMMC 2.0
- CSA Cloud Controls Matrix v4
- Cloudanix Best Practice
- DPDPA
- Digital Operational Resilience Act (EU)
- Essential 8
- ISO/IEC 27017
- ISO/IEC 27018
- ISO/IEC 27701
- KSA PDPL
- MAS Technology Risk Management (Singapore)
- MITRE ATT&CK (Cloud)
- NIS2 Directive
- NIST SP 800-171
- NYDFS 23 NYCRR 500
- SWIFT Customer Security Controls Framework
- Sarbanes-Oxley IT General Controls
- UK NCSC Cyber Assessment Framework
Triage and Remediation
- Remediation
Remediation
Using Console
Below are concise, console-focused steps to remediate the issue “OCI Governance Policies Should Not Grant Unrestricted Resource Access” for OCI Governance Monitoring, by tightening IAM policies to least privilege.
1. Identify the Problem Policies
- Sign in to the OCI Console.
- Open the navigation menu → Identity & Security → Policies.
- Ensure you are in the root compartment (or the compartment where your Governance policies are defined).
- Look for policies related to:
governance-monitoringgovernance-rule-family- or any policy used by your Governance Monitoring dynamic group or user group.
- Open each candidate policy and look for overly broad statements, such as:
Allow group <name> to manage all-resources in tenancyAllow dynamic-group <name> to manage all-resources in compartment <name>- or use of
managewithall-resourcesorinspect/useall-resourcesacross the tenancy.
These are the ones that need to be remediated.
2. Determine the Minimum Required Access
Verify what the Governance Monitoring service actually needs. In most environments, it only requires permissions to:
- Read configuration / resources to evaluate governance rules.
- Write/read its own governance rule configurations and evaluation results.
Common resource-types involved:
governance-rule-family- Possibly
instance-family,object-family,vcn-family,tag-namespaces(for read/inspect only), depending on what the rules evaluate.
Your goal: restrict “manage all-resources” to only the specific resource-families and only with the minimal verb (inspect/use/read/manage) required.
3. Edit the Policy to Remove Unrestricted Access
For each over-permissive policy:
- From the Policies page, click the policy name.
- Click Edit Policy Statements.
- In the existing statements:
- Remove or rewrite lines that include:
all-resourcesin tenancywhen not needed (use specific compartments instead)managewhen lesser verbs likeinspect/read/usesuffice.
- Remove or rewrite lines that include:
Example: Bad Policy
Allow dynamic-group governance-monitoring-dg to manage all-resources in tenancy
Example: More Restrictive Replacement
Adjust based on what you actually need. A typical least-privilege pattern might look like:
Allow dynamic-group governance-monitoring-dg to inspect all-resources in tenancy
Allow dynamic-group governance-monitoring-dg to use governance-rule-family in tenancy
Or, further compartment scoped:
Allow dynamic-group governance-monitoring-dg to inspect all-resources in compartment <governance-compartment>
Allow dynamic-group governance-monitoring-dg to use governance-rule-family in compartment <governance-compartment>
Key principles:
- Replace
manage all-resourceswith:inspect all-resourceswhere only read/visibility is needed, or- Resource-specific access (e.g.,
use governance-rule-family) where write is needed.
- Scope from
in tenancydown to the specific compartment(s) where Governance rules and targets are defined, if possible.
- After editing, click Save Changes.
4. Validate Governance Monitoring Still Works
- Go to Governance & Administration (or Security depending on tenant layout) → Governance Rules / Governance Monitoring.
- Run:
- A manual evaluation or
- Confirm scheduled evaluations run successfully and generate results.
- If evaluation fails with a permission error, revisit the policy and:
- Add narrowly scoped
inspectorusepermissions only for the exact resource-type mentioned in the error. - Avoid reverting back to
manage all-resources.
- Add narrowly scoped
5. Clean Up Any Redundant or Legacy Policies
- In Identity & Security → Policies, review for older, unused, or overlapping policies that still grant:
manage all-resources- Very broad
inspect all-resources in tenancynot needed by Governance.
- If confirmed unused:
- Either delete the policy or
- Comment out/replace the broad statements with more specific ones.
If you share a current policy statement you’re using for Governance Monitoring, I can rewrite it to a least-privilege version you can paste directly into the console.
Using CLI
Below is a practical, CLI‑only approach to identify and remediate overly permissive OCI IAM policies that violate “Governance Policies Should Not Grant Unrestricted Resource Access” (e.g., those used for Governance Monitoring / Cloud Guard or custom governance tooling).
1. Identify Overly Permissive Policies
Typical “unrestricted” patterns you want to flag:
allow group <name> to manage all-resources in tenancyallow group <name> to inspect all-resources in tenancyallow group <name> to read all-resources in tenancy- Any
in tenancywith very broad verbs (manage) and wildcards.
1.1 List Policies in Your Tenancy
TENANCY_OCID="<your_tenancy_ocid>"
oci iam policy list \
--compartment-id "$TENANCY_OCID" \
--all \
--output table \
--query "data[].{Name:\"name\", OCID:\"id\", Description:\"description\"}"
If you know the compartment where governance/monitoring policies live, replace TENANCY_OCID with that compartment OCID.
1.2 Inspect Each Policy’s Statements
For a specific policy:
POLICY_OCID="<policy_ocid>"
oci iam policy get \
--policy-id "$POLICY_OCID" \
--query "data.{Name:name,Description:description,Statements:statements}" \
--output json
Look for statements that:
- Use
all-resources - Use
in tenancyinstead of a compartment - Grant
manageat too broad a scope
Example of a problematic statement:
Allow group governance-monitors to inspect all-resources in tenancy
2. Decide the Correct Scope and Permissions
Before changing anything, decide:
-
Which group truly needs what:
e.g.,governance-monitors. -
What access level is actually required for governance monitoring:
Commonly:inspectorreadon specific services (e.g.,audit-events-family,instances,volumes,buckets).- Rarely
manage, and only for specific resource types if automation is needed.
-
Where (tenancy vs compartment):
Prefer compartment scoping (in compartment <compartment_name>or using compartment OCIDs) unless full‑tenancy visibility is absolutely necessary.
Example: For read‑only governance monitoring that just needs to see resources, you might use something like:
Allow group governance-monitors to inspect instances in tenancy
Allow group governance-monitors to inspect volumes in tenancy
Allow group governance-monitors to inspect buckets in tenancy
Allow group governance-monitors to inspect audit-events-family in tenancy
Still tenancy‑wide, but resource-specific, not all-resources.
If you can limit to a compartment:
Allow group governance-monitors to inspect all-resources in compartment <compartment-name>
3. Update the Policy via OCI CLI
You cannot partially edit a single statement; you replace the entire statement list.
3.1 Save the Existing Policy (Backup)
POLICY_OCID="<policy_ocid>"
oci iam policy get \
--policy-id "$POLICY_OCID" \
--query "data" \
--output json > policy-backup.json
This gives you name, description, statements, etc., in case you need to revert.
3.2 Prepare a New Statements File
Create a JSON file containing the new, least‑privilege list of statements, for example new-statements.json:
{
"statements": [
"Allow group governance-monitors to inspect instances in tenancy",
"Allow group governance-monitors to inspect volumes in tenancy",
"Allow group governance-monitors to inspect buckets in tenancy",
"Allow group governance-monitors to inspect audit-events-family in tenancy"
]
}
Or, if you can scope to a compartment (preferred):
{
"statements": [
"Allow group governance-monitors to inspect all-resources in compartment my-governance-compartment"
]
}
You can build this file from the backup, removing/replacing the problematic lines.
3.3 Apply the New Statements to the Policy
Extract the array from the JSON file and provide it to oci iam policy update:
NEW_STATEMENTS=$(jq -r '.statements' new-statements.json)
oci iam policy update \
--policy-id "$POLICY_OCID" \
--statements "$NEW_STATEMENTS" \
--force
If you also want to adjust the description to reflect that it’s restricted:
oci iam policy update \
--policy-id "$POLICY_OCID" \
--description "Governance monitoring policy with least-privilege access (no unrestricted all-resources)" \
--statements "$NEW_STATEMENTS" \
--force
Note:
jqis used here to pass a proper JSON array to--statements. Ensurejqis installed, or manually inline the array string.
4. Verify the Remediation
4.1 Confirm the New Statements
oci iam policy get \
--policy-id "$POLICY_OCID" \
--query "data.statements" \
--output json
Verify that:
- No statement uses
all-resources in tenancy(unless contractually required and justified). - No statement uses overly broad
managewhere onlyinspect/readis needed.
4.2 Validate Governance Monitoring Still Works
- Trigger or run your governance monitoring / Cloud Guard / custom governance jobs.
- Check for any failures or missing visibility. If something fails, grant only the additional minimal actions required (e.g., add a specific
inspect <service-family>statement) and repeat.
5. Optional: Automate Detection of Unrestricted Policies
If you want to programmatically detect problematic policies with CLI + jq:
oci iam policy list \
--compartment-id "$TENANCY_OCID" \
--all \
--output json \
| jq '.data[] | select(.statements[] | test("all-resources in tenancy"; "i")) | {name, id, statements}'
This shows policies where any statement contains all-resources in tenancy.
You can similarly search for manage all-resources or other patterns.
If you can share an example of the exact problematic policy statement you’re seeing for “OCI Governance Monitoring,” I can give you a minimal, concrete replacement statement set tailored to that use case.
Using Python
Below is a concise approach to detect and then remediate overly permissive OCI policies (granting unrestricted resource access) using Python and the OCI SDK, suitable for use in a “Governance Monitoring” style workflow.
1. What “Unrestricted Resource Access” Typically Looks Like
In OCI policy language, these are examples of overly broad statements:
Allow group <name> to manage all-resources in tenancyAllow group <name> to inspect all-resources in tenancyAllow group <name> to use all-resources in tenancy- Same patterns but
in compartment <compartment-name>when the scope should be more granular.
Your goal: detect these and then replace them with more restrictive, service- or resource-specific statements.
2. Prerequisites
- Install SDK:
pip install oci
- Configure
~/.oci/configwith:[DEFAULT]user=ocid1.user.oc1..xxxxfingerprint=xx:xx:xx:xxkey_file=/path/to/oci_api_key.pemtenancy=ocid1.tenancy.oc1..xxxxregion=us-ashburn-1
3. Python: Detect Policies With Unrestricted Resource Access
This script:
- Lists all compartments
- Lists all IAM policies
- Flags statements with
all-resourcesorin tenancypatterns
import oci
import re
config = oci.config.from_file()
identity = oci.identity.IdentityClient(config)
tenancy_id = config["tenancy"]
# Regex patterns for "unrestricted" policies
ALL_RESOURCES_PATTERN = re.compile(r"\ball-resources\b", re.IGNORECASE)
TENANCY_SCOPE_PATTERN = re.compile(r"\bin tenancy\b", re.IGNORECASE)
def list_all_compartments(tenancy_id):
compartments = []
response = oci.pagination.list_call_get_all_results(
identity.list_compartments,
tenancy_id,
compartment_id_in_subtree=True
)
compartments.extend(response.data)
return compartments
def list_policies_for_compartment(compartment_id):
return oci.pagination.list_call_get_all_results(
identity.list_policies,
compartment_id
).data
def is_unrestricted_statement(statement: str) -> bool:
# Customize here to tighten rules if needed
if ALL_RESOURCES_PATTERN.search(statement) and TENANCY_SCOPE_PATTERN.search(statement):
return True
# Optionally also flag "manage all-resources in compartment"
if "manage all-resources" in statement.lower():
return True
return False
def main():
print("Scanning for overly permissive OCI policies...")
compartments = list_all_compartments(tenancy_id)
# Include root tenancy as a "compartment"
compartments.append(identity.get_tenancy(tenancy_id).data)
findings = []
for cmp in compartments:
cmp_id = cmp.id
cmp_name = getattr(cmp, "name", tenancy_id)
policies = list_policies_for_compartment(cmp_id)
for policy in policies:
for stmt in policy.statements:
if is_unrestricted_statement(stmt):
findings.append({
"compartment_id": cmp_id,
"compartment_name": cmp_name,
"policy_id": policy.id,
"policy_name": policy.name,
"statement": stmt
})
if not findings:
print("No unrestricted policies found.")
return
print("\nUnrestricted policy statements found:")
for f in findings:
print(f"Compartment: {f['compartment_name']} ({f['compartment_id']})")
print(f" Policy: {f['policy_name']} ({f['policy_id']})")
print(f" Statement: {f['statement']}")
print("-" * 80)
if __name__ == "__main__":
main()
Use this for continuous Governance Monitoring (run as a scheduled job, send results to a log/Lambda/function, etc.).
4. Remediation Strategy (Conceptual)
You should not blindly auto-edit policies; you must understand what each group actually needs. General pattern:
- Replace:
Allow group devs to manage all-resources in tenancy
- With more specific:
Allow group devs to manage instances in compartment dev-compartmentAllow group devs to use virtual-network-family in compartment dev-compartmentAllow group devs to use volume-family in compartment dev-compartment
Basic steps:
-
For each flagged statement:
- Identify the
groupordynamic-group. - Identify what services/resources they truly require.
- Draft new statements that:
- Replace
all-resourceswith specific verbs and resource-types (e.g.instances,volume-family,virtual-network-family). - Replace
in tenancywith appropriatein compartment <name>.
- Replace
- Identify the
-
Update the policy using the OCI SDK.
5. Python: Example of Updating a Policy
Below is a template that:
- Reads an existing policy
- Rewrites statements using a mapping you control
- Updates the policy
You must define rewrite_statement to encode your organization’s rules.
import oci
config = oci.config.from_file()
identity = oci.identity.IdentityClient(config)
def rewrite_statement(original_stmt: str) -> str | None:
"""
Custom logic to rewrite broad statements.
Return:
- new statement string if you want to replace it
- None if you want to remove the statement
- original_stmt if you want to keep it
"""
stmt_lower = original_stmt.lower()
# Example 1: devs have too-broad tenancy-level access
if "allow group devs to manage all-resources in tenancy" in stmt_lower:
# Replace with restricted dev access
return (
"Allow group devs to manage instances in compartment dev-compartment\n"
"Allow group devs to use virtual-network-family in compartment dev-compartment\n"
"Allow group devs to use volume-family in compartment dev-compartment"
)
# Example 2: generic "manage all-resources in tenancy" for any group – flag for manual review
if "manage all-resources in tenancy" in stmt_lower:
print(f"[MANUAL REVIEW NEEDED] {original_stmt}")
# Don't auto-change; return as-is or None depending on your policy
return original_stmt
# Default: no change
return original_stmt
def update_policy(policy_id: str):
# Get existing policy
existing = identity.get_policy(policy_id).data
new_statements = []
for stmt in existing.statements:
new_stmt = rewrite_statement(stmt)
if not new_stmt:
continue
# If rewrite returns multi-line, split into separate OCI statements
for s in new_stmt.splitlines():
if s.strip():
new_statements.append(s.strip())
# If no changes, skip
if new_statements == existing.statements:
print(f"No changes for policy {existing.name}")
return
details = oci.identity.models.UpdatePolicyDetails(
description=existing.description,
statements=new_statements,
version_date=existing.version_date,
freeform_tags=existing.freeform_tags,
defined_tags=existing.defined_tags
)
print(f"Updating policy {existing.name} ({policy_id})...")
identity.update_policy(policy_id, details)
print("Update complete.")
if __name__ == "__main__":
# Example: call with a known policy OCID you want to fix
POLICY_OCID = "ocid1.policy.oc1..xxxx"
update_policy(POLICY_OCID)
Important:
- Test changes in a non-production tenancy or compartment first.
- Consider exporting policies (e.g., into Git) before bulk edits for rollback.
- For governance monitoring, usually you:
- Detect problematic policies automatically.
- Open tickets or send alerts to owners.
- Apply changes manually or through a controlled pipeline.
6. Integrating with “OCI Governance Monitoring”
To make this part of a governance solution:
- Run the detection script periodically (OCI Functions, scheduled job, CI pipeline).
- Send findings to:
- OCI Logging / Object Storage, or
- A ticketing system (ServiceNow/Jira) via webhook, or
- Email/Slack via your automation layer.
- For high-risk cases (e.g.,
manage all-resources in tenancy), require manual review. - For low-risk patterns you’ve standardized, use the update script with a carefully controlled rule set.
If you share an example of a specific policy statement you have, I can give a concrete “before/after” rewrite and the exact Python logic to handle that pattern.
Using Terraform
resource "oci_governance_rules_tenancy_policy" "GOVERNANCE_POLICY_NAME" {
# Replace with the OCID of the tenancy where the governance policy is defined
compartment_id = var.TENANCY_OCID
# Replace with the governance tenancy policy display name
display_name = "GOVERNANCE_TENANCY_POLICY_DISPLAY_NAME"
# Replace with the description you want for the policy
description = "Hardened governance tenancy policy without wildcard admin access"
# Remediation: remove broad 'manage/use all-resources in tenancy' grants
# and scope permissions to specific resource families and compartments.
#
# BEFORE (vulnerable example, do NOT keep):
# "Allow group OPERATORS_GROUP to manage all-resources in tenancy"
statements = [
# Example of scoped permissions – adjust to the actual groups, verbs, and resources you require.
# PRINCIPAL: group OPERATORS_GROUP can administer compute instances
# SCOPE: only 'instance-family' resources
# LOCATION: only in a specific compartment
"Allow group OPERATORS_GROUP to manage instance-family in compartment COMPARTMENT_NAME",
# PRINCIPAL: group NETWORK_ADMINS_GROUP manages network resources
# SCOPE: only 'virtual-network-family'
# LOCATION: only in a specific compartment
"Allow group NETWORK_ADMINS_GROUP to manage virtual-network-family in compartment NETWORK_COMPARTMENT_NAME",
# PRINCIPAL: group READONLY_GROUP gets read-only access
# SCOPE: specific families instead of all-resources
# LOCATION: entire tenancy is acceptable for read-only, but verbs are limited to 'inspect'
"Allow group READONLY_GROUP to inspect instance-family in tenancy",
"Allow group READONLY_GROUP to inspect virtual-network-family in tenancy",
]
}
Substitute:
TENANCY_OCIDwith the target tenancy OCID.GOVERNANCE_TENANCY_POLICY_DISPLAY_NAMEwith the existing governance tenancy policy display name.OPERATORS_GROUP,NETWORK_ADMINS_GROUP,READONLY_GROUPwith your actual OCI IAM group names.COMPARTMENT_NAME,NETWORK_COMPARTMENT_NAMEwith the exact compartment names/OCIDs you want to scope access to.
This change updates the existing governance tenancy policy in place (no resource replacement), but it can immediately reduce privileges for affected groups once applied, so coordinate the change with application and operations owners.
For verification, terraform plan should show the oci_governance_rules_tenancy_policy.GOVERNANCE_POLICY_NAME resource with a change only in its statements attribute, removing any manage all-resources in tenancy / use all-resources in tenancy lines and replacing them with the more scoped statements you defined.