Securing Object Storage

This topic provides security information and recommendations for Object Storage.

The Object Storage service is a high-performance storage platform that offers reliable and cost-efficient data durability. You can store an unlimited amount of unstructured data of any content type, including analytic data and rich content, like images and videos.

Security Responsibilities

To use Object Storage securely, learn about your security and compliance responsibilities.

In general, Oracle provides security of cloud infrastructure and operations, such as cloud operator access controls and infrastructure security patching. You are responsible for securely configuring your cloud resources. Security in the cloud is a shared responsibility between you and Oracle.

Oracle is responsible for the following security requirements:

  • Physical Security: Oracle is responsible for protecting the global infrastructure that runs all services offered in Oracle Cloud Infrastructure. This infrastructure consists of the hardware, software, networking, and facilities that run Oracle Cloud Infrastructure services.

Your security responsibilities are described on this page, which include the following areas:

  • Access Control: Limit privileges as much as possible. Users should be given only the access necessary to perform their work.
  • Encryption and Confidentiality: Use encryption keys and secrets to protect your data and connect to secured resources. Rotate these keys regularly.

Initial Security Tasks

Use this checklist to identify the tasks you perform to secure Object Storage in a new Oracle Cloud Infrastructure tenancy.

Task More Information
Use IAM policies to grant access to users and resources IAM Policies
Encrypt resources using a custom key Data Encryption
Secure network access to resources Network Security
Enable and configure Cloud Guard (optional) Cloud Guard
Create a security zone (optional) Security Zones

Routine Security Tasks

After getting started with Object Storage use this checklist to identify security tasks that we recommend you perform regularly.

Task More Information
Rotate encryption keys Data Encryption
Respond to problems detected in Cloud Guard Cloud Guard
Take regular backups Data Durability
Ensure the integrity of your data when it's moved or copied to different locations Data Security
Perform a security audit Auditing

IAM Policies

Use policies to limit access to Object Storage.

A policy specifies who can access Oracle Cloud Infrastructure resources and how. For more information, see How Policies Work.

Assign a group the least privileges that are required to perform their responsibilities. Each policy has a verb that describes what actions the group is allowed to do. From the least amount of access to the most, the available verbs are: inspect, read, use, and manage.

Assign least privileged access to resource types in object-family (buckets and objects). For example, the inspect verb lets you check to see if a bucket exists (HeadBucket) and list the buckets in a compartment (ListBucket). The manage verb gives all permissions on the resource.

We recommend that you give DELETE permissions to a minimum set of IAM users and groups. This practice minimizes loss of data from inadvertent deletes by authorized users or from malicious actors. Only give DELETE permissions to tenancy and compartment administrators.

In the following examples, the policies are scoped to a tenancy. However, specifying a compartment name reduces the scope to a specific compartment in a tenancy.

Restrict Group Access to Specific Buckets

You can restrict access by a group to a specific bucket by using the specific bucket name (target.bucket.name), regular expression matching (/*name/, /name*/, /*name*/), or defined tags (target.tag.definition.name).

The following example of restrict access to users in the BucketUsers group to a specific bucket.

Allow group BucketUsers to use buckets in tenancy
 where target.bucket.name='BucketFoo'

You can modify this policy to restrict access to users in the group BucketUsers to all buckets whose names are prefixed with ProjectA_.

Allow group BucketUsers to use buckets in tenancy
 where target.bucket.name=/ProjectA_*/

You can also match for post-fix (/*_ProjectA/) or substring (/*ProjectA*/).

Restrict Group Access to Read or Write to Objects in a Specific Bucket

The following example allows listing and reading objects by group BucketUsers from a specific bucket named BucketFoo.

Allow group BucketUsers to read buckets in tenancy
Allow group BucketUsers to manage objects in tenancy
 where all {target.bucket.name='BucketFoo', 
            any {request.permission='OBJECT_INSPECT', 
                 request.permission='OBJECT_READ'}}

The following policy modifies the previous policy to allow listing and writing objects to BucketFoo.

Allow group BucketUsers to read buckets in tenancy 
Allow group BucketUsers to manage objects in tenancy
 where all {target.bucket.name='BucketFoo', 
            any {request.permission='OBJECT_INSPECT', 
                 request.permission='OBJECT_CREATE'}}

You can restrict this policy to read or write access to a set of buckets by using regular expressions or tags rather than a specific bucket.

