Storage accounts
A storage account is a place where the File Service stores bytes. The platform storage (default) holds every tenant’s files until you give a tenant storage of its own. This page is for platform administrators: it covers the Storage accounts page of platform administration and the routes behind it. What tenants notice (almost nothing) is on Where files are stored.
Accounts
Section titled “Accounts”The page lists every account, default first, with its kind, location, status and the number of tenants assigned to it.
| Kind | What you enter |
|---|---|
| A bucket | The bucket, its region (auto for stores without regions), the endpoint of the object store (empty: the store’s own default), path-style addressing (most compatible object stores need it), an optional public URL for public files (a CDN in front of the bucket), and an access key id and secret |
| A directory | A directory of the servers the service runs on, inside a root the operator allowed. Only where the platform allows directories; elsewhere storage_adapter_not_allowed |
Saving probes the account first. The service writes, reads, signs and deletes a small probe object in it, and saves the account only when that worked; otherwise the answer is storage_account_verification_failed with the store’s own error message. Verify runs the probe again and records the outcome: an account whose last probe failed (status: failed, with last_error) takes no new tenant and no move (storage_account_not_verified).
- The secret key is stored encrypted and never shown again: the page shows that keys are set and the last four characters of the key id. Rotating the keys is a change of the account, probed before it is saved.
- Two accounts never share a location (
storage_account_in_use): a move between them would delete what it copied. - The name can change at any time; the location only while nothing uses the account.
- Remove works only for an account that no tenant, file version, open upload or move uses (
storage_account_in_useotherwise). It forgets the account; it never deletes the bytes in the bucket or directory. defaultis the platform’s own configuration: it cannot be changed or removed here.- Browsers and apps upload straight to a bucket and read every part’s
ETagfrom its answers. A bucket account therefore needs cross-origin rules that allowPUTfrom the tenant’s app origins with the ticket’s headers and exposeETag, as the platform storage does. The probe does not check them: try an upload from the tenant’s app before you move its files.
A tenant’s storage
Section titled “A tenant’s storage”Choose a tenant to see its assigned account, where its new objects go (the assigned account, or a running move’s target), and how many of its versions and bytes live in each account.
Assigning a tenant to an account changes only where its new files and versions go. Its existing files stay where they are and keep being served from there. To bring them along, move them.
Moving a tenant’s files
Section titled “Moving a tenant’s files”- Start. Choose the target account and start the move. The tenant’s new files go to the target at once.
- Copy (
phase: copying). Every version of the tenant on another account is copied to the target, checked by size and checksum, and then served from the target. A version still uploading or processing waits for its turn (versions_waiting). - Verify (
verifying). Every copy is read back from the target and compared with the original’s checksum; a missing or damaged copy is copied again. - Switch and wait (
waiting). The tenant’s account becomes the target (switched_at). The old copies stay until every URL signed against them has expired (delete_after). - Delete (
deleting, thendone). The old copies are deleted, each only once the target holds it.
The move follows progress: versions_total, versions_moved, objects_copied, bytes_copied, objects_verified, objects_deleted and versions_waiting. One move per tenant runs at a time (storage_migration_in_progress). A move that fails repeatedly stops with status: failed and an error; the tenant’s new files go to its assigned account again, files already moved stay readable where they are, and a new move continues from there.
Throughout, file ids, versions, permissions and share links stay the same, downloads and uploads keep working, and files under a legal hold move like any other. Only a public file’s public_url changes: tell the tenant to read it from the file again rather than keep it. Moving back to default works the same way.
From code
Section titled “From code”| Route | Does |
|---|---|
GET /platform/storage-accounts, GET /platform/storage-accounts/:storage_account_id |
The accounts, or one (credentials never included) |
POST /platform/storage-accounts |
Adds one: { name, adapter, settings, credentials } (a bucket needs credentials: { access_key_id, secret_access_key }; a directory settings.root and adapter: filesystem) |
PATCH /platform/storage-accounts/:storage_account_id |
Renames it, rotates its keys, or changes its location while nothing uses it (settings merge) |
POST /platform/storage-accounts/:storage_account_id/verify |
Probes it again; answers the account with probe: { ok, error, duration_ms } |
DELETE /platform/storage-accounts/:storage_account_id |
Removes an unused account |
GET /platform/tenants/:tenant_id/storage-account, PUT /platform/tenants/:tenant_id/storage-account |
A tenant’s storage; assigns it ({ storage_account_id }, default or null for the platform storage) |
POST /platform/tenants/:tenant_id/storage-migrations |
Starts a move ({ target_storage_account_id }, 202 with the move) |
GET /platform/tenants/:tenant_id/storage-migrations, GET /platform/storage-migrations/:migration_id |
A tenant’s moves, newest first; one move with its progress |
They take a platform administrator’s user token, or a machine token with files:config.manage of a client of the Files platform application itself; every other caller gets platform_admin_required. The ccs-files-client library has them as platform.storage (ccs-files-client). Changes count against the settings rate limit. An account the service cannot reach answers 503 storage_unavailable on every route that needs it.
What is audited
Section titled “What is audited”Every change is audited with the administrator, never with a credential: storage_account.created, storage_account.updated, storage_account.verified, storage_account.deleted, tenant_storage.assigned, and for a move storage_migration.started, storage_migration.switched, storage_migration.completed and storage_migration.failed. See Audit actions.