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

# S3

> S3 APIs with Cloud Adapter.

This page describes how S3 maps to services in the environment where the application runs. Some profiles adapt origin API calls; others translate infrastructure or document target-native behavior.

## Supported environments

| Environment        | Mapping        |
| ------------------ | -------------- |
| Azure              | API            |
| DigitalOcean       | API            |
| Google Cloud       | API            |
| OCI                | API            |
| Private Kubernetes | Infrastructure |
| Scaleway           | API            |

API means the profile adapts origin API behavior. Infrastructure means the profile changes provisioned resources or documents a target-native alternative without promising an origin API endpoint. Check the operation and capability tables for the behavior your application depends on.

## How the targets compare

Each row compares a capability of S3 with its adaptation on each target.
A dash means this profile does not state the capability for that target.

### Cloud Adapter

| Capability                                                                         | S3                                                                                  | Azure                                                                                                                               | DigitalOcean                                                                                                  | Google Cloud                                                                                       | OCI                                                                                             | Private Kubernetes                                                                                            | Scaleway                                                                                                          |
| ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Read consistency · after write                                                     | strong read-after-write                                                             | strong read-after-write                                                                                                             | not documented                                                                                                | strong read-after-write                                                                            | strong read-after-write                                                                         | strict read-after-write + list-after-write                                                                    | -                                                                                                                 |
| Durability · designed-for                                                          | 11 nines (3 AZs)                                                                    | up to 16 nines (GRS)                                                                                                                | -                                                                                                             | 11 nines (erasure-coded, all classes)                                                              | 11 nines (3 ADs / 3 FDs)                                                                        | -                                                                                                             | -                                                                                                                 |
| Bucket model · structural                                                          | the bucket is the unit of configuration                                             | two-level account → container → blob                                                                                                | -                                                                                                             | -                                                                                                  | -                                                                                               | -                                                                                                             | -                                                                                                                 |
| Versioning                                                                         | Yes                                                                                 | Yes - blob versioning (enabled on the account)                                                                                      | Partial - API-managed only (absent from the DO control panel)                                                 | Yes - object versioning (noncurrent versions retained)                                             | Yes - bucket versioning (Enabled / Suspended)                                                   | Yes - bucket versioning (Enabled / Suspended)                                                                 | Yes - version ids, delete markers and ListObjectVersions all verified live                                        |
| Lifecycle policies                                                                 | Yes - tier transitions + expiration + noncurrent + abort-incomplete-multipart       | Partial - tier transitions + expiration + noncurrent, but no abort-incomplete-multipart rule                                        | -                                                                                                             | -                                                                                                  | -                                                                                               | -                                                                                                             | -                                                                                                                 |
| Event notifications                                                                | Yes - one config fans out to SNS / SQS / Lambda / EventBridge                       | Yes - one Event Grid subscription → Queue / Function / Event Hub / Service Bus / webhook                                            | -                                                                                                             | Partial - one Pub/Sub topic per notification config                                                | Partial - bucket object-events → an OCI Events rule → ONS / Streaming / Functions               | Partial - bucket events to webhook / Kafka / AMQP / NATS / Redis / PostgreSQL / MySQL / Elasticsearch targets | -                                                                                                                 |
| Server-side encryption                                                             | Yes - SSE-S3 / SSE-KMS / SSE-C / DSSE-KMS + Bucket Keys                             | Yes - Microsoft-managed, customer-managed (Key Vault CMK), infrastructure double-encryption, and per-request customer-provided keys | -                                                                                                             | -                                                                                                  | -                                                                                               | -                                                                                                             | -                                                                                                                 |
| Replication                                                                        | Yes                                                                                 | Yes - object replication (async, container → container)                                                                             | No                                                                                                            | -                                                                                                  | Yes - cross-region replication policy                                                           | -                                                                                                             | -                                                                                                                 |
| Object lock / WORM                                                                 | Yes - GOVERNANCE / COMPLIANCE modes + independent legal hold                        | Partial - native container immutability; runtime S3 retention/legal-hold calls are not served; legal-hold is not Terraform-settable | -                                                                                                             | Yes - native Bucket Lock retention and holds; runtime S3 retention/legal-hold calls are not served | Partial - native lockable retention rules; runtime S3 retention/legal-hold calls are not served | -                                                                                                             | -                                                                                                                 |
| Storage tiers                                                                      | Yes - per-object classes (Standard … Deep Archive) + Intelligent-Tiering + One-Zone | Partial - Hot / Cool / Cold / Archive access tiers; no One-Zone (single-AZ) analog                                                  | -                                                                                                             | -                                                                                                  | -                                                                                               | -                                                                                                             | -                                                                                                                 |
| CORS                                                                               | Yes                                                                                 | Yes - native account-level Blob CORS; runtime S3 CORS calls are not served; no CORS on the website endpoint                         | Yes - up to 100 rules                                                                                         | Yes - native per-bucket CORS configuration; runtime S3 CORS calls are not served                   | No - fixed allow-all, not configurable                                                          | No - Enterprise / AIStor-gated; Community returns NotImplemented                                              | -                                                                                                                 |
| Static website hosting                                                             | Yes                                                                                 | Partial - index / error documents on the account; no request-routing rules, no CORS                                                 | -                                                                                                             | Partial - index / 404 website config, but no S3-style per-bucket website endpoint host             | No                                                                                              | No                                                                                                            | -                                                                                                                 |
| Requester pays                                                                     | Yes                                                                                 | No                                                                                                                                  | -                                                                                                             | Yes - native Requester Pays flag; runtime S3 request-payment configuration is not served           | No                                                                                              | No                                                                                                            | -                                                                                                                 |
| Object tagging · granularity                                                       | per-object tags (Terraform-settable, usable in lifecycle / IAM conditions)          | blob index tags (filter / query only; not Terraform-settable)                                                                       | -                                                                                                             | -                                                                                                  | -                                                                                               | -                                                                                                             | -                                                                                                                 |
| Integrity / ETag · translator ceiling                                              | ETag = content-MD5 for single-part uploads                                          | same: content-MD5, synthesized and persisted                                                                                        | -                                                                                                             | -                                                                                                  | -                                                                                               | -                                                                                                             | -                                                                                                                 |
| Multipart upload                                                                   | Yes                                                                                 | Yes - mapped to Put Block / Put Block List                                                                                          | Yes                                                                                                           | Partial - served by compose-staging; ListMultipartUploads and UploadPartCopy decline               | -                                                                                               | Yes                                                                                                           | Yes - create/upload/complete/abort, ListParts and UploadPartCopy all verified live, with S3's composite ETag form |
| Presigned access · time-boxed URLs                                                 | presigned URLs (SDK)                                                                | outside the adapter (Azure SAS tokens, out of band)                                                                                 | outside the adapter (Spaces SigV2/V4 signed URLs, out of band)                                                | outside the adapter (GCS V4 signed URLs, out of band)                                              | -                                                                                               | outside the adapter (MinIO presign / `mc share`, out of band)                                                 | -                                                                                                                 |
| API coverage                                                                       | full                                                                                | partial                                                                                                                             | partial                                                                                                       | partial                                                                                            | partial                                                                                         | partial                                                                                                       | high                                                                                                              |
| Durability · designed-for                                                          | 11 nines (3 AZs)                                                                    | -                                                                                                                                   | no published figure                                                                                           | -                                                                                                  | -                                                                                               | deployment-specific erasure-coding protection                                                                 | -                                                                                                                 |
| Lifecycle policies                                                                 | Yes                                                                                 | -                                                                                                                                   | Partial - expiration + noncurrent expiration + abort-incomplete-multipart; no class transitions, no tag rules | Partial - prefix-scoped expiration by relative age; transitions only to STANDARD\_IA / ONEZONE\_IA | Yes - archive / infrequent-access transitions, delete, and abort-incomplete-multipart           | Yes - expiration, noncurrent-version expiration, and abort-incomplete-multipart                               | -                                                                                                                 |
| Event notifications                                                                | Yes - SNS / SQS / Lambda / EventBridge fan-out                                      | -                                                                                                                                   | No                                                                                                            | -                                                                                                  | -                                                                                               | -                                                                                                             | -                                                                                                                 |
| Server-side encryption                                                             | Yes - SSE-S3 / SSE-KMS / SSE-C / DSSE-KMS                                           | -                                                                                                                                   | Partial - SSE-C (per-request header) only                                                                     | Partial - Google-managed, customer-managed (Cloud KMS CMEK), and customer-supplied (CSEK)          | Yes - Oracle-managed, customer-managed (Vault CMK), and SSE-C                                   | Partial - SSE-S3 and SSE-KMS (via KES) plus SSE-C                                                             | Partial - SSE-S3 and SSE-C verified; SSE-KMS rejected with InvalidArgument                                        |
| Object lock / WORM                                                                 | Yes                                                                                 | -                                                                                                                                   | No                                                                                                            | -                                                                                                  | -                                                                                               | -                                                                                                             | -                                                                                                                 |
| Storage tiers                                                                      | Yes - per-object classes (Standard … Deep Archive) + Intelligent-Tiering            | -                                                                                                                                   | Partial - no per-object tiering; Cold Storage is a separate bucket type chosen at creation                    | Yes - Standard / Nearline / Coldline / Archive + Autoclass                                         | -                                                                                               | No                                                                                                            | -                                                                                                                 |
| Object tagging · granularity                                                       | per-object tags                                                                     | -                                                                                                                                   | none                                                                                                          | -                                                                                                  | -                                                                                               | -                                                                                                             | -                                                                                                                 |
| Replication                                                                        | Yes - SRR / CRR rule engine, asynchronous cross-bucket copy                         | -                                                                                                                                   | -                                                                                                             | Partial - dual / multi-region placement + turbo-replication RPO; no per-rule engine                | -                                                                                               | -                                                                                                             | -                                                                                                                 |
| Object tagging · granularity                                                       | per-object tags (usable in lifecycle / IAM conditions)                              | -                                                                                                                                   | -                                                                                                             | stored in reserved object metadata                                                                 | no object tagging; native defined/freeform tags apply only to buckets                           | -                                                                                                             | -                                                                                                                 |
| Presigned access · time-boxed URLs                                                 | presigned URLs (SDK, 7-day max)                                                     | -                                                                                                                                   | -                                                                                                             | -                                                                                                  | outside the adapter (OCI Pre-Authenticated Requests, out of band)                               | -                                                                                                             | -                                                                                                                 |
| Replication                                                                        | Yes - same-region and cross-region bucket replication rules                         | -                                                                                                                                   | -                                                                                                             | -                                                                                                  | -                                                                                               | Yes - active-active bucket replication + site replication (whole deployment, incl. IAM / users / policies)    | -                                                                                                                 |
| Object lock / WORM                                                                 | Yes - GOVERNANCE / COMPLIANCE modes + retention + independent legal hold            | -                                                                                                                                   | -                                                                                                             | -                                                                                                  | -                                                                                               | Partial - native to MinIO, but the adapter does not forward the runtime retention / legal-hold verbs          | -                                                                                                                 |
| Object tagging                                                                     | Yes                                                                                 | -                                                                                                                                   | -                                                                                                             | -                                                                                                  | -                                                                                               | Yes - true per-object tags (get / put / delete)                                                               | -                                                                                                                 |
| Content-MD5 request validation · corrupt-upload rejection, restored by the adapter | wrong digest → 400 BadDigest                                                        | -                                                                                                                                   | -                                                                                                             | -                                                                                                  | -                                                                                               | -                                                                                                             | wrong digest → 400 BadDigest, checked by the adapter                                                              |

## On Azure

### Blob Storage

| Capability                                                      | Area           | Support      | Operations | Notes                                                                                                                                                                                                                                                     |
| --------------------------------------------------------------- | -------------- | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Bucket policy, CORS, website, notification and replication APIs | Bucket config  | Out of scope | -          | These runtime S3 configuration APIs are outside the listed endpoint. Native target configuration and deployment mappings are described separately.                                                                                                        |
| Bucket versioning, tagging, lifecycle and encryption            | Bucket config  | Partial      | -          | At Max, runtime S3 calls retain bucket settings and apply supported target mappings. Lifecycle filters, storage classes and account-level settings retain the limits described below. Simpler request forwarding configures these settings at deployment. |
| Presigned URLs                                                  | Other features | Out of scope | -          | S3 presigned URLs aren't honored: the adapter re-signs to the backend and does not validate the client's presigned signature, so its expiry/scope guarantees aren't enforced.                                                                             |

| Operation               | Area           | Support        | Depth        | Notes                                                                                                                                                                                                                                                                                             |
| ----------------------- | -------------- | -------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GetObjectAcl            | Access control | Out of scope   | Full surface | Object ACL requests are rejected. Configure access through target permissions or deployment configuration.                                                                                                                                                                                        |
| PutObjectAcl            | Access control | Out of scope   | Full surface | Object ACL requests are rejected. Configure access through target permissions or deployment configuration.                                                                                                                                                                                        |
| CreateBucket            | Bucket config  | Supported      | Most usage   | the container is the bucket                                                                                                                                                                                                                                                                       |
| DeleteBucket            | Bucket config  | Supported      | Most usage   | the container is the bucket                                                                                                                                                                                                                                                                       |
| HeadBucket              | Bucket config  | Supported      | Most usage   | the container is the bucket                                                                                                                                                                                                                                                                       |
| AbortMultipartUpload    | Multipart      | Supported      | Most usage   | accepted; uncommitted blocks are left to Azure's 7-day cleanup                                                                                                                                                                                                                                    |
| CompleteMultipartUpload | Multipart      | Supported      | Most usage   | Put Block List                                                                                                                                                                                                                                                                                    |
| CreateMultipartUpload   | Multipart      | Supported      | Most usage   | mapped to Put Block / Put Block List                                                                                                                                                                                                                                                              |
| ListMultipartUploads    | Multipart      | Out of scope   | Most usage   | Azure has no UploadId / cross-blob in-progress-upload listing, so the adapter returns 501                                                                                                                                                                                                         |
| ListParts               | Multipart      | Partial        | Most usage   | the uncommitted block list: PartNumber + Size only, no per-part ETag / LastModified                                                                                                                                                                                                               |
| UploadPart              | Multipart      | Supported      | Most usage   | Put Block                                                                                                                                                                                                                                                                                         |
| GetObjectLegalHold      | Object lock    | Out of scope   | Full surface | the object-lock sub-resources are rejected                                                                                                                                                                                                                                                        |
| GetObjectRetention      | Object lock    | Out of scope   | Full surface | the object-lock sub-resources are rejected                                                                                                                                                                                                                                                        |
| PutObjectLegalHold      | Object lock    | Out of scope   | Full surface | the object-lock sub-resources are rejected                                                                                                                                                                                                                                                        |
| PutObjectRetention      | Object lock    | Out of scope   | Full surface | the object-lock sub-resources are rejected                                                                                                                                                                                                                                                        |
| CopyObject              | Objects        | Partial        | Most usage   | download-then-upload, not server-side; copy-source conditionals are not honored                                                                                                                                                                                                                   |
| DeleteObject            | Objects        | Supported      | Common       | idempotent                                                                                                                                                                                                                                                                                        |
| DeleteObjects           | Objects        | Partial        | Common       | the batch form is served as per-key deletes (N round-trips)                                                                                                                                                                                                                                       |
| GetObject               | Objects        | Supported      | Common       | bodies stream; start/open-ended byte ranges honored (suffix and multi-range fall back to a full download)                                                                                                                                                                                         |
| HeadObject              | Objects        | Supported      | Common       | metadata / size / ETag without a body                                                                                                                                                                                                                                                             |
| ListObjectVersions      | Objects        | Partial        | Most usage   | Native Blob versions use timestamp identifiers and continuation markers. Max adds S3 version metadata and delete-marker behavior; native account-level versioning settings still apply.                                                                                                           |
| ListObjects             | Objects        | Supported      | Common       | the v1 listing form                                                                                                                                                                                                                                                                               |
| ListObjectsV2           | Objects        | Supported      | Common       | flat listing with prefix + paging; delimiter/CommonPrefixes hierarchical listing is not served                                                                                                                                                                                                    |
| PutObject               | Objects        | Supported      | Common       | single-shot to 5000 MiB. The ETag a single-part write returns is S3's: the hex MD5 of the body, computed on the write and persisted as the blob's native Content-MD5 so reads render the same value. Azure's own blob ETag is an opaque change-counter and is deliberately not what a client sees |
| GetObjectAttributes     | Other features | Out of scope   | Full surface | the ?attributes query is not served; use HeadObject                                                                                                                                                                                                                                               |
| RestoreObject           | Other features | Out of scope   | Full surface | the ?restore query is rejected                                                                                                                                                                                                                                                                    |
| SelectObjectContent     | Other features | Out of scope   | Full surface | the ?select query is rejected                                                                                                                                                                                                                                                                     |
| DeleteObjectTagging     | Tagging        | Adapter-served | Most usage   | via Blob Index Tags                                                                                                                                                                                                                                                                               |
| GetObjectTagging        | Tagging        | Adapter-served | Most usage   | via Blob Index Tags                                                                                                                                                                                                                                                                               |
| PutObjectTagging        | Tagging        | Adapter-served | Most usage   | via Blob Index Tags; rejects @ / non-ASCII per Azure's tag charset                                                                                                                                                                                                                                |