Restrict Group Access to Read or Write to Objects based on Bucket Tags

The following example allows listing and reading objects by group BucketUsers from all the buckets with the defined tag "MyTagNamespace.TagKey = MyTagValue".

Allow group BucketUsers to read buckets in tenancy
Allow group BucketUsers to manage objects in tenancy
 where all {target.bucket.tag.MyTagNamespace.TagKey='MyTagValue', 
            any {request.permission='OBJECT_INSPECT', 
                 request.permission='OBJECT_READ'}}

The following policy modifies the previous policy to allow listing and writing objects to all the buckets where the defined tag on the bucket matches the defined tag on the group that the user belongs to.

Allow group BucketUsers to read buckets in tenancy 
Allow group BucketUsers to manage objects in tenancy
 where all {request.principal.group.tag.MyTagNamespace.TagKey=target.bucket.tag.MyTagNamespace.TagKey, 
            any {request.permission='OBJECT_INSPECT', 
                 request.permission='OBJECT_CREATE'}}
Restrict Resource Access to a Particular User

You can restrict access to Object Storage resources to a specific user by adding a condition to the policy that specifies the user's OCID in a variable.

The following policy restricts access to the resources in ObjectStorage compartment to the user OCID specified:

Allow any-user to read object-family in compartment ObjectStorage where request.user.id ='ocid1.user.oc1..<user_OCID>'
Restrict Access to Requests That Originate From an Allowed IP Address

You can restrict access only to requests that originate from an allowed IP address. First, you create a network source  to specify the allowed IP addresses, then you add a condition to your policy to restrict access to the IP addresses in the network source.

The following policy restricts access to only IP addresses in a network source corpnet that defines the allowed IP addresses:

Allow group CorporateUsers to manage object-family in tenancy where request.networkSource.name='corpnet'

For information on creating network sources and using them in a policy, see Managing Network Sources.

Prevent Delete of Buckets or Objects

In the following example, the group BucketUsers can perform all actions on buckets and objects except delete.

Allow group BucketUsers to manage objects in tenancy
 where request.permission!='OBJECT_DELETE' 
Allow group BucketUsers to manage buckets in tenancy
 where request.permission!='BUCKET_DELETE'

The following example further restricts object deletion from the specific bucket (BucketFoo).

Allow group BucketUsers to manage objects in tenancy
  where any {target.bucket.name!='BucketFoo', 
             all {target.bucket.name='BucketFoo',
                  request.permission!='OBJECT_DELETE'}}
Enable WORM Compliance for Objects

Use retention rules to achieve WORM compliance. Retention rules are configured at the bucket level and are applied to all individual objects in the bucket. You cannot update, overwrite, or delete objects or object metadata until the retention rule is deleted (indefinite rule) or for the duration specified (time-bound rules).

The following policies let BucketUsers manage the buckets and objects in the tenancy and allow BucketUsers to create, manage, and delete retention rules. These policies also let BucketUsers lock retentions rules for a specified time.

Allow group BucketUsers to manage buckets in tenancy
Allow group BucketUsers to manage objects in tenancy

The following more restrictive policies let BucketUsers perform all actions on buckets and objects except locking retention rules.

Allow group BucketUsers to manage buckets in tenancy
 where request.permission!='RETENTION_RULE_LOCK'
Allow group BucketUsers to manage objects in tenancy
Prevent Public Buckets Configuration

BUCKET_CREATE and BUCKET_UDPATE permissions are required to create buckets or make existing private buckets public. Removing these permissions prevents users from creating buckets or making existing buckets public.

Allow group BucketUsers to manage buckets in tenancy
 where any {request.permission='BUCKET_INSPECT', 
            request.permission='BUCKET_READ', 
            request.permission='PAR_MANAGE'}

For more information about Object Storage policies and to view more examples, see Details for Object Storage, Archive Storage, and Data Transfer.

Access Control

In addition to creating IAM policies, lock down access to Object Storage using features like pre-authenticated requests.

Public Buckets

A public bucket allows unauthenticated and anonymous reads to all objects in the bucket. Carefully evaluate the intended use case for public buckets before you enable public buckets.

We recommend that you use pre-authenticated requests to give bucket or object access to users without IAM credentials. By defaults, buckets are created with no public access (access type is set to NoPublicAccess).

