Everything below ships today

Capabilities

The full surface, grouped the way an evaluation reads it. What is planned rather than built is kept on its own, at the end.

The S3 API your clients already speak

Arcois Gateway implements the S3 surface that object-storage clients use in practice. If a request carries a subresource the gateway does not implement, the gateway answers with a not-implemented error instead of falling through to the plain verb. The client learns the feature is absent rather than believing the call succeeded.

Objects and buckets

The operations every S3 client issues, answered from the gateway's own records.

  • Put, get, head, delete and copy objects; list objects with both the original and the continuation-token listing; list, create and delete buckets
  • Batch delete, bucket location, bucket ownership controls, and object attributes
  • The whole multipart lifecycle, including parts copied from an object that already exists and composite ETag fidelity on a multipart-preserving copy
  • Browser form uploads over POST, with policy parsing and validation

Versioning and conditionals

Versioning can be enabled or suspended, and a suspended bucket still holds the versions it accumulated while enabled.

  • Version listings and delete markers
  • If-match, if-none-match, if-modified-since and if-unmodified-since on reads and heads
  • MD5 ETags computed on ingest and returned on every read

Addressing

Path-style addressing is always available. Virtual-host-style addressing is switched on by naming your base domains.

  • Signatures are verified against the request as the client sent it, before any rewrite, so header authentication, presigned URLs and chunked uploads all work unchanged
  • Cross-origin rules are configured per bucket and matched by the gateway

Metadata, tags and checksums

What a client attaches to an object comes back exactly as it was sent.

  • Arbitrary user metadata stored and returned transparently; content type sniffed from the data when the client does not supply one
  • Object and bucket tagging, with the metadata and tagging copy directives honoured
  • CRC32, CRC32C, SHA-1, SHA-256 and CRC64NVME on single and multipart objects, including composite checksum computation

Lifecycle rules

Expiry configured per bucket and evaluated by a background worker, one per tenant.

  • Current-version and non-current-version expiration, expired delete-marker cleanup, and abort of incomplete multipart uploads
  • Expiration and abort-date response headers computed by the same evaluator the worker uses, so the header and the eventual deletion cannot disagree
  • Lifecycle expiry raises the same event notifications as any other delete

Aggregation and the storage layout

The mechanism that takes object count off your backend, and the housekeeping that keeps it honest.

Sealed volumes

Small objects are packed into volume files written directly, with no temporary file in between, and sealed with a manifest of their contents.

  • Rotation on size or age, with a size floor and a configurable pool of open volumes per bucket and target
  • Volumes stored under a reserved key namespace, and client writes into that namespace refused
  • A read is one byte-range request for exactly that object's bytes — reading a 40 KB object moves 40 KB, never the volume around it, and a client's own range narrows it further
  • Large objects written straight to the backend, and streamed as a multipart upload above a further configurable size
  • Aggregation can be switched off for a whole placement policy when a workload does not benefit

Reclamation and compaction

Deleting an object inside a volume frees backend capacity when that volume is compacted, so reclamation is background work.

  • Live bytes and live object counts tracked per volume, so compaction knows what is worth rewriting
  • A reverse index, maintained in the same transaction as the current-version pointer. Answering what is still live on a volume then costs the number of live objects, not a full scan
  • Automatic compaction dispatched cluster-wide, one batch per tick
  • Volumes whose buckets no longer exist are detected and cleaned up

Storage classes and tiering

A placement's name doubles as a storage class. There is no mapping table to maintain and no second API — any placement you have defined is usable as a storage class by name.

  • A client that names a placement in the standard storage-class header writes that object there instead of the bucket's usual target
  • Each bucket carries an allowlist of the placements it will accept, empty by default and operator-controlled, so a tenant cannot route its data somewhere you did not offer
  • Lifecycle rules move data between placements on a schedule. Bytes are copied verbatim, with no decrypt and re-encrypt, then the pointer flips; a client write landing mid-transition wins
  • Transition copies are throttled per pod, by worker count and by a byte-rate ceiling
  • AWS storage-class tokens are stored and echoed untouched, so existing clients are unaffected

Disk pressure and spill

Local disk on a gateway pod is a staging area. It is treated as a resource with limits.

  • Above a spill threshold, objects that would have been aggregated take the direct path instead
  • Above a higher pressure threshold, aggregated writes are refused while direct writes carry on
  • When pressure clears, a background worker re-packs the spilled objects into volumes verbatim, without decrypting and re-encrypting them

Multi-tenancy, identity and billing