#### S3 requests in the target environment

The application continues using the S3 API. The Tensor9 adapter runs in the target environment and sends object requests to Azure Blob Storage. It also serves bucket creation, deletion, listing, and configuration through a persistent bucket store. Azure Blob Storage stores the objects; Tensor9 operates the adapter and its bucket-management service.

#### Request flow

Object requests use the target storage service. Bucket settings persist separately and are applied to the target resource.

<div className="t9-diagram-scroll" role="region" aria-label="Scrollable diagram" tabIndex={0}>
  <img className="t9-diagram-light" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjI4OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDI4OCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgUzMgYXBwbGljYXRpb24gY2FsbHMgdGhlIFRlbnNvcjkgYWRhcHRlci4gT2JqZWN0IHJlcXVlc3RzIGdvIHRvIHRoZSB0YXJnZXQgb2JqZWN0IHN0b3JlLiBCdWNrZXQgc2V0dGluZ3MgcGVyc2lzdCBpbiB0aGUgYWRhcHRlcidzIHN0b3JlIGFuZCBhIGNvbmZpZ3VyYXRpb24gd29ya2VyIGFwcGxpZXMgdGhlbSB0byB0aGUgdGFyZ2V0LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgogIDxkZWZzPjxtYXJrZXIgaWQ9InMzLW1heC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI4NCIgcng9IjEwIiBmaWxsPSIjZWZmNmZmIiBzdHJva2U9IiM5M2M1ZmQiLz4KICA8cmVjdCB4PSIzMTAiIHk9IjM2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9Ijg0IiByeD0iMTAiIGZpbGw9IiNlY2ZkZjUiIHN0cm9rZT0iIzZlZTdiNyIvPgogIDxyZWN0IHg9IjU5NiIgeT0iMzYiIHdpZHRoPSIyMjAiIGhlaWdodD0iODQiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjOTRhM2I4Ii8+CiAgPHJlY3QgeD0iMzEwIiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iI2VjZmRmNSIgc3Ryb2tlPSIjNmVlN2I3Ii8+CiAgPHJlY3QgeD0iNTk2IiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjOTRhM2I4Ii8+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE2IiBmaWxsPSIjMGYxNzJhIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj4KICAgIDx0ZXh0IHg9IjEzNCIgeT0iNzAiPkFwcGxpY2F0aW9uPC90ZXh0Pjx0ZXh0IHg9IjEzNCIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPlMzIFNESzwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iNzAiPlRlbnNvcjkgUzMgYWRhcHRlcjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3QgYW5kIGJ1Y2tldCBBUElzPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSI3MCI+QXp1cmUgQmxvYiBTdG9yYWdlPC90ZXh0Pjx0ZXh0IHg9IjcwNiIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPk9iamVjdHMgYW5kIHN0b3JhZ2U8L3RleHQ+CiAgICA8dGV4dCB4PSI0MjAiIHk9IjIxMiI+UGVyc2lzdGVudCBidWNrZXQgc3RvcmU8L3RleHQ+PHRleHQgeD0iNDIwIiB5PSIyMzYiIGZvbnQtc2l6ZT0iMTQiPk5hbWVzIGFuZCBjb25maWd1cmF0aW9uPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSIyMjQiPkNvbmZpZ3VyYXRpb24gd29ya2VyPC90ZXh0PgogIDwvZz4KICA8ZyBzdHJva2U9IiM2NDc0OGIiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0ibm9uZSIgbWFya2VyLWVuZD0idXJsKCNzMy1tYXgtYXJyb3cpIj4KICAgIDxwYXRoIGQ9Ik0yNDQgNzggSDMwNiIvPjxwYXRoIGQ9Ik01MzAgNzggSDU5MiIvPjxwYXRoIGQ9Ik00MjAgMTIwIFYxODAiLz4KICAgIDxwYXRoIGQ9Ik01MzAgMjE4IEg1OTIiLz48cGF0aCBkPSJNNzA2IDE4NCBWMTI0Ii8+CiAgPC9nPgogIDxnIGZvbnQtZmFtaWx5PSJzeXN0ZW0tdWksc2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMiIgZmlsbD0iIzQ3NTU2OSI+CiAgICA8dGV4dCB4PSI0MzIiIHk9IjE1MyI+QnVja2V0IHNldHRpbmdzPC90ZXh0Pjx0ZXh0IHg9IjcxOCIgeT0iMTU0Ij5BcHBseTwvdGV4dD4KICA8L2c+Cjwvc3ZnPg==" alt="The S3 application calls the Tensor9 adapter. Object requests go to the target object store. Bucket settings persist in the adapter's store and a configuration worker applies them to the target." />

  <img className="t9-diagram-dark" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjI4OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDI4OCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgUzMgYXBwbGljYXRpb24gY2FsbHMgdGhlIFRlbnNvcjkgYWRhcHRlci4gT2JqZWN0IHJlcXVlc3RzIGdvIHRvIHRoZSB0YXJnZXQgb2JqZWN0IHN0b3JlLiBCdWNrZXQgc2V0dGluZ3MgcGVyc2lzdCBpbiB0aGUgYWRhcHRlcidzIHN0b3JlIGFuZCBhIGNvbmZpZ3VyYXRpb24gd29ya2VyIGFwcGxpZXMgdGhlbSB0byB0aGUgdGFyZ2V0LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgogIDxkZWZzPjxtYXJrZXIgaWQ9InMzLW1heC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI4NCIgcng9IjEwIiBmaWxsPSIjMWEyNDMxIiBzdHJva2U9IiMzZDUwNjYiLz4KICA8cmVjdCB4PSIzMTAiIHk9IjM2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9Ijg0IiByeD0iMTAiIGZpbGw9IiMxYTMxMjYiIHN0cm9rZT0iIzNkNjY1NSIvPgogIDxyZWN0IHg9IjU5NiIgeT0iMzYiIHdpZHRoPSIyMjAiIGhlaWdodD0iODQiIHJ4PSIxMCIgZmlsbD0iIzFhMjYzMSIgc3Ryb2tlPSIjNDE0ZTYyIi8+CiAgPHJlY3QgeD0iMzEwIiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iIzFhMzEyNiIgc3Ryb2tlPSIjM2Q2NjU1Ii8+CiAgPHJlY3QgeD0iNTk2IiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iIzFhMjYzMSIgc3Ryb2tlPSIjNDE0ZTYyIi8+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE2IiBmaWxsPSIjNTU3NmMyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj4KICAgIDx0ZXh0IHg9IjEzNCIgeT0iNzAiPkFwcGxpY2F0aW9uPC90ZXh0Pjx0ZXh0IHg9IjEzNCIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPlMzIFNESzwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iNzAiPlRlbnNvcjkgUzMgYWRhcHRlcjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3QgYW5kIGJ1Y2tldCBBUElzPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSI3MCI+QXp1cmUgQmxvYiBTdG9yYWdlPC90ZXh0Pjx0ZXh0IHg9IjcwNiIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPk9iamVjdHMgYW5kIHN0b3JhZ2U8L3RleHQ+CiAgICA8dGV4dCB4PSI0MjAiIHk9IjIxMiI+UGVyc2lzdGVudCBidWNrZXQgc3RvcmU8L3RleHQ+PHRleHQgeD0iNDIwIiB5PSIyMzYiIGZvbnQtc2l6ZT0iMTQiPk5hbWVzIGFuZCBjb25maWd1cmF0aW9uPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSIyMjQiPkNvbmZpZ3VyYXRpb24gd29ya2VyPC90ZXh0PgogIDwvZz4KICA8ZyBzdHJva2U9IiM2NDc0OGIiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0ibm9uZSIgbWFya2VyLWVuZD0idXJsKCNzMy1tYXgtYXJyb3cpIj4KICAgIDxwYXRoIGQ9Ik0yNDQgNzggSDMwNiIvPjxwYXRoIGQ9Ik01MzAgNzggSDU5MiIvPjxwYXRoIGQ9Ik00MjAgMTIwIFYxODAiLz4KICAgIDxwYXRoIGQ9Ik01MzAgMjE4IEg1OTIiLz48cGF0aCBkPSJNNzA2IDE4NCBWMTI0Ii8+CiAgPC9nPgogIDxnIGZvbnQtZmFtaWx5PSJzeXN0ZW0tdWksc2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMiIgZmlsbD0iIzc2ODhhMiI+CiAgICA8dGV4dCB4PSI0MzIiIHk9IjE1MyI+QnVja2V0IHNldHRpbmdzPC90ZXh0Pjx0ZXh0IHg9IjcxOCIgeT0iMTU0Ij5BcHBseTwvdGV4dD4KICA8L2c+Cjwvc3ZnPg==" alt="The S3 application calls the Tensor9 adapter. Object requests go to the target object store. Bucket settings persist in the adapter's store and a configuration worker applies them to the target." />
</div>

#### Object requests

Azure Blob uses its own API, so the adapter translates S3 requests, headers, XML results and errors into Blob operations. It streams reads and writes, maps object tags to Blob Index Tags, and handles batch deletion as individual blob deletes. CopyObject downloads and uploads the object rather than using a server-side copy. Flat listing supports prefixes and pagination; delimiter/CommonPrefixes grouping is outside the listed mapping.

#### Bucket creation and configuration

Each S3 bucket has a durable record containing its name, owner, requested configuration, and target reference. For a bucket named `bucket-name`, the S3-facing identifier is `arn:aws:s3:::bucket-name`; the target resource is a Blob container in a selected storage account. `ListBuckets` returns the caller's buckets, and configuration reads use the stored request state.

A configuration worker applies the stored settings to the target. `CreateBucket` waits for the target bucket to be ready before returning success, so an immediate object write does not race bucket creation. `DeleteBucket` waits for removal and returns `BucketNotEmpty` if objects prevent deletion. A lifecycle update also waits for target application. For other configuration changes, a successful read of the new setting describes stored configuration; it does not imply every target-side change has already completed.

#### Versions and multipart uploads

Multipart uploads store parts as Azure blocks and commit a block list at completion. Max retains the part checksums and S3 version metadata needed for composite multipart ETags, S3 version IDs and delete markers. The simpler request-translation path uses Azure's native version and completion-ETag behavior instead. Single-part writes compute the content MD5 and persist it as Blob Content-MD5. Azure tag-character restrictions still apply, including rejection of @ and non-ASCII characters.

#### Target configuration

The adapter stores per-bucket configuration and reconciles each bucket to a container. Several Azure settings belong to the storage account, including region, redundancy, native versioning and default encryption; a container cannot independently choose them. Shared-account configuration must be planned for all buckets using that account. S3 lifecycle settings use the supported target mappings, and unsupported conditions must not change retention behavior silently. Max supplies S3 metadata where native account-level behavior alone is insufficient.

#### Placement and operation

Azure provides strong consistency. Its documented durability depends on redundancy: 11 nines for LRS, 12 for ZRS, and 16 for GRS or GZRS. Choose the account region and redundancy to meet the customer's placement and recovery needs. A bucket's S3 location field does not relocate the storage account. Tensor9 operates the adapter and persistent bucket state; Microsoft operates Blob Storage.

#### Compatibility limits

Bucket policy remains unsupported. The listed object API still has copy-source conditional and hierarchical-listing limits, and suffix or multiple byte ranges use a full-download fallback. A single PutObject is limited to 5000 MiB on this path. Azure has no S3 Requester Pays or direct One Zone storage-class equivalent. Object retention and legal-hold capabilities must be evaluated separately from the runtime APIs this mapping serves.

#### Migration and leaving the adapter

A newly provisioned target bucket starts empty. Copy existing objects and required versions with a migration tool or a coordinated dual-write, then verify object data and application reads before switching. Preserve version history through the S3 API when the application depends on S3 version identifiers or delete markers.

Leaving the Max adapter requires moving bucket configuration as well as object data. Apply the retained settings to native target resources, resolve any S3-specific version metadata, and move clients to the target's own API. Keep the adapter and its persistent state until the application no longer depends on those S3 behaviors.

## On DigitalOcean

### DigitalOcean Spaces

| Capability                                                      | Area           | Support      | Operations | Notes                                                                                                                                                                                                                                                     |
| --------------------------------------------------------------- | -------------- | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Bucket policy, CORS, website, notification and replication APIs | Bucket config  | Out of scope | -          | These runtime S3 configuration APIs are outside the listed endpoint. Native target configuration and deployment mappings are described separately.                                                                                                        |
| Bucket versioning, tagging, lifecycle and encryption            | Bucket config  | Partial      | -          | At Max, runtime S3 calls retain bucket settings and apply supported target mappings. Lifecycle filters, storage classes and account-level settings retain the limits described below. Simpler request forwarding configures these settings at deployment. |
| Presigned URLs                                                  | Other features | Out of scope | -          | S3 presigned URLs aren't honored: the adapter re-signs to the backend and does not validate the client's presigned signature, so its expiry/scope guarantees aren't enforced.                                                                             |

