S3 clients¶
A zone is a bucket. Point rclone, the AWS CLI, s3cmd or anything built on boto at the endpoint and they work unmodified, so syncing a tree needs no client of this service's own.
Credentials¶
A token becomes an S3 key pair. The access key id is the token's key id; the secret is derived from it and from CDN_SECRET_KEY.
cdn_a1b2c3d4e5f6_… ← the bearer token, for the HTTP API
S3 access key id: a1b2c3d4e5f6
S3 secret key: …
S3 endpoint: https://cdn.example.com/_/s3
Because the secret is derived rather than stored, rotating CDN_SECRET_KEY invalidates every S3 credential at once.
rclone¶
# ~/.config/rclone/rclone.conf
[cdn]
type = s3
provider = Other
endpoint = https://cdn.example.com/_/s3
access_key_id = a1b2c3d4e5f6
secret_access_key = …
region = us-east-1
force_path_style = true
force_path_style matters: the bucket is a path segment, because a host with no wildcard DNS cannot put it in a subdomain.
rclone sync over an unchanged tree moves nothing. It keeps each file's modification time in x-amz-meta-mtime, which this service stores and returns; without that it would decide on every run that every file needed its timestamp rewritten, and issue one copy per file for ever.
AWS CLI¶
aws --endpoint-url https://cdn.example.com/_/s3 s3 ls s3://assets/
aws --endpoint-url https://cdn.example.com/_/s3 s3 cp ./logo.png s3://assets/img/
s3cmd, and the hostname it needs¶
s3cmd folds an endpoint's path into the Host header it signs — host:cdn.example.com/_/s3/assets — so no signature it produces can match a service mounted under a path. Give the S3 face a hostname of its own and it works like any other client:
Point that name at the same process. The bucket is then the first path segment of that host, every client agrees about what was signed, and the delivery namespace is untouched: one process, two faces.
# ~/.s3cfg
host_base = s3.example.com
host_bucket = s3.example.com
access_key = a1b2c3d4e5f6
secret_key = …
What is implemented¶
The subset those clients use to sync files:
| operation | notes |
|---|---|
ListBuckets |
the zones this credential can reach |
HeadBucket, CreateBucket |
creating one needs the write scope |
ListObjectsV2, ListObjects |
prefix, delimiter and paging; v1 for older providers |
PutObject |
including aws-chunked streaming bodies |
CopyObject |
what rclone uses to rewrite a timestamp |
GetObject, HeadObject |
ranges and conditional requests |
DeleteObject, DeleteObjects |
the batch form clears a tree quickly |
Anything else answers 501 NotImplemented in the XML clients expect, rather than HTML or an empty body — a client that gets those reports something unrelated to what went wrong. Multipart upload is not implemented; CDN_MAX_UPLOAD_BYTES governs how large a single request may be.
Details, including how signatures are verified, are in the S3 API reference.