The platform layer between a raw object store and a customer who pays for storage.

Realms

A realm is an isolated tenant namespace. Buckets, credentials, policies and usage counters each belong to exactly one, and no realm can read another's data.

  • Tenant records are scoped by realm in the key space, so isolation is structural rather than a filter applied at read time
  • A request's realm is resolved from the credential it carries, never declared by the caller
  • A built-in realm preserves single-tenant behaviour, so a deployment that does not sell storage never has to think about realms

Quotas and metering

Every write passes a quota check before a backend is addressed.

  • A soft quota records and reports the breach and lets the write through; a hard quota refuses it with a storage-full response
  • Deletes are never quota-gated, so a tenant over quota can always recover
  • A background loop reconciles counter drift against the real usage
  • A daily record per tenant of stored bytes and object count, kept for a configurable period, is the input to billing and to capacity trends

Authorisation

Every request to the S3 endpoint, list-buckets included, flows through a policy engine shaped like the one your clients already write policies for.

  • Evaluation runs in a fixed order: realm-administrator bypass, bucket policy, public-access block, identity policy, the bucket owner's implicit allowance, and default deny at the floor
  • Ownership sits last, so an explicit denial above it wins
  • A copy request is authorised twice, for the destination and for the source object, before the source is read
  • Identity policies, bucket policies, block-public-access settings and policy conditions

Tenant self-service identity

Tenants administer their own identity with the tools they already have, without an operator in the loop.

  • An identity-and-access surface on the S3 port that the standard aws iam and aws sts command-line tools drive directly: users, access keys, policies, roles and external identity providers
  • Temporary credentials through session tokens, role assumption, and role assumption from a federated web identity, with an expiry sweeper for session credentials
  • A role session is authorised from the role's own policies, so it inherits nothing from the caller
  • The operator-side administrative surface stays authoritative over all of it

Operator and administrator access

The administrative interface authenticates separately from the S3 endpoint.

  • An OpenID Connect provider is built in, so a new cluster has administrator login before any external identity system exists. An operator who already has one federates to it instead
  • Every administrative route is gated on a capability carried by the caller's role, and roles are assigned within a realm
  • Automation uses service accounts holding opaque tokens. A token rotates with a grace period rather than in one step
  • A break-glass command-line path for the case where login itself is broken

Running it

One control plane addresses every registered backend, and one identity and policy model covers every tenant on all of them. Runbooks, alert thresholds and access reviews are written once against the gateway rather than once per storage system.

Web console

A browser console for operators and for tenants, signing in through the same OpenID Connect flow as the rest of the administrative interface.

  • Overview and usage metering, realms, backends, placements, buckets with an object browser and per-subresource settings, credentials, identity and access management, administrators and identity providers
  • Data-movement operations, disaster recovery and geo-replication, each with typed confirmations on the destructive steps
  • A live event tail and a maintenance screen
  • Name and logo are read at runtime, so a deployed console can be rebranded without rebuilding the image

Operator command line

A single binary with contexts, in the shape administrators already know from cluster tooling.

  • Realms, credentials, backends, buckets, placements, operations, identity, providers, service accounts, notification topics, usage, maintenance, disaster recovery and geo-replication
  • Management goes through the administrative interface; a read-only path into the metadata plane exists for diagnosis
  • Records are decoded and secrets scrubbed before anything is printed

Metrics and diagnostics

Instrumented for the questions an on-call rota actually asks.

  • A Prometheus scrape endpoint covering request rates and latency, in-flight work, volume lifecycle, backend health, the metadata plane, data-movement progress, disk, and per-tenant usage and quota
  • Two provisioned dashboards, one operational and one per tenant
  • Structured logging with request identifiers and per-request latency, an error ring buffer, and a diagnostic bundle endpoint
  • Processor, memory, trace and goroutine profiling on the administrative port

Statistics a backend cannot answer

Because the gateway holds the meaning, it can answer questions about what you store that a storage system has no way to answer.

  • Stored bytes and object count per tenant, moved on every write and delete, and reconciled against real usage by a background pass
  • A daily record per tenant, kept for as long as you configure — what you invoice from, and what you plot capacity trends against
  • Current usage with its quota settings and which quotas are in breach, the list of dates that have records, and any single one of them
  • Chart-ready time series for read and write throughput, operation rates and 95th-percentile latency, over ranges from fifteen minutes to seven days, fleet-wide or for one tenant
  • Object counts per bucket answered from the gateway's own rows, with nothing enumerated on the backend