| Operation               | Area           | Support      | Depth        | Notes                                                                                                      |
| ----------------------- | -------------- | ------------ | ------------ | ---------------------------------------------------------------------------------------------------------- |
| GetObjectAcl            | Access control | Out of scope | Full surface | Object ACL requests are rejected. Configure access through target permissions or deployment configuration. |
| PutObjectAcl            | Access control | Out of scope | Full surface | Object ACL requests are rejected. Configure access through target permissions or deployment configuration. |
| CreateBucket            | Bucket config  | Supported    | Most usage   | The adapter serves this bucket operation.                                                                  |
| DeleteBucket            | Bucket config  | Supported    | Most usage   | The adapter serves this bucket operation.                                                                  |
| HeadBucket              | Bucket config  | Supported    | Most usage   | The adapter serves this bucket operation.                                                                  |
| AbortMultipartUpload    | Multipart      | Supported    | Most usage   | -                                                                                                          |
| CompleteMultipartUpload | Multipart      | Supported    | Most usage   | -                                                                                                          |
| CreateMultipartUpload   | Multipart      | Supported    | Most usage   | -                                                                                                          |
| ListMultipartUploads    | Multipart      | Supported    | Most usage   | -                                                                                                          |
| ListParts               | Multipart      | Supported    | Most usage   | -                                                                                                          |
| UploadPart              | Multipart      | Supported    | Most usage   | -                                                                                                          |
| GetObjectLegalHold      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                 |
| GetObjectRetention      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                 |
| PutObjectLegalHold      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                 |
| PutObjectRetention      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                 |
| CopyObject              | Objects        | Supported    | Most usage   | server-side copy via x-amz-copy-source                                                                     |
| DeleteObject            | Objects        | Supported    | Common       | -                                                                                                          |
| DeleteObjects           | Objects        | Supported    | Common       | batch delete                                                                                               |
| GetObject               | Objects        | Supported    | Common       | bodies + byte ranges                                                                                       |
| HeadObject              | Objects        | Supported    | Common       | -                                                                                                          |
| ListObjectVersions      | Objects        | Supported    | Most usage   | Spaces supports bucket versioning and list-object-versions                                                 |
| ListObjects             | Objects        | Supported    | Common       | the v1 listing form                                                                                        |
| ListObjectsV2           | Objects        | Supported    | Common       | -                                                                                                          |
| PutObject               | Objects        | Supported    | Common       | -                                                                                                          |
| GetObjectAttributes     | Other features | Out of scope | Full surface | the ?attributes query is not served; use HeadObject                                                        |
| RestoreObject           | Other features | Out of scope | Full surface | the ?restore query is rejected                                                                             |
| SelectObjectContent     | Other features | Out of scope | Full surface | the ?select query is rejected                                                                              |
| DeleteObjectTagging     | Tagging        | Out of scope | Most usage   | Spaces returns NotImplemented for object tagging                                                           |
| GetObjectTagging        | Tagging        | Out of scope | Most usage   | Spaces returns NotImplemented for object tagging                                                           |
| PutObjectTagging        | Tagging        | Out of scope | Most usage   | Spaces returns NotImplemented for object tagging                                                           |

#### S3 requests in the target environment

The application continues using the S3 API. The Tensor9 adapter runs in the target environment and sends object requests to DigitalOcean Spaces. It also serves bucket creation, deletion, listing, and configuration through a persistent bucket store. DigitalOcean Spaces stores the objects; Tensor9 operates the adapter and its bucket-management service.

#### Request flow

Object requests use the target storage service. Bucket settings persist separately and are applied to the target resource.

<div className="t9-diagram-scroll" role="region" aria-label="Scrollable diagram" tabIndex={0}>
  <img className="t9-diagram-light" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjI4OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDI4OCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgUzMgYXBwbGljYXRpb24gY2FsbHMgdGhlIFRlbnNvcjkgYWRhcHRlci4gT2JqZWN0IHJlcXVlc3RzIGdvIHRvIHRoZSB0YXJnZXQgb2JqZWN0IHN0b3JlLiBCdWNrZXQgc2V0dGluZ3MgcGVyc2lzdCBpbiB0aGUgYWRhcHRlcidzIHN0b3JlIGFuZCBhIGNvbmZpZ3VyYXRpb24gd29ya2VyIGFwcGxpZXMgdGhlbSB0byB0aGUgdGFyZ2V0LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgogIDxkZWZzPjxtYXJrZXIgaWQ9InMzLW1heC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI4NCIgcng9IjEwIiBmaWxsPSIjZWZmNmZmIiBzdHJva2U9IiM5M2M1ZmQiLz4KICA8cmVjdCB4PSIzMTAiIHk9IjM2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9Ijg0IiByeD0iMTAiIGZpbGw9IiNlY2ZkZjUiIHN0cm9rZT0iIzZlZTdiNyIvPgogIDxyZWN0IHg9IjU5NiIgeT0iMzYiIHdpZHRoPSIyMjAiIGhlaWdodD0iODQiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjOTRhM2I4Ii8+CiAgPHJlY3QgeD0iMzEwIiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iI2VjZmRmNSIgc3Ryb2tlPSIjNmVlN2I3Ii8+CiAgPHJlY3QgeD0iNTk2IiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjOTRhM2I4Ii8+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE2IiBmaWxsPSIjMGYxNzJhIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj4KICAgIDx0ZXh0IHg9IjEzNCIgeT0iNzAiPkFwcGxpY2F0aW9uPC90ZXh0Pjx0ZXh0IHg9IjEzNCIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPlMzIFNESzwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iNzAiPlRlbnNvcjkgUzMgYWRhcHRlcjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3QgYW5kIGJ1Y2tldCBBUElzPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSI3MCI+RGlnaXRhbE9jZWFuIFNwYWNlczwvdGV4dD48dGV4dCB4PSI3MDYiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3RzIGFuZCBzdG9yYWdlPC90ZXh0PgogICAgPHRleHQgeD0iNDIwIiB5PSIyMTIiPlBlcnNpc3RlbnQgYnVja2V0IHN0b3JlPC90ZXh0Pjx0ZXh0IHg9IjQyMCIgeT0iMjM2IiBmb250LXNpemU9IjE0Ij5OYW1lcyBhbmQgY29uZmlndXJhdGlvbjwvdGV4dD4KICAgIDx0ZXh0IHg9IjcwNiIgeT0iMjI0Ij5Db25maWd1cmF0aW9uIHdvcmtlcjwvdGV4dD4KICA8L2c+CiAgPGcgc3Ryb2tlPSIjNjQ3NDhiIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiIG1hcmtlci1lbmQ9InVybCgjczMtbWF4LWFycm93KSI+CiAgICA8cGF0aCBkPSJNMjQ0IDc4IEgzMDYiLz48cGF0aCBkPSJNNTMwIDc4IEg1OTIiLz48cGF0aCBkPSJNNDIwIDEyMCBWMTgwIi8+CiAgICA8cGF0aCBkPSJNNTMwIDIxOCBINTkyIi8+PHBhdGggZD0iTTcwNiAxODQgVjEyNCIvPgogIDwvZz4KICA8ZyBmb250LWZhbWlseT0ic3lzdGVtLXVpLHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTIiIGZpbGw9IiM0NzU1NjkiPgogICAgPHRleHQgeD0iNDMyIiB5PSIxNTMiPkJ1Y2tldCBzZXR0aW5nczwvdGV4dD48dGV4dCB4PSI3MTgiIHk9IjE1NCI+QXBwbHk8L3RleHQ+CiAgPC9nPgo8L3N2Zz4=" alt="The S3 application calls the Tensor9 adapter. Object requests go to the target object store. Bucket settings persist in the adapter's store and a configuration worker applies them to the target." />

  <img className="t9-diagram-dark" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjI4OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDI4OCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgUzMgYXBwbGljYXRpb24gY2FsbHMgdGhlIFRlbnNvcjkgYWRhcHRlci4gT2JqZWN0IHJlcXVlc3RzIGdvIHRvIHRoZSB0YXJnZXQgb2JqZWN0IHN0b3JlLiBCdWNrZXQgc2V0dGluZ3MgcGVyc2lzdCBpbiB0aGUgYWRhcHRlcidzIHN0b3JlIGFuZCBhIGNvbmZpZ3VyYXRpb24gd29ya2VyIGFwcGxpZXMgdGhlbSB0byB0aGUgdGFyZ2V0LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgogIDxkZWZzPjxtYXJrZXIgaWQ9InMzLW1heC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI4NCIgcng9IjEwIiBmaWxsPSIjMWEyNDMxIiBzdHJva2U9IiMzZDUwNjYiLz4KICA8cmVjdCB4PSIzMTAiIHk9IjM2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9Ijg0IiByeD0iMTAiIGZpbGw9IiMxYTMxMjYiIHN0cm9rZT0iIzNkNjY1NSIvPgogIDxyZWN0IHg9IjU5NiIgeT0iMzYiIHdpZHRoPSIyMjAiIGhlaWdodD0iODQiIHJ4PSIxMCIgZmlsbD0iIzFhMjYzMSIgc3Ryb2tlPSIjNDE0ZTYyIi8+CiAgPHJlY3QgeD0iMzEwIiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iIzFhMzEyNiIgc3Ryb2tlPSIjM2Q2NjU1Ii8+CiAgPHJlY3QgeD0iNTk2IiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iIzFhMjYzMSIgc3Ryb2tlPSIjNDE0ZTYyIi8+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE2IiBmaWxsPSIjNTU3NmMyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj4KICAgIDx0ZXh0IHg9IjEzNCIgeT0iNzAiPkFwcGxpY2F0aW9uPC90ZXh0Pjx0ZXh0IHg9IjEzNCIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPlMzIFNESzwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iNzAiPlRlbnNvcjkgUzMgYWRhcHRlcjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3QgYW5kIGJ1Y2tldCBBUElzPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSI3MCI+RGlnaXRhbE9jZWFuIFNwYWNlczwvdGV4dD48dGV4dCB4PSI3MDYiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3RzIGFuZCBzdG9yYWdlPC90ZXh0PgogICAgPHRleHQgeD0iNDIwIiB5PSIyMTIiPlBlcnNpc3RlbnQgYnVja2V0IHN0b3JlPC90ZXh0Pjx0ZXh0IHg9IjQyMCIgeT0iMjM2IiBmb250LXNpemU9IjE0Ij5OYW1lcyBhbmQgY29uZmlndXJhdGlvbjwvdGV4dD4KICAgIDx0ZXh0IHg9IjcwNiIgeT0iMjI0Ij5Db25maWd1cmF0aW9uIHdvcmtlcjwvdGV4dD4KICA8L2c+CiAgPGcgc3Ryb2tlPSIjNjQ3NDhiIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiIG1hcmtlci1lbmQ9InVybCgjczMtbWF4LWFycm93KSI+CiAgICA8cGF0aCBkPSJNMjQ0IDc4IEgzMDYiLz48cGF0aCBkPSJNNTMwIDc4IEg1OTIiLz48cGF0aCBkPSJNNDIwIDEyMCBWMTgwIi8+CiAgICA8cGF0aCBkPSJNNTMwIDIxOCBINTkyIi8+PHBhdGggZD0iTTcwNiAxODQgVjEyNCIvPgogIDwvZz4KICA8ZyBmb250LWZhbWlseT0ic3lzdGVtLXVpLHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTIiIGZpbGw9IiM3Njg4YTIiPgogICAgPHRleHQgeD0iNDMyIiB5PSIxNTMiPkJ1Y2tldCBzZXR0aW5nczwvdGV4dD48dGV4dCB4PSI3MTgiIHk9IjE1NCI+QXBwbHk8L3RleHQ+CiAgPC9nPgo8L3N2Zz4=" alt="The S3 application calls the Tensor9 adapter. Object requests go to the target object store. Bucket settings persist in the adapter's store and a configuration worker applies them to the target." />
</div>

#### Object requests

Spaces speaks the S3 protocol. The adapter changes the endpoint and signs with a Spaces access key, while the service handles objects, ranges, copies, batch deletion and paginated listing in both the v1 and v2 listing forms. The endpoint uses the selected region, such as nyc3.digitaloceanspaces.com. The adapter still provides the S3 endpoint expected by the application.

#### Bucket creation and configuration

Each S3 bucket has a durable record containing its name, owner, requested configuration, and target reference. For a bucket named `bucket-name`, the S3-facing identifier is `arn:aws:s3:::bucket-name`; the target resource is a DigitalOcean Spaces bucket. `ListBuckets` returns the caller's buckets, and configuration reads use the stored request state.

A configuration worker applies the stored settings to the target. `CreateBucket` waits for the target bucket to be ready before returning success, so an immediate object write does not race bucket creation. `DeleteBucket` waits for removal and returns `BucketNotEmpty` if objects prevent deletion. A lifecycle update also waits for target application. For other configuration changes, a successful read of the new setting describes stored configuration; it does not imply every target-side change has already completed.

#### Versions and multipart uploads

Spaces supplies bucket versioning, ListObjectVersions and the full multipart set natively: CreateMultipartUpload, UploadPart, ListParts, ListMultipartUploads, CompleteMultipartUpload and AbortMultipartUpload. Max retains those provider behaviors and adds the persistent bucket-management service on top of them.

#### Target configuration

The Max adapter stores bucket ownership and requested configuration, then reconciles that state to Spaces. Bucket creation, deletion and head already have native operations the adapter serves at the baseline tier; the persistent record gives the application the same management model used with the other targets.

#### Placement and operation

DigitalOcean operates the object store; Tensor9 operates the S3 adapter and its persistent bucket-management service. The Spaces key pair is not the DigitalOcean API token: Spaces mints its own, and both the object and bucket planes sign with that same Spaces pair.

#### Compatibility limits

Object tagging is unsupported upstream: GetObjectTagging, PutObjectTagging and DeleteObjectTagging return NotImplemented from Spaces, and object tagging is not served on this edge. Bucket versioning is the one configuration the adapter applies to Spaces; bucket tagging, lifecycle and encryption settings are held by the management service and answered from that record, and do not reach the provider. Read-after-write consistency is not documented by the provider. Bucket policy, CORS, website, notification and replication remain outside this mapping. The Max management service does not by itself remove these operation-level differences.

#### Migration and leaving the adapter

A newly provisioned target bucket starts empty. Copy existing objects and required versions with a migration tool or a coordinated dual-write, then verify object data and application reads before switching. Preserve version history through the S3 API when the application depends on S3 version identifiers or delete markers.

Leaving the Max adapter requires moving bucket configuration as well as object data. Apply the retained settings to native target resources, resolve any S3-specific version metadata, and move clients to the target's own API. Keep the adapter and its persistent state until the application no longer depends on those S3 behaviors.

## On Google Cloud

### Cloud Storage

| Capability                                                      | Area           | Support      | Operations | Notes                                                                                                                                                                                                                                                     |
| --------------------------------------------------------------- | -------------- | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Bucket policy, CORS, website, notification and replication APIs | Bucket config  | Out of scope | -          | These runtime S3 configuration APIs are outside the listed endpoint. Native target configuration and deployment mappings are described separately.                                                                                                        |
| Bucket versioning, tagging, lifecycle and encryption            | Bucket config  | Partial      | -          | At Max, runtime S3 calls retain bucket settings and apply supported target mappings. Lifecycle filters, storage classes and account-level settings retain the limits described below. Simpler request forwarding configures these settings at deployment. |
| Presigned URLs                                                  | Other features | Out of scope | -          | S3 presigned URLs aren't honored: the adapter re-signs to the backend and does not validate the client's presigned signature, so its expiry/scope guarantees aren't enforced.                                                                             |