You can make existing buckets public by updating the bucket access type to ObjectRead or ObjectReadWithoutList. To minimize the possibility of existing buckets being made public inadvertently or maliciously, restrict BUCKET_UPDATE permission to a minimal set of IAM groups.

The following CLI command returns the public-access-type assigned to a bucket.

oci os bucket get -ns <your_namespace> --bucket-name <bucket_name> | grep "public-access-type"

If the attribute public-access-type has the value NoPublicAccess, the bucket is private. Any other value such as ObjectRead indicates a public bucket.

Pre-Authenticated Requests

For users without IAM credentials, we recommend that you use pre-authenticated requests (PARs) to give time-bound access to objects or buckets.

In a pre-authenticated request, an IAM user who has appropriate privileges for accessing objects, can create special URLs that grant time-bound access to these objects. For more information, see Using Pre-Authenticated Requests.

The creator of a pre-authenticated request must have PAR_MANAGE permission and the appropriate IAM permissions for the access type that you are granting. You can create a pre-authenticated request that grants read, write, or read/write access to one of the following:

  • All objects in the bucket.
  • A specific object in the bucket.
  • All objects in the bucket that have a specified prefix.

The creator of a pre-authenticated request must have PAR_MANAGE permission and the appropriate IAM permissions for the access type that you are granting. You can create a pre-authenticated request that grants read, write, or read/write access to one of the following:

For requests that apply to multiple objects, you can also decide whether you want to let users list those objects.

Pre-authenticated request accesses to a bucket are logged in Audit logs. Pre-authenticated request accesses to an object are logged in Service logs.

Important

The unique URL provided by the system when you create a pre-authenticated request is the only way a user can access the request target. Copy the URL to durable storage. The URL is displayed only at the time of creation, is not stored in Object Storage, and cannot be retrieved later.

The following CLI command returns a list of object PARs in a bucket.

oci os preauth-request list -ns <your_namespace> -bn <bucket_name>

Cloud Guard

Enable Cloud Guard and use it to detect and respond to security issues in Object Storage.

Upon detecting a problem, Cloud Guard suggests corrective actions. You can also configure Cloud Guard to automatically take certain actions. Cloud Guard includes the following detector rules for Object Storage.

  • Bucket is public
  • Object Storage bucket is encrypted with Oracle-managed key
  • IAM customer keys created

For a list of all available detector rules in Cloud Guard, see Detector Recipe Reference.

If you haven't done so already, enable Cloud Guard and configure it to monitor the compartments that contain your resources. You can configure Cloud Guard targets to examine your entire tenancy (root compartment and all subcompartments), or to check only specific compartments. See Getting Started with Cloud Guard.

After enabling Cloud Guard, you can view and resolve detected security problems. See Processing Reported Problems.

Security Zones

Using Security Zones ensures your resources in Object Storage comply with security best practices.

A security zone is associated with one or more compartments and a security zone recipe. When you create and update resources in a security zone's compartment, Oracle Cloud Infrastructure validates these operations against the list of security zone policies in the recipe. If any policy in the recipe is violated, then the operation is denied. The following security zone policies are available for resources in Object Storage.

  • deny public_buckets
  • deny buckets_without_vault_key

For a list of all security zone policies, see Security Zone Policies.

To move existing resources to a compartment that is in a security zone, the resources must comply with all security zone policies in the zone's recipe. Similarly, resources in a security zone can’t be moved to a compartment outside of the security zone because it might be less secure. See Managing Security Zones.

Data Encryption

Create and rotate encryption keys in the Vault service to protect your resources in Object Storage.

All data in Object Storage is encrypted at rest by using AES-256. Encryption is on by default and cannot be turned off. Each object is encrypted with its encryption key, and the object encryption keys are encrypted with a master encryption key.

A vault is a logical entity that stores the encryption keys you use to protect your data. Depending on the protection mode, keys are either stored on the server, or they are stored on highly available and durable hardware security modules (HSMs). Our HSMs meet Federal Information Processing Standards (FIPS) 140-2 Security Level 3 security certification. See Managing Vaults and Managing Keys.

Although default encryption keys can be generated automatically when you create certain Oracle Cloud Infrastructure resources, we recommend that you create and manage your own custom encryption keys in the Vault service.

To assign a custom encryption key to a new bucket or an existing one, see:

Each master encryption key is automatically assigned a key version. When you rotate a key, the Vault service generates a new key version. Periodically rotating keys limits the amount of data encrypted or signed by one key version. If a key is ever comprised, key rotation reduces the risk to your data. See Managing Keys.

We recommend that you use IAM policies to strictly limit the creation, rotation, and deletion of encryption keys. See Details for the Vault Service.

You can also use client-side encryption to encrypt objects with their encryption keys before storing them in Object Storage buckets. An available option for customers is to use the Amazon S3 Compatibility API, along with client-side object encryption support available in AWS SDK for Java. See Amazon S3 Compatibility API for more details about on this SDK.

Data Durability

Take regular backups of your data in Object Storage.

Minimize data loss because of inadvertent deletes by an authorized user or malicious deletes. We recommend the following:
  • Use object versioning to automatically create an object version each time a new object is uploaded, an existing object is overwritten, or when an object is deleted.
  • Give BUCKET_DELETE and OBJECT_DELETE permissions to a minimum set of IAM users and groups. Grant delete permissions only to tenancy and compartment administrators.

"Write once, read many" (WORM) compliance requires that objects cannot be deleted or modified. Use retention rules to achieve WORM compliance. Retention rules are configured at the bucket level and are applied to all individual objects in the bucket. You cannot update, overwrite, or delete objects or object metadata until the retention rule is deleted (indefinite rule) or for the duration specified (time-bound rules).

For an independent assessment of the Object Storage retention rules feature's ability to meet regulatory requirements for record management and retention, see Cohasset Associate's SEC 17a-4(f), FINRA 4511(c), CFTC 1.31(c)-(d) and MiFID II Compliance Assessment.

Data Security

Ensure the integrity of your data in Object Storage.

To verify object data integrity, an MD5 checksum is provided for all objects uploaded to Object Storage. We recommend that you verify that the offline MD5 checksum of an object matches the checksum value returned by the Console or API after upload. Oracle Cloud Infrastructure provides the object checksum value in base64 encoding. To covert the base64 encoded checksum value to hexadecimal, use the following command:

python -c 'print "BASE64-ENCODED-MD5-VALUE".decode("base64").encode("hex")'

Linux provides an md5sum command line utility to compute the MD5 checksum value of an object in hexadecimal format.

Object Storage supports multipart uploads for more efficient and resilient uploads, especially for large objects. In a multipart upload, a large object is broken up into smaller parts by specifying a part size in MiB. Each part is uploaded separately. Object Storage then combines all the parts to create the original object. If any of the parts fail to upload, only those parts need to be retried for upload, and not the entire object.

In a multipart upload, the MD5 checksum values are computed for each part, and an MD5 checksum computed over all the individual checksum values to get the output MD5 value. To verify the MD5 value returned for a multipart upload, follow the same process for offline MD5 checksum calculation. A sample script for the offline calculation of an MD5 checksum value for a multipart upload to Object Storage is available here: https://gist.github.com/itemir/f5bc9fded6483cd79c89ebf4ca1cfd30.

Network Security

Secure network access to your resources in Object Storage.

Data in transit between customer clients (for example, SDKs and CLIs) and Object Storage public endpoints is encrypted with TLS 1.2 by default. FastConnect public peering allows on-premises access to Object Storage over a private network, rather than the public internet. See Access to Your On-Premises Network.

Auditing

Locate access logs and other security data for Object Storage.

The Audit service automatically records all API calls to Oracle Cloud Infrastructure resources. You can achieve your security and compliance goals by using the Audit service to monitor all user activity within your tenancy. Because all Console, SDK, and command line (CLI) calls go through our APIs, all activity from those sources is included. Audit records are available through an authenticated, filterable query API or they can be retrieved as batched files from Object Storage. Audit log contents include what activity occurred, the user that initiated it, the date and time of the request, as well as source IP, user agent, and HTTP headers of the request. See Viewing Audit Log Events.

