Creating a bucket
- Console
- API
- CLI
- Go
Go to Storage → Buckets and choose Create Bucket. Bucket Name
is the only thing you have to fill in; Versioning, Default
encryption, Deletion protection and Tags are on the same form.Those extras are applied as separate calls once the bucket exists, so the
bucket is created even if one of them fails, and the console tells you
which one did.
3–63 characters
required
Lowercase letters, digits and hyphens. Must start and end with a letter or
digit, must not contain a double hyphen (
--), and must not be shaped
like an IP address.buckets quota; exhausting it is
also a 409 on create.
Object Lock has to be decided here
PUT /v1/buckets/{bucket}/object-lock updates the default retention rule on a
bucket that already has Object Lock enabled. Against a bucket that does not, it
is a 409 — object lock must be enabled at bucket creation.
Turning Object Lock on is API only. It has to ride on the call that
creates the bucket, and the console’s Create Bucket form does not send it
— the bucket is created without Object Lock, and the follow-up configuration
is refused with that same
409. Create the bucket through the API when you
need Object Lock.On a bucket that already has it, the console does edit the rule: the Object
Lock card on the bucket’s Settings tab carries the Default retention
rule, with a Mode and a Retention period.Bucket settings in the native API
The settings endpoints use the same top-level fields forGET responses and
PUT requests:
The rules arrays have no extra configuration wrapper. Object Lock’s
object_lock_rule contains default_retention. Lifecycle updates require the
current revision in If-Match; see Lifecycle rules.
These shapes apply to the native API. S3 clients continue to use the standard
S3 configuration formats.
Pointing an S3 client at it
Set a custom endpoint and sign with your Basaltic access key. Nothing else about the client changes.Credentials
Credentials
The same access keys you use everywhere else. A service account’s long-lived
key needs nothing extra; temporary credentials from STS — a role session or
a user session — must also carry the session token, and are rejected
without it.See authentication for how to obtain each.
Addressing style
Addressing style
Both styles work. Virtual-hosted
(
https://my-app-assets.objects.sa-saopaulo-1.basaltic.cloud/key) is what
most SDKs default to; path-style
(https://objects.sa-saopaulo-1.basaltic.cloud/my-app-assets/key) is
available through your client’s addressing-style option.The region string
The region string
Set
region_name to the Basaltic region code. The value is not checked
against the region serving the request — it only has to match what your
client signed with — so a tool hard-wired to us-east-1 still works.
GetBucketLocation reports the real region.Clock skew and presigned URLs
Clock skew and presigned URLs
A signed request must be within 15 minutes of the server’s clock, or it
is rejected as too skewed. Presigned URLs are supported with an expiry
between 1 second and 7 days, and a URL dated in the future beyond the
skew tolerance is refused rather than becoming valid later.
What the S3 endpoint serves
The endpoint is verified against a real AWS SDK rather than a specification of our own — if boto3 can do it and gets S3’s error codes back, it works. What is routed today:Buckets
ListBuckets, CreateBucket, HeadBucket, DeleteBucket, GetBucketLocation, and
the
?policy, ?cors, ?lifecycle, ?versioning, ?encryption,
?tagging, ?object-lock and ?acl sub-resources.Objects
PutObject, GetObject (including range requests), HeadObject, DeleteObject,
DeleteObjects, CopyObject, ListObjects, ListObjectsV2, ListObjectVersions,
and the
?tagging, ?retention, ?legal-hold and ?acl sub-resources.Multipart
CreateMultipartUpload, UploadPart, UploadPartCopy, ListParts,
ListMultipartUploads, CompleteMultipartUpload, AbortMultipartUpload.
Payload signing
Signed payloads,
UNSIGNED-PAYLOAD, and signed aws-chunked streaming
uploads. The body is re-hashed as it streams, so a body that does not match
what was signed is rejected mid-flight.NotImplemented. Preflight OPTIONS
requests are answered without a signature, because browsers never sign them.
Deleting a bucket
DELETE /v1/buckets/{bucket} does two quite different things depending on
whether deletion protection is on. Protection is deliberately off by default
for S3 parity: unlike Secrets and KMS, unprotected buckets have no recovery window.
- Protection off (default)
- Protection on
The bucket must be empty. Any remaining objects, versions or in-flight
multipart uploads make it a
409 BucketNotEmpty. An empty bucket is
deleted immediately and the quota slot is released.- Console
- API
- CLI
- Go
The Deletion protection card on the bucket’s Settings tab is a
switch alongside Recovery window (days). Save applies both.
recovery_window_days accepts whole numbers from 1–30. Omitting every
window field uses 7 days. Invalid values return 400, including when
turning protection off.
Release note: recovery fields
Bucket responses exposerecovery_window_days, scheduled_purge_at and
nullable deleted_at. Protected DELETE returns 200 with scheduled_purge_at;
immediate DELETE returns 204.
Breaking behavior change: invalid windows return 400
The service previously silently clamped windows: values below 1 selected 7 days, and values above 30 selected 30 days. It now rejects them with400 instead.
For example, asking for 60 days fails; it no longer schedules a purge after only
30 days. Explicit zero is also invalid; omit the window fields to select the
7-day default. Fractional days are invalid. Update callers that relied on
clamping separately from adopting the new field names.
During a rolling deployment, old service instances can still apply their old
clamping behavior; rejection is universal once all instances are updated.