| Operation               | Area           | Support        | Depth        | Notes                                                                                                                                                                                                                                                                                                                                               |
| ----------------------- | -------------- | -------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GetObjectAcl            | Access control | Out of scope   | Full surface | Object ACL requests are rejected. Configure access through target permissions or deployment configuration.                                                                                                                                                                                                                                          |
| PutObjectAcl            | Access control | Out of scope   | Full surface | Object ACL requests are rejected. Configure access through target permissions or deployment configuration.                                                                                                                                                                                                                                          |
| CreateBucket            | Bucket config  | Supported      | Most usage   | The adapter serves this bucket operation.                                                                                                                                                                                                                                                                                                           |
| DeleteBucket            | Bucket config  | Supported      | Most usage   | The adapter serves this bucket operation.                                                                                                                                                                                                                                                                                                           |
| HeadBucket              | Bucket config  | Supported      | Most usage   | The adapter serves this bucket operation.                                                                                                                                                                                                                                                                                                           |
| AbortMultipartUpload    | Multipart      | Supported      | Most usage   | served by compose-staging rather than by forwarding, because GCS's own XML multipart wire is not S3-identical: each part streams to a temp object and CompleteMultipartUpload composes them with the GCS JSON compose API, so an unmodified SDK's multipart upload works end to end                                                                 |
| CompleteMultipartUpload | Multipart      | Supported      | Most usage   | served by compose-staging rather than by forwarding, because GCS's own XML multipart wire is not S3-identical: each part streams to a temp object and CompleteMultipartUpload composes them with the GCS JSON compose API, so an unmodified SDK's multipart upload works end to end                                                                 |
| CreateMultipartUpload   | Multipart      | Supported      | Most usage   | served by compose-staging rather than by forwarding, because GCS's own XML multipart wire is not S3-identical: each part streams to a temp object and CompleteMultipartUpload composes them with the GCS JSON compose API, so an unmodified SDK's multipart upload works end to end                                                                 |
| ListMultipartUploads    | Multipart      | Out of scope   | Most usage   | compose-staging keys an upload's parts under a per-key prefix and keeps no bucket-wide uploadId registry, so a bucket's in-progress uploads cannot be enumerated; the Azure translator declines it for the same reason                                                                                                                              |
| ListParts               | Multipart      | Supported      | Most usage   | served by compose-staging rather than by forwarding, because GCS's own XML multipart wire is not S3-identical: each part streams to a temp object and CompleteMultipartUpload composes them with the GCS JSON compose API, so an unmodified SDK's multipart upload works end to end                                                                 |
| UploadPart              | Multipart      | Supported      | Most usage   | served by compose-staging rather than by forwarding, because GCS's own XML multipart wire is not S3-identical: each part streams to a temp object and CompleteMultipartUpload composes them with the GCS JSON compose API, so an unmodified SDK's multipart upload works end to end                                                                 |
| UploadPartCopy          | Multipart      | Out of scope   | Full surface | the copy-source range form is declined on this backend                                                                                                                                                                                                                                                                                              |
| GetObjectLegalHold      | Object lock    | Out of scope   | Full surface | the object-lock sub-resources are rejected                                                                                                                                                                                                                                                                                                          |
| GetObjectRetention      | Object lock    | Out of scope   | Full surface | the object-lock sub-resources are rejected                                                                                                                                                                                                                                                                                                          |
| PutObjectLegalHold      | Object lock    | Out of scope   | Full surface | the object-lock sub-resources are rejected                                                                                                                                                                                                                                                                                                          |
| PutObjectRetention      | Object lock    | Out of scope   | Full surface | the object-lock sub-resources are rejected                                                                                                                                                                                                                                                                                                          |
| CopyObject              | Objects        | Supported      | Most usage   | server-side copy via x-amz-copy-source                                                                                                                                                                                                                                                                                                              |
| DeleteObject            | Objects        | Supported      | Common       | -                                                                                                                                                                                                                                                                                                                                                   |
| DeleteObjects           | Objects        | Supported      | Common       | batch delete is served: GCS has no \<Delete> batch endpoint, so the adapter fans the key list out to per-key deletes under a time budget and renders the S3 \<Deleted>/\<Error> result rows; a missing key is a success, matching S3's own idempotency                                                                                              |
| GetObject               | Objects        | Supported      | Common       | -                                                                                                                                                                                                                                                                                                                                                   |
| HeadObject              | Objects        | Supported      | Common       | -                                                                                                                                                                                                                                                                                                                                                   |
| ListObjectVersions      | Objects        | Supported      | Most usage   | The adapter renders S3 version listings from the GCS JSON API. VersionId identifies the native generation; delete markers record versionless deletes on versioned buckets.                                                                                                                                                                          |
| ListObjects             | Objects        | Supported      | Common       | the v1 listing form                                                                                                                                                                                                                                                                                                                                 |
| ListObjectsV2           | Objects        | Supported      | Common       | -                                                                                                                                                                                                                                                                                                                                                   |
| PutObject               | Objects        | Supported      | Common       | -                                                                                                                                                                                                                                                                                                                                                   |
| GetObjectAttributes     | Other features | Out of scope   | Full surface | the ?attributes query is not served; use HeadObject                                                                                                                                                                                                                                                                                                 |
| RestoreObject           | Other features | Out of scope   | Full surface | the ?restore query is rejected                                                                                                                                                                                                                                                                                                                      |
| SelectObjectContent     | Other features | Out of scope   | Full surface | the ?select query is rejected                                                                                                                                                                                                                                                                                                                       |
| DeleteObjectTagging     | Tagging        | Adapter-served | Most usage   | Cloud Storage has no object-tag primitive of its own, so the tag set is stored in reserved custom metadata on the object and rendered back as an S3 tagging document on read. Put replaces the whole set, matching S3. Version-addressed tagging requests are declined; native lifecycle and IAM conditions cannot use these reserved metadata tags |
| GetObjectTagging        | Tagging        | Adapter-served | Most usage   | Cloud Storage has no object-tag primitive of its own, so the tag set is stored in reserved custom metadata on the object and rendered back as an S3 tagging document on read. Put replaces the whole set, matching S3. Version-addressed tagging requests are declined; native lifecycle and IAM conditions cannot use these reserved metadata tags |
| PutObjectTagging        | Tagging        | Adapter-served | Most usage   | Cloud Storage has no object-tag primitive of its own, so the tag set is stored in reserved custom metadata on the object and rendered back as an S3 tagging document on read. Put replaces the whole set, matching S3. Version-addressed tagging requests are declined; native lifecycle and IAM conditions cannot use these reserved metadata tags |

#### S3 requests in the target environment

The application continues using the S3 API. The Tensor9 adapter runs in the target environment and sends object requests to Google Cloud Storage. It also serves bucket creation, deletion, listing, and configuration through a persistent bucket store. Google Cloud Storage stores the objects; Tensor9 operates the adapter and its bucket-management service.

#### Request flow

Object requests use the target storage service. Bucket settings persist separately and are applied to the target resource.

<div className="t9-diagram-scroll" role="region" aria-label="Scrollable diagram" tabIndex={0}>
  <img className="t9-diagram-light" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjI4OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDI4OCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgUzMgYXBwbGljYXRpb24gY2FsbHMgdGhlIFRlbnNvcjkgYWRhcHRlci4gT2JqZWN0IHJlcXVlc3RzIGdvIHRvIHRoZSB0YXJnZXQgb2JqZWN0IHN0b3JlLiBCdWNrZXQgc2V0dGluZ3MgcGVyc2lzdCBpbiB0aGUgYWRhcHRlcidzIHN0b3JlIGFuZCBhIGNvbmZpZ3VyYXRpb24gd29ya2VyIGFwcGxpZXMgdGhlbSB0byB0aGUgdGFyZ2V0LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgogIDxkZWZzPjxtYXJrZXIgaWQ9InMzLW1heC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI4NCIgcng9IjEwIiBmaWxsPSIjZWZmNmZmIiBzdHJva2U9IiM5M2M1ZmQiLz4KICA8cmVjdCB4PSIzMTAiIHk9IjM2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9Ijg0IiByeD0iMTAiIGZpbGw9IiNlY2ZkZjUiIHN0cm9rZT0iIzZlZTdiNyIvPgogIDxyZWN0IHg9IjU5NiIgeT0iMzYiIHdpZHRoPSIyMjAiIGhlaWdodD0iODQiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjOTRhM2I4Ii8+CiAgPHJlY3QgeD0iMzEwIiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iI2VjZmRmNSIgc3Ryb2tlPSIjNmVlN2I3Ii8+CiAgPHJlY3QgeD0iNTk2IiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjOTRhM2I4Ii8+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE2IiBmaWxsPSIjMGYxNzJhIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj4KICAgIDx0ZXh0IHg9IjEzNCIgeT0iNzAiPkFwcGxpY2F0aW9uPC90ZXh0Pjx0ZXh0IHg9IjEzNCIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPlMzIFNESzwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iNzAiPlRlbnNvcjkgUzMgYWRhcHRlcjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3QgYW5kIGJ1Y2tldCBBUElzPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSI3MCI+R29vZ2xlIENsb3VkIFN0b3JhZ2U8L3RleHQ+PHRleHQgeD0iNzA2IiB5PSI5NiIgZm9udC1zaXplPSIxNCI+T2JqZWN0cyBhbmQgc3RvcmFnZTwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iMjEyIj5QZXJzaXN0ZW50IGJ1Y2tldCBzdG9yZTwvdGV4dD48dGV4dCB4PSI0MjAiIHk9IjIzNiIgZm9udC1zaXplPSIxNCI+TmFtZXMgYW5kIGNvbmZpZ3VyYXRpb248L3RleHQ+CiAgICA8dGV4dCB4PSI3MDYiIHk9IjIyNCI+Q29uZmlndXJhdGlvbiB3b3JrZXI8L3RleHQ+CiAgPC9nPgogIDxnIHN0cm9rZT0iIzY0NzQ4YiIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBtYXJrZXItZW5kPSJ1cmwoI3MzLW1heC1hcnJvdykiPgogICAgPHBhdGggZD0iTTI0NCA3OCBIMzA2Ii8+PHBhdGggZD0iTTUzMCA3OCBINTkyIi8+PHBhdGggZD0iTTQyMCAxMjAgVjE4MCIvPgogICAgPHBhdGggZD0iTTUzMCAyMTggSDU5MiIvPjxwYXRoIGQ9Ik03MDYgMTg0IFYxMjQiLz4KICA8L2c+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjEyIiBmaWxsPSIjNDc1NTY5Ij4KICAgIDx0ZXh0IHg9IjQzMiIgeT0iMTUzIj5CdWNrZXQgc2V0dGluZ3M8L3RleHQ+PHRleHQgeD0iNzE4IiB5PSIxNTQiPkFwcGx5PC90ZXh0PgogIDwvZz4KPC9zdmc+" alt="The S3 application calls the Tensor9 adapter. Object requests go to the target object store. Bucket settings persist in the adapter's store and a configuration worker applies them to the target." />

  <img className="t9-diagram-dark" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjI4OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDI4OCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgUzMgYXBwbGljYXRpb24gY2FsbHMgdGhlIFRlbnNvcjkgYWRhcHRlci4gT2JqZWN0IHJlcXVlc3RzIGdvIHRvIHRoZSB0YXJnZXQgb2JqZWN0IHN0b3JlLiBCdWNrZXQgc2V0dGluZ3MgcGVyc2lzdCBpbiB0aGUgYWRhcHRlcidzIHN0b3JlIGFuZCBhIGNvbmZpZ3VyYXRpb24gd29ya2VyIGFwcGxpZXMgdGhlbSB0byB0aGUgdGFyZ2V0LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgogIDxkZWZzPjxtYXJrZXIgaWQ9InMzLW1heC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI4NCIgcng9IjEwIiBmaWxsPSIjMWEyNDMxIiBzdHJva2U9IiMzZDUwNjYiLz4KICA8cmVjdCB4PSIzMTAiIHk9IjM2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9Ijg0IiByeD0iMTAiIGZpbGw9IiMxYTMxMjYiIHN0cm9rZT0iIzNkNjY1NSIvPgogIDxyZWN0IHg9IjU5NiIgeT0iMzYiIHdpZHRoPSIyMjAiIGhlaWdodD0iODQiIHJ4PSIxMCIgZmlsbD0iIzFhMjYzMSIgc3Ryb2tlPSIjNDE0ZTYyIi8+CiAgPHJlY3QgeD0iMzEwIiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iIzFhMzEyNiIgc3Ryb2tlPSIjM2Q2NjU1Ii8+CiAgPHJlY3QgeD0iNTk2IiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iIzFhMjYzMSIgc3Ryb2tlPSIjNDE0ZTYyIi8+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE2IiBmaWxsPSIjNTU3NmMyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj4KICAgIDx0ZXh0IHg9IjEzNCIgeT0iNzAiPkFwcGxpY2F0aW9uPC90ZXh0Pjx0ZXh0IHg9IjEzNCIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPlMzIFNESzwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iNzAiPlRlbnNvcjkgUzMgYWRhcHRlcjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3QgYW5kIGJ1Y2tldCBBUElzPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSI3MCI+R29vZ2xlIENsb3VkIFN0b3JhZ2U8L3RleHQ+PHRleHQgeD0iNzA2IiB5PSI5NiIgZm9udC1zaXplPSIxNCI+T2JqZWN0cyBhbmQgc3RvcmFnZTwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iMjEyIj5QZXJzaXN0ZW50IGJ1Y2tldCBzdG9yZTwvdGV4dD48dGV4dCB4PSI0MjAiIHk9IjIzNiIgZm9udC1zaXplPSIxNCI+TmFtZXMgYW5kIGNvbmZpZ3VyYXRpb248L3RleHQ+CiAgICA8dGV4dCB4PSI3MDYiIHk9IjIyNCI+Q29uZmlndXJhdGlvbiB3b3JrZXI8L3RleHQ+CiAgPC9nPgogIDxnIHN0cm9rZT0iIzY0NzQ4YiIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBtYXJrZXItZW5kPSJ1cmwoI3MzLW1heC1hcnJvdykiPgogICAgPHBhdGggZD0iTTI0NCA3OCBIMzA2Ii8+PHBhdGggZD0iTTUzMCA3OCBINTkyIi8+PHBhdGggZD0iTTQyMCAxMjAgVjE4MCIvPgogICAgPHBhdGggZD0iTTUzMCAyMTggSDU5MiIvPjxwYXRoIGQ9Ik03MDYgMTg0IFYxMjQiLz4KICA8L2c+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjEyIiBmaWxsPSIjNzY4OGEyIj4KICAgIDx0ZXh0IHg9IjQzMiIgeT0iMTUzIj5CdWNrZXQgc2V0dGluZ3M8L3RleHQ+PHRleHQgeD0iNzE4IiB5PSIxNTQiPkFwcGx5PC90ZXh0PgogIDwvZz4KPC9zdmc+" alt="The S3 application calls the Tensor9 adapter. Object requests go to the target object store. Bucket settings persist in the adapter's store and a configuration worker applies them to the target." />
</div>

#### Object requests

Core GetObject, HeadObject, PutObject, CopyObject, DeleteObject, and listing requests use GCS's S3-interoperable XML endpoint with target credentials. Batch deletion sends per-object deletes and returns S3 Deleted/Error entries. Object tags are encoded in reserved GCS object metadata and reconstructed as S3 tagging documents. The object data stays in GCS; the bucket store does not hold object bodies.

#### Bucket creation and configuration

Each S3 bucket has a durable record containing its name, owner, requested configuration, and target reference. For a bucket named `bucket-name`, the S3-facing identifier is `arn:aws:s3:::bucket-name`; the target resource is a GCS bucket. `ListBuckets` returns the caller's buckets, and configuration reads use the stored request state.

A configuration worker applies the stored settings to the target. `CreateBucket` waits for the target bucket to be ready before returning success, so an immediate object write does not race bucket creation. `DeleteBucket` waits for removal and returns `BucketNotEmpty` if objects prevent deletion. A lifecycle update also waits for target application. For other configuration changes, a successful read of the new setting describes stored configuration; it does not imply every target-side change has already completed.

#### Versions and multipart uploads

GCS multipart uploads use temporary objects for individual parts. Completion calls the GCS JSON compose API to form the final object. At Max, the adapter retains part checksums to supply S3's composite multipart ETag and maintains the S3 version history and delete markers that differ from native GCS generations. A deployment that only forwards object requests instead exposes the native generation model and compose ETag. ListMultipartUploads and UploadPartCopy remain outside the listed mapping.

#### Target configuration

Bucket versioning, tagging, lifecycle and encryption settings are managed through runtime S3 calls. Lifecycle translation supports the rules listed in the feature comparison: prefix-scoped, relative-age expiration and transitions to STANDARD\_IA or ONEZONE\_IA, both mapped to Nearline. Unsupported date, filter, noncurrent-version and archival-transition forms return an error rather than a different retention or cost policy. Encryption uses Google-managed keys, Cloud KMS customer-managed keys or customer-supplied keys as applicable; DSSE-KMS and S3 Bucket Keys have no direct equivalent.

#### Placement and operation

GCS provides strong read-after-write consistency and designs for 99.999999999% annual durability. Region, dual-region or multi-region placement controls where the provider stores the data. Cross-bucket replication uses Storage Transfer Service rather than the S3 replication-rule engine. Object notifications go to Pub/Sub; routing to other destination types requires downstream integration. Tensor9 operates the bucket-management adapter, while Google operates object storage.

#### Compatibility limits