Example Audit Log
{
  "datetime": 1642104527377,
  "logContent": {
    "data": {
      "additionalDetails": {
        "namespace": "mytenancy"
      },
      "availabilityDomain": "PHX-AD-1",
      "compartmentId": "ocid1.compartment.oc1..<unique_id>",
      "compartmentName": "mycompartment",
      "definedTags": null,
      "eventGroupingId": "<unique_id>",
      "eventName": "ListBuckets",
      "freeformTags": null,
      "identity": {
        "authType": null,
        "callerId": null,
        "callerName": null,
        "consoleSessionId": null,
        "credentials": "<key>",
        "ipAddress": "<ip_address>",
        "principalId": "<user_id>",
        "principalName": "<user_name>",
        "tenantId": "ocid1.tenancy.oc1..<unique_id>",
        "userAgent": "Oracle-JavaSDK/1.37.1 (Linux/4.14.35-2047.509.2.2.el7uek.x86_64; Java/1.8.0_301; Java HotSpot(TM) 64-Bit Server VM GraalVM EE 20.3.3/25.301-b09-jvmci-20.3-b18)"
      },
      "message": "List of buckets retrieved.",
      "request": {
        "action": "GET",
        "headers": {
          "Accept": [
            "application/json"
          ],
          "Connection": [
            "keep-alive"
          ],
          "User-Agent": [
            "Oracle-JavaSDK/1.37.1 (Linux/4.14.35-2047.509.2.2.el7uek.x86_64; Java/1.8.0_301; Java HotSpot(TM) 64-Bit Server VM GraalVM EE 20.3.3/25.301-b09-jvmci-20.3-b18)"
          ],
          "authorization": [
            "Signature headers=\"date (request-target) host\",keyId=\"<key>"
          ],
          "date": [
            "Thu, 13 Jan 2022 20:08:47 GMT"
          ],
          "opc-client-info": [
            "Oracle-JavaSDK/1.37.1"
          ],
          "opc-request-id": [
            "<unique_id>"
          ]
        },
        "id": "<unique_id>",
        "parameters": {
          "compartmentId": [
            "ocid1.compartment.oc1..<unique_id>"
          ],
          "fields": [
            "tags"
          ],
          "limit": [
            "1000"
          ],
          "param0": [
            "mytenancy"
          ]
        },
        "path": "/n/mytenancy/b?compartmentId=ocid1.compartment.oc1..<unique_id>&limit=1000&fields=tags"
      },
      "resourceId": "/n/mytenancy/b?compartmentId=ocid1.compartment.oc1..<unique_id>&limit=1000&fields=tags",
      "response": {
        "headers": {
          "Content-Length": [
            "2"
          ],
          "Content-Type": [
            "application/json"
          ],
          "access-control-allow-credentials": [
            "true"
          ],
          "access-control-allow-methods": [
            "POST,PUT,GET,HEAD,DELETE,OPTIONS"
          ],
          "access-control-allow-origin": [
            "*"
          ],
          "access-control-expose-headers": [
            "access-control-allow-credentials,access-control-allow-methods,access-control-allow-origin,content-length,content-type,date,opc-client-info,opc-request-id,x-api-id"
          ],
          "date": [
            "Thu, 13 Jan 2022 20:08:47 GMT"
          ],
          "opc-request-id": [
            "<unique_id>"
          ],
          "x-api-id": [
            "native"
          ]
        },
        "message": null,
        "payload": {
          "id": "/n/mytenancy/b?compartmentId=ocid1.compartment.oc1..<unique_id>&limit=1000&fields=tags",
          "resourceName": "/n/mytenancy/b?compartmentId=ocid1.compartment.oc1..<unique_id>&limit=1000&fields=tags"
        },
        "responseTime": "2022-01-13T20:08:47.377Z",
        "status": "200"
      },
      "stateChange": null
    },
    "dataschema": "2.0",
    "id": "<unique_id>",
    "oracle": {
      "compartmentid": "ocid1.compartment.oc1..<unique_id>",
      "ingestedtime": "2022-01-13T20:08:49.384Z",
      "loggroupid": "_Audit",
      "tenantid": "ocid1.tenancy.oc1..<unique_id>"
    },
    "source": "/n/mytenancy/b?compartmentId=ocid1.compartment.oc1..<unique_id>&limit=1000&fields=tags",
    "specversion": "1.0",
    "time": "2022-01-13T20:08:47.377Z",
    "type": "com.oraclecloud.objectstorage.listbuckets"
  }
}

If you enabled Cloud Guard in your tenancy, then it reports any user activities that are potential security concerns. Upon detecting a problem, Cloud Guard suggests corrective actions. You can also configure Cloud Guard to automatically take certain actions. See Getting Started with Cloud Guard and Processing Reported Problems.