> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# OCI Storage Buckets Should Not Be Publicly Accessible

### More Info:

Buckets must not be publicly accessible. Open buckets are a primary vector for cloud data breaches. Access must be strictly governed via robust Identity and Access Management (IAM) policies

### Risk Level

Critical

### Address

Compliance, Security

### Compliance Standards

* APRA CPS 234 (Australia)
* AWS Startup Security Baseline
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS AWS
* CIS Critical Security Controls v8
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* Cloudanix Best Practice
* DPDPA
* Digital Operational Resilience Act (EU)
* Essential 8
* FedRAMP
* GDPR
* HIPAA
* HITRUST CSF
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST
* NIST CSF
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* PCI
* Reserve Bank of India (RBI) Cyber Security Framework
* Reserve Bank of India (RBI) Master Direction – Information Technology Framework
* SOC2
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* Securities and Exchange Board of India (SEBI) - Cloud Security Adoption Framework
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are concise, step‑by‑step instructions to **find and fix public OCI Object Storage buckets using the OCI Console**.

        ***

        ## 1. Identify Public Buckets

        ### A. Using Cloud Guard (recommended for “monitoring”)

        1. In the OCI Console, open the navigation menu (≡).
        2. Go to **Security → Cloud Guard**.
        3. Select your **Compartment** and **Target** where Object Storage is used.
        4. Go to **Detections → Problems**.
        5. Filter:
           * **Resource Type** = `Object Storage Bucket`
           * (Optional) **Risk Level** = `High` or `Critical`
        6. Look for problems with descriptions like **“Bucket is publicly accessible”** or similar.

        These are the buckets you need to remediate.

        ### B. Directly from Object Storage

        1. Open the navigation menu (≡).
        2. Go to **Storage → Buckets (Object Storage)**.
        3. Select the **Compartment**.
        4. Review each bucket:
           * The **Access Type** column will show `Public` for public buckets.

        ***

        ## 2. Remove Public Access from a Bucket

        Perform this for each bucket that should not be public.

        1. In the Console, go to **Storage → Buckets**.
        2. Choose the correct **Compartment**.
        3. Click the **bucket name** that is public.
        4. On the bucket detail page, click **Edit** (upper left).
        5. Find the **Public access type** / **Access Type** setting:
           * If set to `Public`, change it to:
             * `Private` (recommended)
             * or a more restricted option like `No public access` if shown.
        6. Click **Save changes**.

        ***

        ## 3. Check and Remove Public Policies / Grants

        Even if “Public” is disabled at the bucket setting, IAM policies or users might still expose data.

        ### A. Bucket Public Access via “Bucket Policy” or Grants

        1. Still on the bucket’s page, review:
           * **Permissions / Access** or **Bucket Policy** section.
        2. Remove any access entries that:
           * Grant access to **`Any user`**, **`ObjectRead`**, **`ObjectReadWithoutList`**, or similar public roles.
        3. Save changes.

        ### B. IAM Policies at Tenancy/Compartment Level

        1. Navigation menu (≡) → **Identity & Security → Policies**.
        2. For each policy in the relevant compartment/tenancy:
           * Look for statements granting object storage access to **`any-user`** or **`all-users`**, e.g.:
             * `allow any-user to read objects in compartment ...`
        3. Edit or remove those policies, and replace them with least-privilege policies that grant access only to:
           * Specific groups
           * Specific dynamic groups
           * Specific compartments

        ***

        ## 4. Disable/Review Pre-Authenticated Requests (PARs)

        1. On the bucket page, open the **Pre-Authenticated Requests** tab.
        2. Check for PARs that:
           * Have **No expiration** or a very long expiry
           * Provide **read** or **write** access broadly.
        3. For any PAR not strictly needed:
           * Click the PAR → **Revoke**.
        4. For necessary PARs:
           * Ensure they:
             * Have minimal privileges.
             * Have a short, appropriate expiration.

        ***

        ## 5. Set Up Ongoing Monitoring & Alerts

        To continuously monitor for new public buckets:

        1. **Cloud Guard**:
           * Ensure Cloud Guard is **Enabled** at tenancy or root compartment.
           * Confirm the **Detector Recipes** include:
             * Object Storage configuration detectors (public bucket detection).
           * Enable **Responder Recipes** if you want automatic or guided remediation.

        2. **Notifications / Alarms (Optional)**:
           * Use **Cloud Guard → Notifications** or create OCI **Events + Notifications** to alert when:
             * A bucket’s access settings change.
             * New Cloud Guard problems appear for Object Storage.

        ***

        Following these steps in the OCI Console will remove public access and keep OCI Object Storage buckets monitored for future misconfigurations.
      </Accordion>

      <Accordion title="Using CLI">
        Below are concise, step‑by‑step instructions to detect and remediate public OCI Object Storage buckets **using OCI CLI**.

        Assumptions:

        * You have OCI CLI installed and configured (`oci setup config` done).
        * You know the **compartment OCID** where your monitoring buckets live.
        * Replace placeholders like `<compartment_ocid>` and `<bucket_name>` with real values.

        ***

        ## 1. Identify Public Buckets

        Public buckets have `publicAccessType` set to `ObjectRead` or `NoList` (any non-`NoPublicAccess`).

        List all buckets in a compartment and show their access type:

        ```bash theme={null}
        oci os bucket list \
          --compartment-id <compartment_ocid> \
          --all \
          --output table \
          --query "data[].{name:name, namespace:namespace, access:public-access-type}"
        ```

        Optionally, filter to only buckets that are public:

        ```bash theme={null}
        oci os bucket list \
          --compartment-id <compartment_ocid> \
          --all \
          --query "data[?\"public-access-type\" != 'NoPublicAccess'].[name, namespace, \"public-access-type\"]" \
          --output table
        ```

        Take note of:

        * `name`
        * `namespace`
          for each public bucket.

        ***

        ## 2. Remediate a Single Public Bucket (Lock Down Access)

        For each bucket you identified, set `public-access-type` to `NoPublicAccess`.

        ```bash theme={null}
        oci os bucket update \
          --namespace-name <namespace> \
          --bucket-name <bucket_name> \
          --public-access-type NoPublicAccess
        ```

        Verify:

        ```bash theme={null}
        oci os bucket get \
          --namespace-name <namespace> \
          --bucket-name <bucket_name> \
          --query "data.{name:name, access:public-access-type}" \
          --output table
        ```

        You should see: `access = NoPublicAccess`.

        ***

        ## 3. Bulk Remediate All Public Buckets in a Compartment

        Use a small shell loop (Linux/macOS, with `jq`):

        ```bash theme={null}
        COMPARTMENT_ID="<compartment_ocid>"

        oci os bucket list \
          --compartment-id "$COMPARTMENT_ID" \
          --all \
          --raw-output \
          | jq -r '.data[] | select(."public-access-type" != "NoPublicAccess") | "\(.namespace) \(.name)"' \
          | while read NS BUCKET; do
              echo "Locking down bucket: $BUCKET (namespace: $NS)"
              oci os bucket update \
                --namespace-name "$NS" \
                --bucket-name "$BUCKET" \
                --public-access-type NoPublicAccess
            done
        ```

        ***

        ## 4. Ensure No Public Access via IAM Policies (Optional but Recommended)

        Even if bucket `public-access-type` is private, IAM policies can expose data if misconfigured.

        List policies in the compartment:

        ```bash theme={null}
        oci iam policy list \
          --compartment-id <compartment_ocid> \
          --all \
          --output table \
          --query "data[].{name:name, id:id}"
        ```

        Get policy statements:

        ```bash theme={null}
        oci iam policy get \
          --policy-id <policy_ocid> \
          --query "data.statements" \
          --output table
        ```

        Look for rules like:

        * `Allow any-user to read objects in tenancy`
        * `Allow any-user to read objects in compartment <name>`

        If you find such statements, **edit policies via Console or `oci iam policy update`** to remove/limit `any-user` access. (Policy text must be updated as a whole, so usually easier via Console.)

        ***

        ## 5. Validate No Buckets are Public

        Re-run:

        ```bash theme={null}
        oci os bucket list \
          --compartment-id <compartment_ocid> \
          --all \
          --query "data[?\"public-access-type\" != 'NoPublicAccess'].[name, namespace, \"public-access-type\"]" \
          --output table
        ```

        If output is empty, all buckets in that compartment are no longer publicly accessible.

        ***

        If you share an example bucket’s `oci os bucket get` output (sanitized), I can give an exact `oci` command tailored to that bucket.
      </Accordion>

      <Accordion title="Using Python">
        Below is a minimal, concrete way to *detect* and *remediate* publicly accessible OCI Object Storage buckets using Python and the OCI SDK.

        ***

        ## 1. Prerequisites

        1. Install the OCI Python SDK:

        ```bash theme={null}
        pip install oci
        ```

        2. Configure OCI CLI/SDK credentials (e.g. `~/.oci/config`):

        ```ini theme={null}
        [DEFAULT]
        user=ocid1.user.oc1..aaaa...
        fingerprint=xx:xx:xx:xx:xx
        key_file=/path/to/oci_api_key.pem
        tenancy=ocid1.tenancy.oc1..aaaa...
        region=us-ashburn-1
        ```

        ***

        ## 2. What “public” means in OCI Object Storage

        A bucket is public if:

        1. Its `public_access_type` is:
           * `ObjectRead` or
           * `ObjectReadWithoutList`
        2. Or IAM policies allow `ANY-USER` or `ANONYMOUS-USER` to access it.
        3. Or there are Pre-Authenticated Requests (PARs) that expose objects.

        Below is Python code that:

        * Finds buckets with public access type
        * Sets them to private (`NoPublicAccess`)
        * Optionally deletes PARs for those buckets

        ***

        ## 3. Python script: Monitor & Remediate Public Buckets

        ```python theme={null}
        import oci

        # ---- CONFIG ----
        PROFILE = "DEFAULT"  # name in ~/.oci/config
        DRY_RUN = False      # set True to only report, False to remediate

        config = oci.config.from_file("~/.oci/config", PROFILE)
        identity_client = oci.identity.IdentityClient(config)
        object_storage_client = oci.object_storage.ObjectStorageClient(config)

        tenancy_id = config["tenancy"]
        namespace = object_storage_client.get_namespace().data

        # 1. Get all compartments (including root)
        def list_compartments(tenancy_id):
            compartments = []
            request = oci.identity.models.ListCompartmentsRequest(
                compartment_id=tenancy_id
            )
            # Use paginator to get all
            for c in oci.pagination.list_call_get_all_results(
                identity_client.list_compartments,
                tenancy_id,
                compartment_id_in_subtree=True,
                access_level="ACCESSIBLE"
            ).data:
                if c.lifecycle_state == "ACTIVE":
                    compartments.append(c)
            # ensure root compartment is included
            root_compartment = identity_client.get_compartment(tenancy_id).data
            compartments.append(root_compartment)
            return compartments

        # 2. Find & fix public buckets
        def remediate_public_buckets():
            compartments = list_compartments(tenancy_id)

            for comp in compartments:
                print(f"\nChecking compartment: {comp.name} ({comp.id})")

                buckets = oci.pagination.list_call_get_all_results(
                    object_storage_client.list_buckets,
                    namespace_name=namespace,
                    compartment_id=comp.id
                ).data

                for bucket in buckets:
                    # Get full bucket details
                    b = object_storage_client.get_bucket(
                        namespace_name=namespace,
                        bucket_name=bucket.name
                    ).data

                    pat = b.public_access_type
                    if pat in ("ObjectRead", "ObjectReadWithoutList"):
                        print(f"  [PUBLIC] Bucket: {b.name}, public_access_type={pat}")

                        if not DRY_RUN:
                            # 2a. Set bucket to private
                            update_details = oci.object_storage.models.UpdateBucketDetails(
                                public_access_type="NoPublicAccess"
                            )
                            object_storage_client.update_bucket(
                                namespace_name=namespace,
                                bucket_name=b.name,
                                update_bucket_details=update_details
                            )
                            print(f"    -> Updated public_access_type to NoPublicAccess")

                            # 2b. Optionally: delete PARs on this bucket
                            # (comment out if you only want to change public_access_type)
                            delete_bucket_pars(namespace, b.name)
                    else:
                        print(f"  [OK] Bucket: {b.name}, public_access_type={pat}")

        # 3. Delete Pre-Authenticated Requests (PARs) for a bucket
        def delete_bucket_pars(namespace, bucket_name):
            print(f"    -> Checking PARs for bucket: {bucket_name}")
            pars_response = oci.pagination.list_call_get_all_results(
                object_storage_client.list_preauthenticated_requests,
                namespace_name=namespace,
                bucket_name=bucket_name
            )
            pars = pars_response.data

            if not pars:
                print("       No PARs found.")
                return

            for par in pars:
                print(f"       PAR: {par.name} ({par.id}), access_type={par.access_type}")
                if not DRY_RUN:
                    object_storage_client.delete_preauthenticated_request(
                        namespace_name=namespace,
                        bucket_name=bucket_name,
                        par_id=par.id
                    )
                    print(f"         -> Deleted PAR {par.id}")

        if __name__ == "__main__":
            print(f"DRY_RUN = {DRY_RUN}")
            remediate_public_buckets()
        ```

        ***

        ## 4. How to use this for “monitoring”

        * Run this script periodically (e.g., via cron, Jenkins, or OCI DevOps).
        * Keep `DRY_RUN = True` in a monitoring job to only report.
        * Use `DRY_RUN = False` in a remediation job to auto-fix.

        For stricter security, additionally review and clean up IAM policies that grant object/bucket access to `ANY-USER` or `ANONYMOUS-USER`. That part requires parsing `identity_client.list_policies(...)` and adjusting policy statements, which is usually done manually or via Terraform.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "oci_objectstorage_bucket" "PRIVATE_BUCKET" {
          # Replace with your tenancy details
          compartment_id = "OCID_OF_COMPARTMENT"
          namespace      = "OBJECTSTORAGE_NAMESPACE"
          name           = "BUCKET_NAME"

          # Ensure the bucket is NOT publicly accessible
          public_access_type = "NoPublicAccess"

          # Keep or add any other arguments you already manage here
          storage_tier = "Standard"
        }
        ```

        Changing `public_access_type` from a public value (e.g. `ObjectRead`, `NoList`) to `"NoPublicAccess"` is an in‑place update and does not force replacement of the bucket.

        For verification, `terraform plan` should show an in-place update on `oci_objectstorage_bucket.PRIVATE_BUCKET` with `public_access_type` changing to `NoPublicAccess` and no resource replacements.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