Bucket policy is unsupported at every adaptation tier. Object ACL, retention/legal-hold, S3 Select and RestoreObject APIs remain outside the listed S3 endpoint. Native GCS features such as Bucket Lock, Requester Pays and Autoclass must be assessed with their own configuration and semantics; native availability does not turn them into unrestricted S3 API equivalents.

#### Migration and leaving the adapter

A newly provisioned target bucket starts empty. Copy existing objects and required versions with a migration tool or a coordinated dual-write, then verify object data and application reads before switching. Preserve version history through the S3 API when the application depends on S3 version identifiers or delete markers.

Leaving the Max adapter requires moving bucket configuration as well as object data. Apply the retained settings to native target resources, resolve any S3-specific version metadata, and move clients to the target's own API. Keep the adapter and its persistent state until the application no longer depends on those S3 behaviors.

## On OCI

### OCI Object Storage

| Capability                                                      | Area           | Support      | Operations | Notes                                                                                                                                                                                                                                                     |
| --------------------------------------------------------------- | -------------- | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Bucket policy, CORS, website, notification and replication APIs | Bucket config  | Out of scope | -          | These runtime S3 configuration APIs are outside the listed endpoint. Native target configuration and deployment mappings are described separately.                                                                                                        |
| Bucket versioning, tagging, lifecycle and encryption            | Bucket config  | Partial      | -          | At Max, runtime S3 calls retain bucket settings and apply supported target mappings. Lifecycle filters, storage classes and account-level settings retain the limits described below. Simpler request forwarding configures these settings at deployment. |
| Presigned URLs                                                  | Other features | Out of scope | -          | S3 presigned URLs aren't honored: the adapter re-signs to the backend and does not validate the client's presigned signature, so its expiry/scope guarantees aren't enforced.                                                                             |

| Operation               | Area           | Support      | Depth        | Notes                                                                                                                |
| ----------------------- | -------------- | ------------ | ------------ | -------------------------------------------------------------------------------------------------------------------- |
| GetObjectAcl            | Access control | Out of scope | Full surface | Object ACL requests are rejected. Configure access through target permissions or deployment configuration.           |
| PutObjectAcl            | Access control | Out of scope | Full surface | Object ACL requests are rejected. Configure access through target permissions or deployment configuration.           |
| CreateBucket            | Bucket config  | Supported    | Most usage   | The adapter serves this bucket operation.                                                                            |
| DeleteBucket            | Bucket config  | Supported    | Most usage   | The adapter serves this bucket operation.                                                                            |
| HeadBucket              | Bucket config  | Supported    | Most usage   | The adapter serves this bucket operation.                                                                            |
| AbortMultipartUpload    | Multipart      | Supported    | Most usage   | -                                                                                                                    |
| CompleteMultipartUpload | Multipart      | Supported    | Most usage   | -                                                                                                                    |
| CreateMultipartUpload   | Multipart      | Supported    | Most usage   | -                                                                                                                    |
| ListMultipartUploads    | Multipart      | Supported    | Most usage   | -                                                                                                                    |
| ListParts               | Multipart      | Supported    | Most usage   | -                                                                                                                    |
| UploadPart              | Multipart      | Supported    | Most usage   | -                                                                                                                    |
| GetObjectLegalHold      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                           |
| GetObjectRetention      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                           |
| PutObjectLegalHold      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                           |
| PutObjectRetention      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                           |
| CopyObject              | Objects        | Supported    | Most usage   | server-side copy via x-amz-copy-source                                                                               |
| DeleteObject            | Objects        | Supported    | Common       | -                                                                                                                    |
| DeleteObjects           | Objects        | Supported    | Common       | batch delete (OCI BulkDelete)                                                                                        |
| GetObject               | Objects        | Supported    | Common       | bodies + byte ranges                                                                                                 |
| HeadObject              | Objects        | Supported    | Common       | -                                                                                                                    |
| ListObjectVersions      | Objects        | Out of scope | Most usage   | Version-addressed reads and deletes are supported, but ListObjectVersions is outside this mapping, including at Max. |
| ListObjects             | Objects        | Supported    | Common       | the v1 listing form                                                                                                  |
| ListObjectsV2           | Objects        | Supported    | Common       | -                                                                                                                    |
| PutObject               | Objects        | Supported    | Common       | -                                                                                                                    |
| GetObjectAttributes     | Other features | Out of scope | Full surface | the ?attributes query is not served; use HeadObject                                                                  |
| RestoreObject           | Other features | Out of scope | Full surface | the ?restore query is rejected                                                                                       |
| SelectObjectContent     | Other features | Out of scope | Full surface | the ?select query is rejected                                                                                        |
| DeleteObjectTagging     | Tagging        | Out of scope | Most usage   | OCI's S3-compat API has only bucket tagging, not object tagging                                                      |
| GetObjectTagging        | Tagging        | Out of scope | Most usage   | OCI's S3-compat API has only bucket tagging, not object tagging                                                      |
| PutObjectTagging        | Tagging        | Out of scope | Most usage   | OCI's S3-compat API has only bucket tagging, not object tagging                                                      |

#### S3 requests in the target environment

The application continues using the S3 API. The Tensor9 adapter runs in the target environment and sends object requests to OCI Object Storage. It also serves bucket creation, deletion, listing, and configuration through a persistent bucket store. OCI Object Storage stores the objects; Tensor9 operates the adapter and its bucket-management service.

#### Request flow

Object requests use the target storage service. Bucket settings persist separately and are applied to the target resource.

<div className="t9-diagram-scroll" role="region" aria-label="Scrollable diagram" tabIndex={0}>
  <img className="t9-diagram-light" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjI4OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDI4OCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgUzMgYXBwbGljYXRpb24gY2FsbHMgdGhlIFRlbnNvcjkgYWRhcHRlci4gT2JqZWN0IHJlcXVlc3RzIGdvIHRvIHRoZSB0YXJnZXQgb2JqZWN0IHN0b3JlLiBCdWNrZXQgc2V0dGluZ3MgcGVyc2lzdCBpbiB0aGUgYWRhcHRlcidzIHN0b3JlIGFuZCBhIGNvbmZpZ3VyYXRpb24gd29ya2VyIGFwcGxpZXMgdGhlbSB0byB0aGUgdGFyZ2V0LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgogIDxkZWZzPjxtYXJrZXIgaWQ9InMzLW1heC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI4NCIgcng9IjEwIiBmaWxsPSIjZWZmNmZmIiBzdHJva2U9IiM5M2M1ZmQiLz4KICA8cmVjdCB4PSIzMTAiIHk9IjM2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9Ijg0IiByeD0iMTAiIGZpbGw9IiNlY2ZkZjUiIHN0cm9rZT0iIzZlZTdiNyIvPgogIDxyZWN0IHg9IjU5NiIgeT0iMzYiIHdpZHRoPSIyMjAiIGhlaWdodD0iODQiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjOTRhM2I4Ii8+CiAgPHJlY3QgeD0iMzEwIiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iI2VjZmRmNSIgc3Ryb2tlPSIjNmVlN2I3Ii8+CiAgPHJlY3QgeD0iNTk2IiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjOTRhM2I4Ii8+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE2IiBmaWxsPSIjMGYxNzJhIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj4KICAgIDx0ZXh0IHg9IjEzNCIgeT0iNzAiPkFwcGxpY2F0aW9uPC90ZXh0Pjx0ZXh0IHg9IjEzNCIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPlMzIFNESzwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iNzAiPlRlbnNvcjkgUzMgYWRhcHRlcjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3QgYW5kIGJ1Y2tldCBBUElzPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSI3MCI+T0NJIE9iamVjdCBTdG9yYWdlPC90ZXh0Pjx0ZXh0IHg9IjcwNiIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPk9iamVjdHMgYW5kIHN0b3JhZ2U8L3RleHQ+CiAgICA8dGV4dCB4PSI0MjAiIHk9IjIxMiI+UGVyc2lzdGVudCBidWNrZXQgc3RvcmU8L3RleHQ+PHRleHQgeD0iNDIwIiB5PSIyMzYiIGZvbnQtc2l6ZT0iMTQiPk5hbWVzIGFuZCBjb25maWd1cmF0aW9uPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSIyMjQiPkNvbmZpZ3VyYXRpb24gd29ya2VyPC90ZXh0PgogIDwvZz4KICA8ZyBzdHJva2U9IiM2NDc0OGIiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0ibm9uZSIgbWFya2VyLWVuZD0idXJsKCNzMy1tYXgtYXJyb3cpIj4KICAgIDxwYXRoIGQ9Ik0yNDQgNzggSDMwNiIvPjxwYXRoIGQ9Ik01MzAgNzggSDU5MiIvPjxwYXRoIGQ9Ik00MjAgMTIwIFYxODAiLz4KICAgIDxwYXRoIGQ9Ik01MzAgMjE4IEg1OTIiLz48cGF0aCBkPSJNNzA2IDE4NCBWMTI0Ii8+CiAgPC9nPgogIDxnIGZvbnQtZmFtaWx5PSJzeXN0ZW0tdWksc2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMiIgZmlsbD0iIzQ3NTU2OSI+CiAgICA8dGV4dCB4PSI0MzIiIHk9IjE1MyI+QnVja2V0IHNldHRpbmdzPC90ZXh0Pjx0ZXh0IHg9IjcxOCIgeT0iMTU0Ij5BcHBseTwvdGV4dD4KICA8L2c+Cjwvc3ZnPg==" alt="The S3 application calls the Tensor9 adapter. Object requests go to the target object store. Bucket settings persist in the adapter's store and a configuration worker applies them to the target." />

  <img className="t9-diagram-dark" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjI4OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDI4OCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgUzMgYXBwbGljYXRpb24gY2FsbHMgdGhlIFRlbnNvcjkgYWRhcHRlci4gT2JqZWN0IHJlcXVlc3RzIGdvIHRvIHRoZSB0YXJnZXQgb2JqZWN0IHN0b3JlLiBCdWNrZXQgc2V0dGluZ3MgcGVyc2lzdCBpbiB0aGUgYWRhcHRlcidzIHN0b3JlIGFuZCBhIGNvbmZpZ3VyYXRpb24gd29ya2VyIGFwcGxpZXMgdGhlbSB0byB0aGUgdGFyZ2V0LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgogIDxkZWZzPjxtYXJrZXIgaWQ9InMzLW1heC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI4NCIgcng9IjEwIiBmaWxsPSIjMWEyNDMxIiBzdHJva2U9IiMzZDUwNjYiLz4KICA8cmVjdCB4PSIzMTAiIHk9IjM2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9Ijg0IiByeD0iMTAiIGZpbGw9IiMxYTMxMjYiIHN0cm9rZT0iIzNkNjY1NSIvPgogIDxyZWN0IHg9IjU5NiIgeT0iMzYiIHdpZHRoPSIyMjAiIGhlaWdodD0iODQiIHJ4PSIxMCIgZmlsbD0iIzFhMjYzMSIgc3Ryb2tlPSIjNDE0ZTYyIi8+CiAgPHJlY3QgeD0iMzEwIiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iIzFhMzEyNiIgc3Ryb2tlPSIjM2Q2NjU1Ii8+CiAgPHJlY3QgeD0iNTk2IiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iIzFhMjYzMSIgc3Ryb2tlPSIjNDE0ZTYyIi8+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE2IiBmaWxsPSIjNTU3NmMyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj4KICAgIDx0ZXh0IHg9IjEzNCIgeT0iNzAiPkFwcGxpY2F0aW9uPC90ZXh0Pjx0ZXh0IHg9IjEzNCIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPlMzIFNESzwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iNzAiPlRlbnNvcjkgUzMgYWRhcHRlcjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3QgYW5kIGJ1Y2tldCBBUElzPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSI3MCI+T0NJIE9iamVjdCBTdG9yYWdlPC90ZXh0Pjx0ZXh0IHg9IjcwNiIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPk9iamVjdHMgYW5kIHN0b3JhZ2U8L3RleHQ+CiAgICA8dGV4dCB4PSI0MjAiIHk9IjIxMiI+UGVyc2lzdGVudCBidWNrZXQgc3RvcmU8L3RleHQ+PHRleHQgeD0iNDIwIiB5PSIyMzYiIGZvbnQtc2l6ZT0iMTQiPk5hbWVzIGFuZCBjb25maWd1cmF0aW9uPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSIyMjQiPkNvbmZpZ3VyYXRpb24gd29ya2VyPC90ZXh0PgogIDwvZz4KICA8ZyBzdHJva2U9IiM2NDc0OGIiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0ibm9uZSIgbWFya2VyLWVuZD0idXJsKCNzMy1tYXgtYXJyb3cpIj4KICAgIDxwYXRoIGQ9Ik0yNDQgNzggSDMwNiIvPjxwYXRoIGQ9Ik01MzAgNzggSDU5MiIvPjxwYXRoIGQ9Ik00MjAgMTIwIFYxODAiLz4KICAgIDxwYXRoIGQ9Ik01MzAgMjE4IEg1OTIiLz48cGF0aCBkPSJNNzA2IDE4NCBWMTI0Ii8+CiAgPC9nPgogIDxnIGZvbnQtZmFtaWx5PSJzeXN0ZW0tdWksc2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMiIgZmlsbD0iIzc2ODhhMiI+CiAgICA8dGV4dCB4PSI0MzIiIHk9IjE1MyI+QnVja2V0IHNldHRpbmdzPC90ZXh0Pjx0ZXh0IHg9IjcxOCIgeT0iMTU0Ij5BcHBseTwvdGV4dD4KICA8L2c+Cjwvc3ZnPg==" alt="The S3 application calls the Tensor9 adapter. Object requests go to the target object store. Bucket settings persist in the adapter's store and a configuration worker applies them to the target." />
</div>

#### Object requests

Object requests use OCI's Amazon S3 Compatibility endpoint. The adapter changes the endpoint and signs with the customer's OCI S3-compatible access and secret keys. Core reads, writes, copies, deletes and multipart uploads use the provider API. Object bodies remain in OCI Object Storage, while the adapter stores bucket configuration separately.

#### Bucket creation and configuration

Each S3 bucket has a durable record containing its name, owner, requested configuration, and target reference. For a bucket named `bucket-name`, the S3-facing identifier is `arn:aws:s3:::bucket-name`; the target resource is an OCI Object Storage bucket. `ListBuckets` returns the caller's buckets, and configuration reads use the stored request state.

A configuration worker applies the stored settings to the target. `CreateBucket` waits for the target bucket to be ready before returning success, so an immediate object write does not race bucket creation. `DeleteBucket` waits for removal and returns `BucketNotEmpty` if objects prevent deletion. A lifecycle update also waits for target application. For other configuration changes, a successful read of the new setting describes stored configuration; it does not imply every target-side change has already completed.

#### Versions and multipart uploads

OCI provides native multipart uploads and accepts a versionId on object reads, metadata reads and deletion. Its compatibility endpoint does not provide the S3 version-listing behavior used by the application. At Max, the adapter retains the version and deletion metadata needed by S3-addressed object operations. ListObjectVersions remains outside this mapping; maintaining version metadata does not add that API. Native multipart operations retain the provider's behavior.

#### Target configuration

Runtime bucket configuration is stored by the adapter and applied through the target bucket-management design. Native OCI bucket settings provide lifecycle, encryption, replication and retention. Encryption can use provider-managed, Vault-managed or customer-supplied keys; DSSE-KMS and S3 Bucket Keys have no direct equivalent. OCI tags apply to buckets; object tagging is outside the listed mapping. Retention rules combine time-based retention with optional locking and do not provide an independent S3 legal-hold object.

#### Placement and operation

OCI provides strong read-after-write consistency and designs for eleven-nines durability. It replicates across three availability domains, or three fault domains in a single-domain region. Cross-region replication targets a preexisting destination bucket. Object events use OCI Events. Tensor9 operates the bucket-management adapter, and Oracle operates the object store.

