๐ก Setup โ Why Preparation Matters
A proper environment eliminates runtime surprises when working with OCI bucket policies via the Python SDK; the workflow depends on an authenticated client object.
๐ Table of Contents
- ๐ก Setup โ Why Preparation Matters
- ๐ Policy Structure โ How OCI Interprets Policies
- ๐ Statement Anatomy โ What Each Field Does
- ๐ Building the Policy with Python SDK
- ๐ Creating a Policy โ Applying It to a Bucket
- ๐ Updating and Deleting โ Managing Policy Lifecycle
- โ๏ธ Update Example โ Adding a Write Permission
- ๐ Delete Example โ Removing All Custom Rules
- ๐ Testing and Validation โ Verifying OCI Bucket Policies with Python SDK
- ๐ฉ Final Thoughts
- โ Frequently Asked Questions
- How do I list the current policy of a bucket?
- Can I apply multiple policies to the same bucket?
- What is the limit on policy size?
- ๐ References & Further Reading
๐ Policy Structure โ How OCI Interprets Policies
OCI bucket policy is a JSON document evaluated for each request; the SDK serializes this structure into a string passed to the put_bucket_policy API.
A policy consists of an array of statements, each defining an effect, a list of actions, a principal, and a condition that limits when the statement applies.
OCI bucket policy is a set of JSON statements that grant or deny permissions on a bucket based on request attributes.
According to the official OCI documentation, the policy language supports wildcards and condition operators that are evaluated serverโside, reducing network chatter.
๐ Statement Anatomy โ What Each Field Does
{ "Version": "20190401", "Statement": [ { "Effect": "Allow", "Action": ["OBJECT_READ"], "Principal": {"AWS": ["*"]}, "Resource": ["arn:oci:objectstorage:us-phoenix-1:example-tenancy:bucket/example-bucket/*"] } ]
}
What this does:
- Version: Schema version; required for forward compatibility.
-
Effect: Either
AlloworDeny. -
Action: List of OCI Object Storage actions (e.g.,
OBJECT_READ). -
Principal: Who the statement applies to;
*means any authenticated principal. - Resource: ARN pattern matching objects inside the bucket.
๐ Building the Policy with Python SDK
# build_policy.py
import json policy = { "Version": "20190401", "Statement": [ { "Effect": "Allow", "Action": ["OBJECT_READ"], "Principal": {"AWS": ["*"]}, "Resource": [f"arn:oci:objectstorage:{config['region']}:{config['tenancy']}:bucket/{bucket_name}/*"] } ]
} policy_json = json.dumps(policy, indent=2)
print(policy_json)
Serializing with json.dumps guarantees proper quoting and ordering, which the SDK transmits unchanged.
Key point: The policy JSON must be valid UTFโ8; malformed syntax triggers a 400 Bad Request before any evaluation occurs. (More onPythonTPoint tutorials)
๐ Creating a Policy โ Applying It to a Bucket
Creating a policy attaches the JSON document to a bucket, making the access rules enforceable immediately. (Also read: โ๏ธ OCI vs GCP compute pricing for Docker โ which one should you use?)
# apply_policy.py
import oci
import json config = oci.config.from_file()
client = oci.object_storage.ObjectStorageClient(config) bucket_name = "example-bucket"
policy_path = "policy.json" # Load JSON from file
with open(policy_path, "r") as f: policy_json = f.read() response = client.put_bucket_policy( namespace_name=client.get_namespace().data, bucket_name=bucket_name, put_bucket_policy_details=oci.object_storage.models.PutBucketPolicyDetails( policy=policy_json )
) print(f"Status: {response.status}")
What this does:
- client.get_namespace(): Retrieves the tenancy namespace required for all Object Storage calls.
-
put_bucket_policy: Sends a
PUTrequest with the policy string. -
response.status: HTTP status;
200indicates success.$ python apply_policy.py
Status: 200
The SDK call is reproducible, versionโcontrolled, and CIโcompatible, unlike a oneโoff console edit.
Consistent policy deployment through code eliminates drift between environments.
Key point: Once attached, the policy is evaluated for every request, providing a single source of truth for bucket permissions. (Also read: โ๏ธ S3 bucket policy vs ACL comparison โ which one should you use?)
๐ Updating and Deleting โ Managing Policy Lifecycle
Updating a policy replaces the existing JSON document; deleting removes all custom rules, reverting to the default implicit deny.
โ๏ธ Update Example โ Adding a Write Permission
# update_policy.py
import oci, json config = oci.config.from_file()
client = oci.object_storage.ObjectStorageClient(config) bucket_name = "example-bucket" # Retrieve current policy
current = client.get_bucket_policy( namespace_name=client.get_namespace().data, bucket_name=bucket_name
).data.policy policy = json.loads(current)
policy["Statement"].append({ "Effect": "Allow", "Action": ["OBJECT_WRITE"], "Principal": {"AWS": ["*"]}, "Resource": [f"arn:oci:objectstorage:{config['region']}:{config['tenancy']}:bucket/{bucket_name}/*"]
}) updated_json = json.dumps(policy, indent=2) client.put_bucket_policy( namespace_name=client.get_namespace().data, bucket_name=bucket_name, put_bucket_policy_details=oci.object_storage.models.PutBucketPolicyDetails( policy=updated_json )
) print("Policy updated")
$ python update_policy.py
Policy updated
๐ Delete Example โ Removing All Custom Rules
# delete_policy.py
import oci config = oci.config.from_file()
client = oci.object_storage.ObjectStorageClient(config) bucket_name = "example-bucket" client.delete_bucket_policy( namespace_name=client.get_namespace().data, bucket_name=bucket_name
) print("Policy deleted")
$ python delete_policy.py
Policy deleted
Deleting first guarantees that stale statements are not retained if the new policy accidentally omits required fields.
Key point: The SDK raises oci.exceptions.ServiceError on failure, enabling programmatic retries.
๐ Testing and Validation โ Verifying OCI Bucket Policies with Python SDK
Testing confirms that the policy behaves as intended before it reaches production workloads.
Use a temporary object and attempt operations that should be allowed or denied based on the current policy.
# test_policy.py
import oci, json, uuid config = oci.config.from_file()
client = oci.object_storage.ObjectStorageClient(config) ns = client.get_namespace().data
bucket = "example-bucket"
obj_name = f"test-{uuid.uuid4()}.txt"
content = b"policy test" # Upload object โ should succeed if OBJECT_WRITE is allowed
try: client.put_object( namespace_name=ns, bucket_name=bucket, object_name=obj_name, put_object_body=content ) print("Upload succeeded")
except oci.exceptions.ServiceError as e: print(f"Upload failed: {e.message}") # Attempt to delete โ should fail if only READ is allowed
try: client.delete_object( namespace_name=ns, bucket_name=bucket, object_name=obj_name ) print("Delete succeeded")
except oci.exceptions.ServiceError as e: print(f"Delete failed: {e.message}")
$ python test_policy.py
Upload succeeded
Delete failed: Forbidden
The SDK surfaces HTTP 403 as a ServiceError, making it straightforward to assert expected outcomes in unit tests.
Key point: Automated tests catch policy regressions early, preventing accidental privilege escalation.
๐ฉ Final Thoughts
OCI bucket policies with the Python SDK provide a programmatic, repeatable method for enforcing fineโgrained access controls. Constructing the JSON policy in code keeps the definition versioned alongside application logic, reducing drift between environments.
Understanding the evaluation mechanismโhow the service parses each statement and matches it against request attributesโenables the design of policies that are both secure and performant. The SDKโs builtโin error handling and pagination simplify integration into CI pipelines, making policy management a firstโclass part of the deployment workflow.
โ Frequently Asked Questions
How do I list the current policy of a bucket?
Use client.get_bucket_policy with the namespace and bucket name; the response contains the policy JSON string.
Can I apply multiple policies to the same bucket?
No. OCI allows only a single policy document per bucket; combine all statements into one JSON document.
What is the limit on policy size?
OCI enforces a maximum of 20 KB for the policy string; exceeding this limit returns a 413 Payload Too Large error.
๐ก Want to practise this hands-on? DigitalOcean gives new accounts $200 free credit for 60 days โ enough to spin up a full Linux/Docker/Kubernetes environment at no cost.
๐ Recommended reading: Best DevOps & cloud books on Amazon โ from Linux fundamentals to Kubernetes in production, curated for working engineers.
๐ References & Further Reading
- Python JSON handling โ best practices for serializing policy documents: docs.python.org

Top comments (0)