Event notifications

Bucket events posted to webhooks the operator registers.

  • Standard notification configuration on buckets, with topic names resolving against an operator registry
  • Delivery is signed with a shared secret when the topic carries one, and never blocks the write path
  • A per-endpoint circuit breaker, a sharded dead-letter queue with its own retry worker, and a live tail for debugging
  • The destination address is checked against operator-blocked ranges as the connection is made, so a tenant cannot aim a notification at an internal address

Scale and availability

Three workloads on Kubernetes or OpenShift, with no node whose loss stops the service.

  • The gateway tier is active-active: every pod is equal, every pod serves every request, one address in front of all of them
  • Background jobs are held by lease rather than by an elected leader, so a pod that dies simply releases its work for another to pick up
  • The metadata store is Raft-replicated across three or more nodes, with leaders elected per key range and spread across them, alongside a three-replica placement driver
  • Both tiers scale while serving traffic, by changing a replica count
  • Liveness and readiness probes and a pod disruption budget on every tier, so a rolling upgrade or a node drain stays inside the budget you set
  • OpenShift installations get a service account and security context constraints with the manifests

Your own certificate authority

Nearly everything the gateway calls outbound sits inside your network, and in an enterprise or a sovereign installation those endpoints present certificates from an internal authority.

  • A certificate authority bundle per backend, given at registration, and per notification topic
  • Bundles for the peer and the witness of a replicated pair
  • The bundle is write-only: no route reads it back, and a listing returns only its SHA-256 fingerprint
  • Verification can be switched off per backend for a lab, and a Prometheus gauge reports every backend running that way, so you can alert on it rather than discover it later

Written runbooks

Operator runbooks ship with the product, organised by what you are doing rather than by the subsystem that implements it.

  • Ten domains: data movement, replication between sites, identity and authentication, tenant lifecycle, placement, backend registration and retirement, notifications, the S3 feature surface, capacity and disk pressure, and a per-feature alerting guide
  • Written as procedures with the commands in them, including the ones nobody wants to improvise: recovering a lost cluster, promoting a site during an outage, rebuilding a replica that has fallen behind, and resetting administrator access when login itself is broken

Configuration and deployment

Configuration is environment-driven, with the operationally useful knobs changeable while running.

  • Runtime configuration read, patched and audited through the administrative interface, validated before it is applied, with the last good value kept if a change does not validate
  • An environment-pinned value always beats the stored overlay, so a deliberate pin cannot be edited away
  • Container images and Kubernetes manifests, with the console shipped as its own deployable artefact behind a web server
  • Server access logging in both the standard format and an extended journal mode, with key-name filters and deterministic key layouts

Access logging

Server access logs delivered into a bucket you nominate.

  • The standard format, plus a compact journal mode covering mutating operations only, delivered before the write commits
  • Deterministic simple and partitioned key layouts, key-name filters, batch sealing by record count, and an explicit flush endpoint
  • Sources that share a target bucket and prefix aggregate into one delivery group

Covered on their own pages

Placement policies, write acknowledgement, owed copies and the five data-movement operations are set out under how it works, because they only make sense alongside the write path. Encryption, retention, authorisation, geo-replication and disaster recovery are under security and resilience, with the limits on the same page.

What we are building next

In order, because each step rests on the one before it. Tape is the one under active development.

Tape and cold archive

Data ages down to cheap disk and finally onto tape in your own racks: offline, air-gapped, and held for as long as your regulator asks, with no retrieval bill from anyone else. Two of the three pieces already ship. Aggregation gives a tape drive the long continuous run it wants, and lifecycle transitions already move data down a tier on a schedule, which is why ageing onto cheap disk works today. What is being built is the last hop onto offline media, and the restore path back.

A backend layer that is not tied to S3

The rule the product rests on asks very little of a backend: store a blob, return a byte range from it, delete it, list keys. Anything that can do those four things can hold the bytes, because none of the meaning is kept there. Opening the write path up to that narrow contract is designed, and it is what everything cross-vendor is built on.

Native adapters for stores that do not speak S3

Written against that contract, for hyperscaler object storage reached through its own protocol and for shared filesystems reached over a network. Each one is an adapter rather than a change to the gateway, so adding one does not disturb anything already running.

Everything in the sections above this one is in the product today. We keep the two lists apart on purpose, so you always know which is which.

Bring your own object count and we will work through the arithmetic

You already know your object count and size distribution. That is everything needed to work out what your backend would hold after aggregation, before anyone signs anything.