#### Compatibility limits

Bucket policy is unsupported at every tier. OCI's compatibility endpoint has no configurable CORS; its fixed response is not an S3 CORS rule set. Website hosting and Requester Pays have no direct OCI Object Storage equivalent. Presigned access uses OCI Pre-Authenticated Requests outside this S3 adapter path. The API table identifies operations that remain unavailable despite native storage features.

#### Migration and leaving the adapter

A newly provisioned target bucket starts empty. Copy existing objects and required versions with a migration tool or a coordinated dual-write, then verify object data and application reads before switching. Preserve version history through the S3 API when the application depends on S3 version identifiers or delete markers.

Leaving the Max adapter requires moving bucket configuration as well as object data. Apply the retained settings to native target resources, resolve any S3-specific version metadata, and move clients to the target's own API. Keep the adapter and its persistent state until the application no longer depends on those S3 behaviors.

## On Private Kubernetes

### MinIO Storage

| Capability                                                                                                        | Area           | Support      | Operations | Notes                                                                                                                                                                         |
| ----------------------------------------------------------------------------------------------------------------- | -------------- | ------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Bucket sub-resources (versioning / lifecycle / encryption / policy / CORS / website / notification / replication) | Bucket config  | Out of scope | -          | provisioned at deploy time, not served as runtime S3 control calls                                                                                                            |
| Presigned URLs                                                                                                    | Other features | Out of scope | -          | S3 presigned URLs aren't honored: the adapter re-signs to the backend and does not validate the client's presigned signature, so its expiry/scope guarantees aren't enforced. |

| Operation               | Area           | Support      | Depth        | Notes                                                                                                      |
| ----------------------- | -------------- | ------------ | ------------ | ---------------------------------------------------------------------------------------------------------- |
| GetObjectAcl            | Access control | Out of scope | Full surface | Object ACL requests are rejected. Configure access through target permissions or deployment configuration. |
| PutObjectAcl            | Access control | Out of scope | Full surface | Object ACL requests are rejected. Configure access through target permissions or deployment configuration. |
| CreateBucket            | Bucket config  | Supported    | Most usage   | The adapter serves this bucket operation.                                                                  |
| DeleteBucket            | Bucket config  | Supported    | Most usage   | The adapter serves this bucket operation.                                                                  |
| HeadBucket              | Bucket config  | Supported    | Most usage   | The adapter serves this bucket operation.                                                                  |
| AbortMultipartUpload    | Multipart      | Supported    | Most usage   | -                                                                                                          |
| CompleteMultipartUpload | Multipart      | Supported    | Most usage   | -                                                                                                          |
| CreateMultipartUpload   | Multipart      | Supported    | Most usage   | -                                                                                                          |
| ListMultipartUploads    | Multipart      | Supported    | Most usage   | -                                                                                                          |
| ListParts               | Multipart      | Supported    | Most usage   | -                                                                                                          |
| UploadPart              | Multipart      | Supported    | Most usage   | -                                                                                                          |
| GetObjectLegalHold      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                 |
| GetObjectRetention      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                 |
| PutObjectLegalHold      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                 |
| PutObjectRetention      | Object lock    | Out of scope | Full surface | the object-lock sub-resources are rejected                                                                 |
| CopyObject              | Objects        | Supported    | Most usage   | server-side copy via x-amz-copy-source                                                                     |
| DeleteObject            | Objects        | Supported    | Common       | -                                                                                                          |
| DeleteObjects           | Objects        | Supported    | Common       | batch delete                                                                                               |
| GetObject               | Objects        | Supported    | Common       | -                                                                                                          |
| HeadObject              | Objects        | Supported    | Common       | -                                                                                                          |
| ListObjectVersions      | Objects        | Supported    | Most usage   | when bucket versioning is enabled                                                                          |
| ListObjects             | Objects        | Supported    | Common       | the v1 listing form                                                                                        |
| ListObjectsV2           | Objects        | Supported    | Common       | -                                                                                                          |
| PutObject               | Objects        | Supported    | Common       | -                                                                                                          |
| GetObjectAttributes     | Other features | Out of scope | Full surface | the ?attributes query is not served; use HeadObject                                                        |
| RestoreObject           | Other features | Out of scope | Full surface | the ?restore query is rejected                                                                             |
| SelectObjectContent     | Other features | Out of scope | Full surface | the ?select query is rejected                                                                              |
| DeleteObjectTagging     | Tagging        | Supported    | Most usage   | -                                                                                                          |
| GetObjectTagging        | Tagging        | Supported    | Most usage   | -                                                                                                          |
| PutObjectTagging        | Tagging        | Supported    | Most usage   | -                                                                                                          |

#### S3 on the customer's own storage

The application uses its S3 client to reach the Tensor9 adapter. The adapter signs requests with the customer's MinIO credentials and forwards the supported operations to MinIO's S3 endpoint. Tensor9 deploys and operates MinIO inside the Cloud Adapter deployment, including in disconnected environments. Objects remain on the customer's disks.

<div className="t9-diagram-scroll" role="region" aria-label="Scrollable diagram" tabIndex={0}>
  <img className="t9-diagram-light" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjE3MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDE3MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYXBwbGljYXRpb24gc2VuZHMgUzMgcmVxdWVzdHMgdGhyb3VnaCB0aGUgVGVuc29yOSBhZGFwdGVyIHRvIE1pbklPIGluIHRoZSBjdXN0b21lciBlbnZpcm9ubWVudC4gVGhlIGFkYXB0ZXIgc2lnbnMgcmVxdWVzdHMgZm9yIE1pbklPOyBNaW5JTyBzdG9yZXMgdGhlIG9iamVjdHMgb24gY3VzdG9tZXIgZGlza3MuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CiAgPGRlZnM+PG1hcmtlciBpZD0ibWluaW8tcmVxdWVzdC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxnIHN0cm9rZT0iIzk0YTNiOCI+PHJlY3QgZmlsbD0iI2Y4ZmFmYyIgeD0iMjAiIHk9IjQwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9Ijk1IiByeD0iMTAiLz48cmVjdCBmaWxsPSIjZjhmYWZjIiB4PSIzMTUiIHk9IjQwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9Ijk1IiByeD0iMTAiLz48cmVjdCBmaWxsPSIjZjhmYWZjIiB4PSI2MTAiIHk9IjQwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9Ijk1IiByeD0iMTAiLz48L2c+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmaWxsPSIjMGYxNzJhIj48dGV4dCB4PSIxMjUiIHk9Ijc3Ij5BcHBsaWNhdGlvbjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijc3Ij5UZW5zb3I5IGFkYXB0ZXI8L3RleHQ+PHRleHQgeD0iNzE1IiB5PSI3NyI+TWluSU88L3RleHQ+PC9nPgogIDxnIGZvbnQtZmFtaWx5PSJzeXN0ZW0tdWksc2Fucy1zZXJpZiIgZm9udC1zaXplPSIxNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZmlsbD0iIzQ3NTU2OSI+PHRleHQgeD0iMTI1IiB5PSIxMDYiPlMzIGNsaWVudDwvdGV4dD48dGV4dCB4PSI0MjAiIHk9IjEwNiI+U2lnbiBhbmQgZm9yd2FyZCByZXF1ZXN0czwvdGV4dD48dGV4dCB4PSI3MTUiIHk9IjEwNiI+T2JqZWN0cyBvbiBjdXN0b21lciBkaXNrczwvdGV4dD48L2c+CiAgPGcgc3Ryb2tlPSIjNjQ3NDhiIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjbWluaW8tcmVxdWVzdC1hcnJvdykiPjxwYXRoIGQ9Ik0yMzAgODggSDMxMCIvPjxwYXRoIGQ9Ik01MjUgODggSDYwNSIvPjwvZz4KPC9zdmc+" alt="The application sends S3 requests through the Tensor9 adapter to MinIO in the target environment. The adapter signs requests for MinIO; MinIO stores the objects on customer disks." />

  <img className="t9-diagram-dark" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjE3MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDE3MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYXBwbGljYXRpb24gc2VuZHMgUzMgcmVxdWVzdHMgdGhyb3VnaCB0aGUgVGVuc29yOSBhZGFwdGVyIHRvIE1pbklPIGluIHRoZSBjdXN0b21lciBlbnZpcm9ubWVudC4gVGhlIGFkYXB0ZXIgc2lnbnMgcmVxdWVzdHMgZm9yIE1pbklPOyBNaW5JTyBzdG9yZXMgdGhlIG9iamVjdHMgb24gY3VzdG9tZXIgZGlza3MuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CiAgPGRlZnM+PG1hcmtlciBpZD0ibWluaW8tcmVxdWVzdC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxnIHN0cm9rZT0iIzQxNGU2MiI+PHJlY3QgZmlsbD0iIzFhMjYzMSIgeD0iMjAiIHk9IjQwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9Ijk1IiByeD0iMTAiLz48cmVjdCBmaWxsPSIjMWEyNjMxIiB4PSIzMTUiIHk9IjQwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9Ijk1IiByeD0iMTAiLz48cmVjdCBmaWxsPSIjMWEyNjMxIiB4PSI2MTAiIHk9IjQwIiB3aWR0aD0iMjEwIiBoZWlnaHQ9Ijk1IiByeD0iMTAiLz48L2c+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmaWxsPSIjNTU3NmMyIj48dGV4dCB4PSIxMjUiIHk9Ijc3Ij5BcHBsaWNhdGlvbjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijc3Ij5UZW5zb3I5IGFkYXB0ZXI8L3RleHQ+PHRleHQgeD0iNzE1IiB5PSI3NyI+TWluSU88L3RleHQ+PC9nPgogIDxnIGZvbnQtZmFtaWx5PSJzeXN0ZW0tdWksc2Fucy1zZXJpZiIgZm9udC1zaXplPSIxNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZmlsbD0iIzc2ODhhMiI+PHRleHQgeD0iMTI1IiB5PSIxMDYiPlMzIGNsaWVudDwvdGV4dD48dGV4dCB4PSI0MjAiIHk9IjEwNiI+U2lnbiBhbmQgZm9yd2FyZCByZXF1ZXN0czwvdGV4dD48dGV4dCB4PSI3MTUiIHk9IjEwNiI+T2JqZWN0cyBvbiBjdXN0b21lciBkaXNrczwvdGV4dD48L2c+CiAgPGcgc3Ryb2tlPSIjNjQ3NDhiIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjbWluaW8tcmVxdWVzdC1hcnJvdykiPjxwYXRoIGQ9Ik0yMzAgODggSDMxMCIvPjxwYXRoIGQ9Ik01MjUgODggSDYwNSIvPjwvZz4KPC9zdmc+" alt="The application sends S3 requests through the Tensor9 adapter to MinIO in the target environment. The adapter signs requests for MinIO; MinIO stores the objects on customer disks." />
</div>

#### Object operations

The adapter forwards the listed reads, writes, listings, deletes, server-side copies and multipart uploads. Versioned buckets also support version listing. Object tags are stored as MinIO object tags, so MinIO can use them in its lifecycle and access-policy conditions.

MinIO's broader API does not determine what this endpoint accepts. The adapter rejects object ACL requests, bucket-policy requests, S3 Select, Glacier restore and runtime retention or legal-hold calls. MinIO implements Object Lock, including GOVERNANCE and COMPLIANCE retention and independent legal holds; configure those features directly on MinIO.

#### Consistency and recovery

MinIO provides strict read-after-write and list-after-write consistency. A completed write is visible to subsequent reads and listings.

MinIO splits objects into data and parity shards across drives. Parity lets it reconstruct missing or damaged shards while enough drives remain available. Failure tolerance depends on the configured parity and the placement of drives across nodes. Read and write availability have separate quorum requirements: recovering data after an outage does not guarantee that writes can continue throughout it.

