Oracle Cloud (OCI) Object Storage
Back NativeLink's CAS and Action Cache with Oracle Cloud Infrastructure Object Storage via its S3 Compatibility API.
NativeLink can use Oracle Cloud Infrastructure (OCI) Object
Storage as the backing
store for the CAS and Action Cache. It is configured through the
experimental_cloud_object_store store with provider: "oci", alongside the
aws, gcs, azure, and r2 providers.
How it works
OCI Object Storage exposes an S3 Compatibility API. The OCI store is a thin adapter that points NativeLink's S3 store at OCI's S3-compatible endpoint, so it reuses the same multipart upload, retry, and streaming code paths as the AWS backend. Two OCI-specific adjustments are applied automatically:
- Path-style addressing - OCI requires
endpoint/bucket/keyrather than virtual-hosted (bucket.endpoint/key) URLs. - Checksums downgraded to "when required" - the AWS SDK otherwise adds a
default trailing checksum that forces
Content-Encoding: aws-chunked, which OCI rejects with501 NotImplemented: AWS chunked encoding not supported. Without this, small single-PUTobjects (notably Action Cache entries) fail.
You do not need to configure either of these; they are handled by the store.
Prerequisites
- A bucket. Create one in the OCI Console under Storage → Buckets, or
with
oci os bucket create. Note the bucket's region (e.g.ap-mumbai-1). - Your Object Storage namespace. A tenancy-wide identifier shown under
Tenancy details, or via
oci os ns get. The endpoint is derived ashttps://{namespace}.compat.objectstorage.{region}.oci.customer-oci.com. - A Customer Secret Key (see Authentication).
Authentication
OCI's S3 Compatibility API authenticates with Customer Secret Keys - a
static access-key / secret-key pair, used as the S3 access_key_id and
secret_access_key.
Generate one in the Console under Profile → Customer Secret Keys → Generate Secret Key:
- The Secret Key is shown only once at generation time - copy it immediately.
- The Access Key is listed permanently in the Customer Secret Keys table and can be copied at any time.
Grant the associated user read/write on the bucket with a least-privilege policy:
Allow group <your-group> to manage object-family in compartment <compartment> where target.bucket.name='<bucket>'We recommend supplying the keys via environment variables and referencing them with shellexpand.
The S3 Compatibility API supports only Customer Secret Keys. OCI-native authentication - API signing keys, and instance/resource principals - is not available through this store. If you run NativeLink on OCI compute and want keyless workload-identity auth, that is not currently supported; you must use static Customer Secret Keys and rotate them yourself.
Configuration
A minimal CAS + Action Cache setup (see also
oci_backend.json5):
{
stores: [
{
name: "CAS_MAIN_STORE",
experimental_cloud_object_store: {
provider: "oci",
namespace: "storagenamespace",
region: "ap-mumbai-1",
bucket: "nativelink-cas",
access_key_id: "${OCI_ACCESS_KEY_ID}",
secret_access_key: "${OCI_SECRET_ACCESS_KEY}",
key_prefix: "cas/",
retry: { max_retries: 6, delay: 0.3, jitter: 0.5 },
},
},
{
name: "AC_MAIN_STORE",
experimental_cloud_object_store: {
provider: "oci",
namespace: "storagenamespace",
region: "ap-mumbai-1",
bucket: "nativelink-cas",
access_key_id: "${OCI_ACCESS_KEY_ID}",
secret_access_key: "${OCI_SECRET_ACCESS_KEY}",
key_prefix: "ac/",
retry: { max_retries: 6, delay: 0.3, jitter: 0.5 },
},
},
],
// ...servers omitted; see oci_backend.json5
}In production, wrap the CAS store in verify (for integrity) and front it with
a fast_slow filesystem/memory layer to cut round-trips to OCI, exactly as you
would for the AWS backend.
Fields
| Field | Required | Description |
|---|---|---|
namespace | yes | Object Storage namespace; used to derive the endpoint. |
region | yes | OCI region id (e.g. ap-mumbai-1); also the SigV4 signing region. |
bucket | yes | Target bucket. |
access_key_id | no | Customer Secret Key access key. Falls back to the AWS default credential chain if unset. |
secret_access_key | no | Customer Secret Key secret. |
key_prefix, retry, ... | no | Shared experimental_cloud_object_store options. |
Operational notes
- Reap incomplete multipart uploads. When a multipart upload fails
mid-flight the store issues
AbortMultipartUploadto clean up (verified that OCI honors bothListMultipartUploadsandAbortMultipartUpload). A process killed before it can abort still leaves orphaned parts, so add a bucket lifecycle rule to abort incomplete multipart uploads after a few days as a backstop. - Status. This backend lives under
experimental_cloud_object_store. Its core paths - read, write, existence checks, ranged reads, multipart, and integrity - are verified against live OCI, including an end-to-end Bazel remote cache round-trip, a 2 GiB multipart upload (~400 parts) with full byte verification, multipart abort/cleanup, and 200-way concurrent load. It has not been benchmarked at sustained production scale or duration.