MinIO checks reads with HighwayHash and can repair detected corruption from surviving shards. Tensor9 operates recovery and monitors the deployment; durability depends on its hardware and layout. There is no MinIO durability percentage or availability SLA to substitute for that design. See [MinIO's erasure-coding documentation](https://min.io/docs/minio/linux/operations/concepts/erasure-coding.html) for parity and quorum requirements.

<div className="t9-diagram-scroll" role="region" aria-label="Scrollable diagram" tabIndex={0}>
  <img className="t9-diagram-light" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjE5MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDE5MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJJbGx1c3RyYXRpdmUgZXJhc3VyZS1jb2RpbmcgbGF5b3V0OiBmb3VyIGRhdGEgc2hhcmRzIGFuZCB0d28gcGFyaXR5IHNoYXJkcy4gVHdvIG1pc3Npbmcgc2hhcmRzIGNhbiBiZSByZWNvbnN0cnVjdGVkIGZyb20gdGhlIGZvdXIgcmVtYWluaW5nIHNoYXJkcy4gUHJvZHVjdGlvbiByZWNvdmVyeSBhbmQgd3JpdGUgYXZhaWxhYmlsaXR5IGRlcGVuZCBvbiB0aGUgY29uZmlndXJlZCBwYXJpdHkgYW5kIHBsYWNlbWVudC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KICA8dGV4dCB4PSIyNCIgeT0iMzAiIGZvbnQtZmFtaWx5PSJzeXN0ZW0tdWksc2Fucy1zZXJpZiIgZm9udC1zaXplPSIxNyIgZmlsbD0iIzBmMTcyYSI+RXhhbXBsZTogZm91ciBkYXRhIHNoYXJkcyBhbmQgdHdvIHBhcml0eSBzaGFyZHM8L3RleHQ+CiAgPGcgc3Ryb2tlPSIjOTNjNWZkIj48cmVjdCBmaWxsPSIjZWZmNmZmIiB4PSIyNCIgeT0iNTQiIHdpZHRoPSIxMTIiIGhlaWdodD0iNjYiIHJ4PSI4Ii8+PHJlY3QgZmlsbD0iI2VmZjZmZiIgeD0iMTYwIiB5PSI1NCIgd2lkdGg9IjExMiIgaGVpZ2h0PSI2NiIgcng9IjgiLz48cmVjdCBmaWxsPSIjZWZmNmZmIiB4PSIyOTYiIHk9IjU0IiB3aWR0aD0iMTEyIiBoZWlnaHQ9IjY2IiByeD0iOCIvPjxyZWN0IGZpbGw9IiNlZmY2ZmYiIHg9IjQzMiIgeT0iNTQiIHdpZHRoPSIxMTIiIGhlaWdodD0iNjYiIHJ4PSI4Ii8+PC9nPgogIDxnIHN0cm9rZT0iIzZlZTdiNyI+PHJlY3QgZmlsbD0iI2VjZmRmNSIgeD0iNTY4IiB5PSI1NCIgd2lkdGg9IjExMiIgaGVpZ2h0PSI2NiIgcng9IjgiLz48cmVjdCBmaWxsPSIjZWNmZGY1IiB4PSI3MDQiIHk9IjU0IiB3aWR0aD0iMTEyIiBoZWlnaHQ9IjY2IiByeD0iOCIvPjwvZz4KICA8ZyBmb250LWZhbWlseT0ic3lzdGVtLXVpLHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IiMwZjE3MmEiPjx0ZXh0IHg9IjgwIiB5PSI5MyI+RGF0YSAxPC90ZXh0Pjx0ZXh0IHg9IjIxNiIgeT0iOTMiPkRhdGEgMjwvdGV4dD48dGV4dCB4PSIzNTIiIHk9IjkzIj5EYXRhIDM8L3RleHQ+PHRleHQgeD0iNDg4IiB5PSI5MyI+RGF0YSA0PC90ZXh0Pjx0ZXh0IHg9IjYyNCIgeT0iOTMiPlBhcml0eSAxPC90ZXh0Pjx0ZXh0IHg9Ijc2MCIgeT0iOTMiPlBhcml0eSAyPC90ZXh0PjwvZz4KICA8dGV4dCB4PSIyNCIgeT0iMTU3IiBmb250LWZhbWlseT0ic3lzdGVtLXVpLHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTYiIGZpbGw9IiM0NzU1NjkiPlJlY29uc3RydWN0aW9uIG5lZWRzIGZvdXIgc3Vydml2aW5nIHNoYXJkcyBpbiB0aGlzIGV4YW1wbGUuPC90ZXh0Pgo8L3N2Zz4=" alt="Illustrative erasure-coding layout: four data shards and two parity shards. Two missing shards can be reconstructed from the four remaining shards. Production recovery and write availability depend on the configured parity and placement." />

  <img className="t9-diagram-dark" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjE5MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDE5MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJJbGx1c3RyYXRpdmUgZXJhc3VyZS1jb2RpbmcgbGF5b3V0OiBmb3VyIGRhdGEgc2hhcmRzIGFuZCB0d28gcGFyaXR5IHNoYXJkcy4gVHdvIG1pc3Npbmcgc2hhcmRzIGNhbiBiZSByZWNvbnN0cnVjdGVkIGZyb20gdGhlIGZvdXIgcmVtYWluaW5nIHNoYXJkcy4gUHJvZHVjdGlvbiByZWNvdmVyeSBhbmQgd3JpdGUgYXZhaWxhYmlsaXR5IGRlcGVuZCBvbiB0aGUgY29uZmlndXJlZCBwYXJpdHkgYW5kIHBsYWNlbWVudC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KICA8dGV4dCB4PSIyNCIgeT0iMzAiIGZvbnQtZmFtaWx5PSJzeXN0ZW0tdWksc2Fucy1zZXJpZiIgZm9udC1zaXplPSIxNyIgZmlsbD0iIzU1NzZjMiI+RXhhbXBsZTogZm91ciBkYXRhIHNoYXJkcyBhbmQgdHdvIHBhcml0eSBzaGFyZHM8L3RleHQ+CiAgPGcgc3Ryb2tlPSIjM2Q1MDY2Ij48cmVjdCBmaWxsPSIjMWEyNDMxIiB4PSIyNCIgeT0iNTQiIHdpZHRoPSIxMTIiIGhlaWdodD0iNjYiIHJ4PSI4Ii8+PHJlY3QgZmlsbD0iIzFhMjQzMSIgeD0iMTYwIiB5PSI1NCIgd2lkdGg9IjExMiIgaGVpZ2h0PSI2NiIgcng9IjgiLz48cmVjdCBmaWxsPSIjMWEyNDMxIiB4PSIyOTYiIHk9IjU0IiB3aWR0aD0iMTEyIiBoZWlnaHQ9IjY2IiByeD0iOCIvPjxyZWN0IGZpbGw9IiMxYTI0MzEiIHg9IjQzMiIgeT0iNTQiIHdpZHRoPSIxMTIiIGhlaWdodD0iNjYiIHJ4PSI4Ii8+PC9nPgogIDxnIHN0cm9rZT0iIzNkNjY1NSI+PHJlY3QgZmlsbD0iIzFhMzEyNiIgeD0iNTY4IiB5PSI1NCIgd2lkdGg9IjExMiIgaGVpZ2h0PSI2NiIgcng9IjgiLz48cmVjdCBmaWxsPSIjMWEzMTI2IiB4PSI3MDQiIHk9IjU0IiB3aWR0aD0iMTEyIiBoZWlnaHQ9IjY2IiByeD0iOCIvPjwvZz4KICA8ZyBmb250LWZhbWlseT0ic3lzdGVtLXVpLHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IiM1NTc2YzIiPjx0ZXh0IHg9IjgwIiB5PSI5MyI+RGF0YSAxPC90ZXh0Pjx0ZXh0IHg9IjIxNiIgeT0iOTMiPkRhdGEgMjwvdGV4dD48dGV4dCB4PSIzNTIiIHk9IjkzIj5EYXRhIDM8L3RleHQ+PHRleHQgeD0iNDg4IiB5PSI5MyI+RGF0YSA0PC90ZXh0Pjx0ZXh0IHg9IjYyNCIgeT0iOTMiPlBhcml0eSAxPC90ZXh0Pjx0ZXh0IHg9Ijc2MCIgeT0iOTMiPlBhcml0eSAyPC90ZXh0PjwvZz4KICA8dGV4dCB4PSIyNCIgeT0iMTU3IiBmb250LWZhbWlseT0ic3lzdGVtLXVpLHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTYiIGZpbGw9IiM3Njg4YTIiPlJlY29uc3RydWN0aW9uIG5lZWRzIGZvdXIgc3Vydml2aW5nIHNoYXJkcyBpbiB0aGlzIGV4YW1wbGUuPC90ZXh0Pgo8L3N2Zz4=" alt="Illustrative erasure-coding layout: four data shards and two parity shards. Two missing shards can be reconstructed from the four remaining shards. Production recovery and write availability depend on the configured parity and placement." />
</div>

#### Bucket configuration

Configure bucket features at deployment or directly on MinIO. The described adapter does not forward runtime S3 bucket-configuration requests. MinIO supports versioning, expiration of current and noncurrent objects, and cleanup of incomplete multipart uploads. Encryption supports SSE-S3, SSE-C and SSE-KMS through the KES key server; DSSE-KMS and S3 Bucket Keys have no equivalent in this mapping.

Bucket replication copies objects between configured buckets. Site replication also replicates buckets and identity configuration, including users, groups and policies, across MinIO deployments. Choose the replication mode and recovery destinations for the application.

MinIO can send object events to webhooks, Kafka, AMQP, NATS, Redis and several databases. Configure these destinations on MinIO; the adapter rejects PutBucketNotificationConfiguration.

#### Storage and website limitations

MinIO's STANDARD and REDUCED\_REDUNDANCY classes select erasure-coding parity, not storage cost tiers. Lifecycle rules can move data to an external object store, but this mapping has no on-cluster Glacier-style class or Requester Pays billing mode.

The Community server does not implement configurable CORS in this mapping; verify support in the MinIO edition deployed. MinIO also has no S3 index/error-document website mode. A web server or reverse proxy can serve static content from the bucket. S3 analytics, inventory, Intelligent-Tiering and metrics configurations are outside this mapping.

#### Operations and migration

The customer supplies the disks and nodes, and Tensor9 operates the store as part of the Cloud Adapter deployment. Size usable capacity after accounting for parity and replication, and plan expansion and recovery around the actual drive and node layout.

New buckets start empty. Copy existing S3 objects and required versions before switching clients, then verify reads and version-dependent behavior. MinIO site replication can seed another MinIO deployment, including its identity configuration.

This adapter does not enforce S3 presigned-URL signatures and expiry. Use MinIO's native presigning or mc share for time-limited direct access. Moving away from the adapter requires changing client endpoints and credentials and preserving the bucket settings the application uses.

## On Scaleway

### Scaleway Object Storage

| Capability                       | Area       | Support      | Operations | Notes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| -------------------------------- | ---------- | ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SSE-C (customer key)             | Encryption | Supported    | -          | per-request customer-provided key accepted                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| SSE-KMS                          | Encryption | Out of scope | -          | rejected with 400 InvalidArgument, since Scaleway has no SSE-KMS                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| SSE-S3 (AES256)                  | Encryption | Supported    | -          | YOUR OBJECTS ARE ENCRYPTED AT REST AND THE RESPONSES SAY SO, as on S3. S3 encrypts every object and answers x-amz-server-side-encryption: AES256 on put, get and head whether or not you ask; Scaleway does neither unless the request asks. So the adapter ASKS -- it adds the SSE-S3 request to every object write where you did not specify encryption yourself -- and Scaleway then encrypts the object and reports the header on writes and reads alike. The header you read is the STORE's own statement, not the adapter's claim about someone else's storage; that distinction is why this is done on the request rather than synthesized on the response. A write that carries your OWN encryption choice, including an SSE-C customer key, is never overridden. Measured on a live drive 2026-09-14: with the request added, all nineteen certification cells match S3 exactly, and without it five of them diverged on this header alone. |
| Content-MD5 validation           | Integrity  | Supported    | -          | THE ADAPTER VALIDATES IT, which the raw Scaleway wire does not: a PutObject carrying a wrong Content-MD5 is answered 400 BadDigest in S3's own wording, and a correct one is accepted. Measured on the raw wire twice in August 2026, Scaleway ACCEPTS the wrong digest with 200 and returns an ETag of the actual body, so a client sending a digest for integrity gets none and cannot tell -- which is why this check is in the adapter. This row read OutOfScope until 2026-09-14, describing the wire rather than the product.                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Flexible checksum (CRC32)        | Integrity  | Partial      | -          | the adapter ACCEPTS the aws-chunked trailer and VERIFIES it against the bytes as they decode, refusing an upload whose payload contradicts its declared checksum. It does NOT echo one: measured 2026-09-14, the response carries no x-amz-checksum-\* and no x-amz-checksum-type where S3 answers both. The adapter removes the client's algorithm request when it de-frames the upload -- Scaleway refuses a request declaring a trailer that is no longer there -- so the store is never asked to compute one. A client that reads back the checksum its store recorded gets nothing. This row said 'accepted and echoed' until the first live drive measured the reply.                                                                                                                                                                                                                                                                          |
| GetObject (x-amz-te: append-md5) | Integrity  | Out of scope | -          | S3 honours this request header -- answering x-amz-transfer-encoding: append-md5 and a body 16 bytes longer, so a client can verify the bytes in flight. Scaleway does not implement it and the adapter does not emulate it: the object arrives with no appended digest and no answering header, and the content length is the object's own. Measured 2026-09-14 with both legs asked the same way.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| GetObject (If-Modified-Since)    | Objects    | Supported    | -          | 304 Not Modified                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| GetObject (Range)                | Objects    | Supported    | -          | 206 Partial Content                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| GetObject (missing key)          | Objects    | Supported    | -          | 404 NoSuchKey, in the S3 error envelope                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ListObjectsV2 (response framing) | Objects    | Partial      | -          | the listing itself matches; its HTTP framing does not. S3 streams the XML chunked with no Content-Length, Scaleway sends a Content-Length, and the adapter relays the store rather than re-chunking to match. A client that reads the listing through an SDK sees no difference; one that reads framing does. Measured 2026-09-14.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| PutObject (If-None-Match)        | Objects    | Supported    | -          | 412 PreconditionFailed, as S3                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| User metadata + Content-Type     | Objects    | Supported    | -          | arbitrary keys and casing round-trip through PUT → HEAD                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| Bucket versioning                | Versioning | Supported    | -          | version ids minted                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| Delete markers                   | Versioning | Supported    | -          | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |

| Operation                                | Area           | Support      | Depth        | Notes                                                                                                                                                                                                                                                                                                                                                                                     |
| ---------------------------------------- | -------------- | ------------ | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| DeleteBucketPolicy                       | Access control | Out of scope | Most usage   | refused with its Put sibling; see PutBucketPolicy                                                                                                                                                                                                                                                                                                                                         |
| GetBucketAcl                             | Access control | Out of scope | Most usage   | refused with its Put sibling; see PutBucketAcl                                                                                                                                                                                                                                                                                                                                            |
| GetBucketPolicy                          | Access control | Out of scope | Most usage   | refused with its Put sibling; see PutBucketPolicy                                                                                                                                                                                                                                                                                                                                         |
| GetObjectAcl                             | Access control | Out of scope | Full surface | the ?acl sub-resource is refused; configure access through Scaleway's permissions                                                                                                                                                                                                                                                                                                         |
| GetPublicAccessBlock                     | Access control | Out of scope | Most usage   | refused with its Put sibling; see PutPublicAccessBlock                                                                                                                                                                                                                                                                                                                                    |
| PutBucketAcl                             | Access control | Out of scope | Most usage   | MEASURED 501 - and real S3 refuses it too on a bucket created today, 400 AccessControlListNotSupported, because new buckets default to bucket-owner-enforced ownership. Both sides decline; only the code differs. Configure access through Scaleway's own permissions.                                                                                                                   |
| PutBucketOwnershipControls               | Access control | Out of scope | Full surface | the ?ownershipControls sub-resource is refused                                                                                                                                                                                                                                                                                                                                            |
| PutBucketPolicy                          | Access control | Out of scope | Most usage   | MEASURED 501: the adapter compiles no request-time policy evaluation in v1 and refuses rather than accept a policy it would never enforce - a policy accepted and unenforced would tell your application its access controls are in force when nothing evaluates them. Scaleway Object Storage DOES support bucket policy natively, so this is a gap in the adapter and not in the store. |
| PutObjectAcl                             | Access control | Out of scope | Full surface | the ?acl sub-resource is refused; configure access through Scaleway's permissions                                                                                                                                                                                                                                                                                                         |
| PutPublicAccessBlock                     | Access control | Out of scope | Most usage   | MEASURED 501. This is a SAFETY control - you set it to guarantee no object can become public, and your next action is to trust it - so accepting it without enforcing it would be the most dangerous silent success on this surface. It fails loud instead.                                                                                                                               |
| CreateBucket                             | Bucket config  | Supported    | Most usage   | -                                                                                                                                                                                                                                                                                                                                                                                         |
| DeleteBucket                             | Bucket config  | Supported    | Most usage   | -                                                                                                                                                                                                                                                                                                                                                                                         |
| GetBucketLocation                        | Bucket config  | Supported    | Most usage   | echoes the Scaleway region (fr-par), not an AWS one                                                                                                                                                                                                                                                                                                                                       |
| HeadBucket                               | Bucket config  | Supported    | Most usage   | -                                                                                                                                                                                                                                                                                                                                                                                         |
| AbortMultipartUpload                     | Multipart      | Supported    | Most usage   | aborted upload is then NoSuchUpload, as S3                                                                                                                                                                                                                                                                                                                                                |
| CompleteMultipartUpload                  | Multipart      | Supported    | Most usage   | composite ETag matches S3's -N form                                                                                                                                                                                                                                                                                                                                                       |
| CreateMultipartUpload                    | Multipart      | Supported    | Most usage   | -                                                                                                                                                                                                                                                                                                                                                                                         |
| ListParts                                | Multipart      | Supported    | Most usage   | -                                                                                                                                                                                                                                                                                                                                                                                         |
| UploadPart                               | Multipart      | Supported    | Most usage   | data integrity verified end to end                                                                                                                                                                                                                                                                                                                                                        |
| UploadPartCopy                           | Multipart      | Supported    | Most usage   | -                                                                                                                                                                                                                                                                                                                                                                                         |
| GetObjectLegalHold                       | Object lock    | Out of scope | Full surface | the object-lock sub-resources are refused                                                                                                                                                                                                                                                                                                                                                 |
| GetObjectRetention                       | Object lock    | Out of scope | Full surface | the object-lock sub-resources are refused                                                                                                                                                                                                                                                                                                                                                 |
| PutObjectLegalHold                       | Object lock    | Out of scope | Full surface | the object-lock sub-resources are refused                                                                                                                                                                                                                                                                                                                                                 |
| PutObjectRetention                       | Object lock    | Out of scope | Full surface | the object-lock sub-resources are refused                                                                                                                                                                                                                                                                                                                                                 |
| CopyObject                               | Objects        | Supported    | Most usage   | server-side copy with metadata REPLACE                                                                                                                                                                                                                                                                                                                                                    |
| DeleteObjects                            | Objects        | Supported    | Common       | batch delete                                                                                                                                                                                                                                                                                                                                                                              |
| GetObject                                | Objects        | Supported    | Common       | read-after-write returned the exact bytes                                                                                                                                                                                                                                                                                                                                                 |
| HeadObject                               | Objects        | Supported    | Common       | -                                                                                                                                                                                                                                                                                                                                                                                         |
| ListObjectsV2                            | Objects        | Supported    | Common       | pagination honoured                                                                                                                                                                                                                                                                                                                                                                       |
| PutObject                                | Objects        | Supported    | Common       | single-part ETag is the content MD5, matching S3                                                                                                                                                                                                                                                                                                                                          |
| GetBucketNotificationConfiguration       | Other features | Out of scope | Most usage   | refused with its Put sibling; see PutBucketNotificationConfiguration                                                                                                                                                                                                                                                                                                                      |
| GetBucketWebsite                         | Other features | Out of scope | Most usage   | refused with its Put sibling; see PutBucketWebsite                                                                                                                                                                                                                                                                                                                                        |
| GetObjectAttributes                      | Other features | Out of scope | Full surface | the ?attributes query is not served; use HeadObject                                                                                                                                                                                                                                                                                                                                       |
| PutBucketAccelerateConfiguration         | Other features | Out of scope | Full surface | the ?accelerate sub-resource is refused                                                                                                                                                                                                                                                                                                                                                   |
| PutBucketAnalyticsConfiguration          | Other features | Out of scope | Full surface | the ?analytics sub-resource is refused                                                                                                                                                                                                                                                                                                                                                    |
| PutBucketIntelligentTieringConfiguration | Other features | Out of scope | Full surface | the ?intelligent-tiering sub-resource is refused                                                                                                                                                                                                                                                                                                                                          |
| PutBucketInventoryConfiguration          | Other features | Out of scope | Full surface | the ?inventory sub-resource is refused                                                                                                                                                                                                                                                                                                                                                    |
| PutBucketLogging                         | Other features | Out of scope | Full surface | the ?logging sub-resource is refused                                                                                                                                                                                                                                                                                                                                                      |
| PutBucketMetricsConfiguration            | Other features | Out of scope | Full surface | the ?metrics sub-resource is refused                                                                                                                                                                                                                                                                                                                                                      |
| PutBucketNotificationConfiguration       | Other features | Out of scope | Most usage   | MEASURED 501: event notification is served by neither plane, so a configuration accepted here would leave your application waiting on events nobody will send - a silence that looks like an empty bucket rather than a failure.                                                                                                                                                          |
| PutBucketReplication                     | Other features | Out of scope | Full surface | the ?replication sub-resource is refused                                                                                                                                                                                                                                                                                                                                                  |
| PutBucketWebsite                         | Other features | Out of scope | Most usage   | MEASURED 501: website hosting changes how the bucket answers ANONYMOUS reads at an endpoint this adapter does not front, so a configuration accepted here would describe a site nobody serves.                                                                                                                                                                                            |
| RestoreObject                            | Other features | Out of scope | Full surface | the ?restore query is refused                                                                                                                                                                                                                                                                                                                                                             |
| SelectObjectContent                      | Other features | Out of scope | Full surface | the ?select query is refused                                                                                                                                                                                                                                                                                                                                                              |
| ListObjectVersions                       | Versioning     | Supported    | Most usage   | -                                                                                                                                                                                                                                                                                                                                                                                         |

#### S3 requests in the target environment

The application continues using the S3 API. The Tensor9 adapter runs in the target environment and sends object requests to Scaleway Object Storage. It also serves bucket creation, deletion, listing, and configuration through a persistent bucket store. Scaleway Object Storage stores the objects; Tensor9 operates the adapter and its bucket-management service.

#### Request flow

Object requests use the target storage service. Bucket settings persist separately and are applied to the target resource.

<div className="t9-diagram-scroll" role="region" aria-label="Scrollable diagram" tabIndex={0}>
  <img className="t9-diagram-light" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjI4OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDI4OCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgUzMgYXBwbGljYXRpb24gY2FsbHMgdGhlIFRlbnNvcjkgYWRhcHRlci4gT2JqZWN0IHJlcXVlc3RzIGdvIHRvIHRoZSB0YXJnZXQgb2JqZWN0IHN0b3JlLiBCdWNrZXQgc2V0dGluZ3MgcGVyc2lzdCBpbiB0aGUgYWRhcHRlcidzIHN0b3JlIGFuZCBhIGNvbmZpZ3VyYXRpb24gd29ya2VyIGFwcGxpZXMgdGhlbSB0byB0aGUgdGFyZ2V0LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgogIDxkZWZzPjxtYXJrZXIgaWQ9InMzLW1heC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI4NCIgcng9IjEwIiBmaWxsPSIjZWZmNmZmIiBzdHJva2U9IiM5M2M1ZmQiLz4KICA8cmVjdCB4PSIzMTAiIHk9IjM2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9Ijg0IiByeD0iMTAiIGZpbGw9IiNlY2ZkZjUiIHN0cm9rZT0iIzZlZTdiNyIvPgogIDxyZWN0IHg9IjU5NiIgeT0iMzYiIHdpZHRoPSIyMjAiIGhlaWdodD0iODQiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjOTRhM2I4Ii8+CiAgPHJlY3QgeD0iMzEwIiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iI2VjZmRmNSIgc3Ryb2tlPSIjNmVlN2I3Ii8+CiAgPHJlY3QgeD0iNTk2IiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjOTRhM2I4Ii8+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE2IiBmaWxsPSIjMGYxNzJhIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj4KICAgIDx0ZXh0IHg9IjEzNCIgeT0iNzAiPkFwcGxpY2F0aW9uPC90ZXh0Pjx0ZXh0IHg9IjEzNCIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPlMzIFNESzwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iNzAiPlRlbnNvcjkgUzMgYWRhcHRlcjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3QgYW5kIGJ1Y2tldCBBUElzPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSI3MCI+U2NhbGV3YXkgT2JqZWN0IFN0b3JhZ2U8L3RleHQ+PHRleHQgeD0iNzA2IiB5PSI5NiIgZm9udC1zaXplPSIxNCI+T2JqZWN0cyBhbmQgc3RvcmFnZTwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iMjEyIj5QZXJzaXN0ZW50IGJ1Y2tldCBzdG9yZTwvdGV4dD48dGV4dCB4PSI0MjAiIHk9IjIzNiIgZm9udC1zaXplPSIxNCI+TmFtZXMgYW5kIGNvbmZpZ3VyYXRpb248L3RleHQ+CiAgICA8dGV4dCB4PSI3MDYiIHk9IjIyNCI+Q29uZmlndXJhdGlvbiB3b3JrZXI8L3RleHQ+CiAgPC9nPgogIDxnIHN0cm9rZT0iIzY0NzQ4YiIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBtYXJrZXItZW5kPSJ1cmwoI3MzLW1heC1hcnJvdykiPgogICAgPHBhdGggZD0iTTI0NCA3OCBIMzA2Ii8+PHBhdGggZD0iTTUzMCA3OCBINTkyIi8+PHBhdGggZD0iTTQyMCAxMjAgVjE4MCIvPgogICAgPHBhdGggZD0iTTUzMCAyMTggSDU5MiIvPjxwYXRoIGQ9Ik03MDYgMTg0IFYxMjQiLz4KICA8L2c+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjEyIiBmaWxsPSIjNDc1NTY5Ij4KICAgIDx0ZXh0IHg9IjQzMiIgeT0iMTUzIj5CdWNrZXQgc2V0dGluZ3M8L3RleHQ+PHRleHQgeD0iNzE4IiB5PSIxNTQiPkFwcGx5PC90ZXh0PgogIDwvZz4KPC9zdmc+" alt="The S3 application calls the Tensor9 adapter. Object requests go to the target object store. Bucket settings persist in the adapter's store and a configuration worker applies them to the target." />

  <img className="t9-diagram-dark" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODQwIiBoZWlnaHQ9IjI4OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgODQwIDI4OCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgUzMgYXBwbGljYXRpb24gY2FsbHMgdGhlIFRlbnNvcjkgYWRhcHRlci4gT2JqZWN0IHJlcXVlc3RzIGdvIHRvIHRoZSB0YXJnZXQgb2JqZWN0IHN0b3JlLiBCdWNrZXQgc2V0dGluZ3MgcGVyc2lzdCBpbiB0aGUgYWRhcHRlcidzIHN0b3JlIGFuZCBhIGNvbmZpZ3VyYXRpb24gd29ya2VyIGFwcGxpZXMgdGhlbSB0byB0aGUgdGFyZ2V0LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgogIDxkZWZzPjxtYXJrZXIgaWQ9InMzLW1heC1hcnJvdyIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iOCIgcmVmWD0iNyIgcmVmWT0iNCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNMCwwIEw4LDQgTDAsOCBaIiBmaWxsPSIjNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgogIDxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI4NCIgcng9IjEwIiBmaWxsPSIjMWEyNDMxIiBzdHJva2U9IiMzZDUwNjYiLz4KICA8cmVjdCB4PSIzMTAiIHk9IjM2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9Ijg0IiByeD0iMTAiIGZpbGw9IiMxYTMxMjYiIHN0cm9rZT0iIzNkNjY1NSIvPgogIDxyZWN0IHg9IjU5NiIgeT0iMzYiIHdpZHRoPSIyMjAiIGhlaWdodD0iODQiIHJ4PSIxMCIgZmlsbD0iIzFhMjYzMSIgc3Ryb2tlPSIjNDE0ZTYyIi8+CiAgPHJlY3QgeD0iMzEwIiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iIzFhMzEyNiIgc3Ryb2tlPSIjM2Q2NjU1Ii8+CiAgPHJlY3QgeD0iNTk2IiB5PSIxODQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNjgiIHJ4PSIxMCIgZmlsbD0iIzFhMjYzMSIgc3Ryb2tlPSIjNDE0ZTYyIi8+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjE2IiBmaWxsPSIjNTU3NmMyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj4KICAgIDx0ZXh0IHg9IjEzNCIgeT0iNzAiPkFwcGxpY2F0aW9uPC90ZXh0Pjx0ZXh0IHg9IjEzNCIgeT0iOTYiIGZvbnQtc2l6ZT0iMTQiPlMzIFNESzwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iNzAiPlRlbnNvcjkgUzMgYWRhcHRlcjwvdGV4dD48dGV4dCB4PSI0MjAiIHk9Ijk2IiBmb250LXNpemU9IjE0Ij5PYmplY3QgYW5kIGJ1Y2tldCBBUElzPC90ZXh0PgogICAgPHRleHQgeD0iNzA2IiB5PSI3MCI+U2NhbGV3YXkgT2JqZWN0IFN0b3JhZ2U8L3RleHQ+PHRleHQgeD0iNzA2IiB5PSI5NiIgZm9udC1zaXplPSIxNCI+T2JqZWN0cyBhbmQgc3RvcmFnZTwvdGV4dD4KICAgIDx0ZXh0IHg9IjQyMCIgeT0iMjEyIj5QZXJzaXN0ZW50IGJ1Y2tldCBzdG9yZTwvdGV4dD48dGV4dCB4PSI0MjAiIHk9IjIzNiIgZm9udC1zaXplPSIxNCI+TmFtZXMgYW5kIGNvbmZpZ3VyYXRpb248L3RleHQ+CiAgICA8dGV4dCB4PSI3MDYiIHk9IjIyNCI+Q29uZmlndXJhdGlvbiB3b3JrZXI8L3RleHQ+CiAgPC9nPgogIDxnIHN0cm9rZT0iIzY0NzQ4YiIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIiBtYXJrZXItZW5kPSJ1cmwoI3MzLW1heC1hcnJvdykiPgogICAgPHBhdGggZD0iTTI0NCA3OCBIMzA2Ii8+PHBhdGggZD0iTTUzMCA3OCBINTkyIi8+PHBhdGggZD0iTTQyMCAxMjAgVjE4MCIvPgogICAgPHBhdGggZD0iTTUzMCAyMTggSDU5MiIvPjxwYXRoIGQ9Ik03MDYgMTg0IFYxMjQiLz4KICA8L2c+CiAgPGcgZm9udC1mYW1pbHk9InN5c3RlbS11aSxzYW5zLXNlcmlmIiBmb250LXNpemU9IjEyIiBmaWxsPSIjNzY4OGEyIj4KICAgIDx0ZXh0IHg9IjQzMiIgeT0iMTUzIj5CdWNrZXQgc2V0dGluZ3M8L3RleHQ+PHRleHQgeD0iNzE4IiB5PSIxNTQiPkFwcGx5PC90ZXh0PgogIDwvZz4KPC9zdmc+" alt="The S3 application calls the Tensor9 adapter. Object requests go to the target object store. Bucket settings persist in the adapter's store and a configuration worker applies them to the target." />
</div>

#### Object requests

Scaleway speaks the S3 protocol. The adapter changes the endpoint and signs with a Scaleway API key, while the service handles objects, ranges, conditional requests, copies, batch deletion and paginated listing. The endpoint uses the selected Scaleway region, such as s3.fr-par.scw\.cloud. The adapter still provides the S3 endpoint expected by the application.

#### Bucket creation and configuration

Each S3 bucket has a durable record containing its name, owner, requested configuration, and target reference. For a bucket named `bucket-name`, the S3-facing identifier is `arn:aws:s3:::bucket-name`; the target resource is a Scaleway Object Storage bucket. `ListBuckets` returns the caller's buckets, and configuration reads use the stored request state.

A configuration worker applies the stored settings to the target. `CreateBucket` waits for the target bucket to be ready before returning success, so an immediate object write does not race bucket creation. `DeleteBucket` waits for removal and returns `BucketNotEmpty` if objects prevent deletion. A lifecycle update also waits for target application. For other configuration changes, a successful read of the new setting describes stored configuration; it does not imply every target-side change has already completed.

#### Versions and multipart uploads

Scaleway supplies multipart upload, ListParts, UploadPartCopy, composite ETags, version IDs and delete markers natively. Max therefore retains those provider behaviors while adding the persistent bucket-management service. Multipart completion keeps the S3 part-count ETag form, and version listing exposes the provider's version history.

#### Target configuration

The Max adapter stores bucket ownership and requested configuration, then reconciles that state to Scaleway. Bucket creation, deletion and versioning already have native S3 operations on the provider; the persistent record gives the application the same management model used with the other targets. Storage-class translation is separate from API compatibility and must retain the selected class and region constraints.

#### Placement and operation

Scaleway operates the object store; Tensor9 operates the S3 adapter and its persistent bucket-management service. The recorded August 20, 2026 fidelity run verified object reads and writes, byte ranges, conditional responses, copy, batch delete, pagination, metadata, multipart operations and versioning. These are compatibility results, not a throughput, latency or durability measurement.

#### Compatibility limits

SSE-S3 and customer-supplied-key encryption are supported, and objects are encrypted at rest with the responses reporting it as S3 does, because the adapter requests SSE-S3 on every write that does not carry your own choice; SSE-KMS is outside this mapping. Content-MD5 IS validated by the adapter, answering 400 BadDigest as S3 does, which the raw Scaleway wire does not. Bucket notification and bucket policy APIs are unsupported. The Max management service does not by itself remove these operation-level differences.

#### Migration and leaving the adapter

A newly provisioned target bucket starts empty. Copy existing objects and required versions with a migration tool or a coordinated dual-write, then verify object data and application reads before switching. Preserve version history through the S3 API when the application depends on S3 version identifiers or delete markers.

Leaving the Max adapter requires moving bucket configuration as well as object data. Apply the retained settings to native target resources, resolve any S3-specific version metadata, and move clients to the target's own API. Keep the adapter and its persistent state until the application no longer depends on those S3 behaviors.

## Existing data and credentials

Selecting a backend does not copy existing data, credentials or access policies. Plan and verify migration separately before changing an application's endpoint. Do not assume an identifier, credential or encrypted value from the origin service works unchanged on the target.

## Configure, tune and debug

Start with [setup](/cloud-adapter/getting-started/overview) and [configuration](/cloud-adapter/configuration/overview). Use [tuning](/cloud-adapter/tuning/overview) to understand supported request tags, [debugging](/cloud-adapter/debugging/overview) to investigate a request, and [High Fidelity Cloud Emulators](/cloud-adapter/local-testing/overview) to validate a bounded reproduction.
