Actions
27 actions, callable from the panel, the command palette and the API as
POST /api/v1/a/<id>. Internal actions used between modules are not listed.
| Action | What it does | Risk | Preview |
|---|---|---|---|
storage.connection.create | Add storage connection | medium | No dry run |
storage.connection.update | Edit storage connection | medium | No dry run |
storage.connection.test | Test storage connection (read) | low | No dry run |
storage.connection.list | List storage connections (read) | low | No dry run |
storage.connection.get | Get a storage connection (read) | low | No dry run |
storage.connection.browse | Browse a storage connection (read) | low | No dry run |
storage.connection.delete | Delete storage connection | medium | |
storage.connection.attach | Record or release a user of a connection | low | No dry run |
storage.s3.enable | Enable the built-in S3 store | high | |
storage.s3.disable | Disable the built-in S3 store | critical | |
storage.s3.status | Built-in S3 store status (read) | low | No dry run |
storage.bucket.create | Create a bucket | low | No dry run |
storage.bucket.update | Update bucket settings | medium | No dry run |
storage.bucket.delete | Delete a bucket | high | |
storage.bucket.list | List buckets (read) | low | No dry run |
storage.bucket.get | Get a bucket (read) | low | No dry run |
storage.object.list | List objects (read) | low | No dry run |
storage.object.delete | Delete an object | medium | No dry run |
storage.object.presign | Presign an object URL (read) | low | No dry run |
storage.lifecycle.set | Set lifecycle rules | medium | No dry run |
storage.lifecycle.preview | Preview a lifecycle rule (read) | low | No dry run |
storage.key.create | Create an access key | medium | No dry run |
storage.key.list | List access keys (read) | low | No dry run |
storage.key.rotate | Rotate an access key | medium | No dry run |
storage.key.revoke | Revoke an access key | medium | No dry run |
storage.usage.get | Storage usage (read) | low | No dry run |
storage.reconcile | Re-apply storage to its servers | low | No dry run |
Permissions and limits
Permissions
storage.connection.viewView storage connectionsstorage.connection.manageCreate, edit, test and delete storage connectionsstorage.bucket.viewView buckets, keys and usagestorage.bucket.manageCreate and change buckets and lifecycle rulesstorage.object.manageBrowse, delete and presign objectsstorage.key.manageCreate, rotate and revoke access keysstorage.s3.adminEnable, disable and reconcile the built-in S3 store
Plan limits
storage.connectionsStorage connectionsstorage.bucketsBucketsstorage.s3_bytesObject storagestorage.s3_keysAccess keys
Engineering notes
Generated from modules/storage/docs.md at build d90e9e2. These are the notes the engineers keep
next to the code: precise, technical, and honest about what is not done yet.
Model
- Connections (
storage.connection.*): kinds s3, backblaze_b2, wasabi, r2, spaces, azure_blob, gcs, sftp, ftp, ftps, webdav, local_path (admin only, under /srv or /mnt). The agent writes one root-only rclone config per connection (/etc/rc-storage/rclone/<id>.conf, remote namerc) on the account's server; wasabi/r2/spaces derive the endpoint from region / account id. Secrets live in the vault (conn/<id>); the row keeps only a masked hint (••••last4), API responses never carry a secret.test= list + write/read/delete probe (30 s cap) classified as ok / auth_failed / endpoint_unreachable / tls_error / permission_denied / quota_exceeded. Status ok -> degraded -> failing withstorage.connection.failed/recoveredevents;storage.connections.recheckretests the 20 oldest every 15 min.storage.connection.attachlets other modules record a dependency (backups does); delete is refused with the dependents listed. - Built-in S3 (
storage.s3.enable, admin): the agent downloads the pinned SeaweedFS release (v4.48, SHA-256 pinned ininternal/agent/storage.go, refuses on mismatch), creates userrc-seaweed, writesrc-seaweedfs.service(master/volume/filer on loopback, S3 onbind:port) and one staticrc-adminidentity (keys only in/etc/rc-seaweedfs/settings.json, 0600 root). Customer keys are SeaweedFS dynamic identities (weed shell s3.configure): create/rotate/revoke need no restart and take effect in about a second (the static-s3.configfile is NOT hot reloaded; that is why only the admin lives there). - Buckets: names 3-63 DNS style, unique server-wide; private or public-read (public = the
anonymousidentity getsRead:<bucket>); versioning; object lock (COMPLIANCE, default retention) only at creation; CORS; lifecycle (expiry by prefix/age, abort multipart); per-bucket quota; presigned GET/PUT (SigV4 query signature built by the agent with the admin identity, 1 min - 7 days). - Keys: scope = all buckets of the account or one bucket (+ optional prefix), read or readwrite, optional expiry. SeaweedFS has no
separate delete action:
Writecovers delete. The secret is returned once (vault keeps it only to rebuild identities).syncAccountrebuilds every identity of the account from the DB (idempotent), also on bucket create/delete. - Quotas:
storage.quota.enforce(every minute, system actor) measures buckets (fs.dufor bytes, S3 listing for object count), compares with the bucket quota and the account limitstorage.s3_bytes, flipswrite_blockedand re-syncs identities (Write/Tagging dropped for blocked buckets, reads stay). Events at 80/95 % (storage.quota.warning) and 100 % (storage.quota.exceeded). So enforcement lags by up to a minute (a single big write can overshoot); SeaweedFS' owns3.bucket.quota.enforcedid not act in the lab, so this module does it. Backup-purpose buckets/keys are not counted against the user's bucket/key/byte limits. accounts.deletedsubscription removes keys, buckets (object-lock buckets are kept and markedretained) and connections.
Verified in the lab (2026-10-09, FAKENET=full, Ubuntu 24.04, SeaweedFS 4.48, rclone 1.60.1)
See docs/tasks/w4/w4-01-storage-backups.handover.md for the command log: unmodified AWS SDK (aws-cli v2) from another container
- put/get/list/head/copy/delete, 120 MB multipart (2.8 s, checksum equal), presigned GET/PUT (panel- and SDK-generated), expiry (403 "Request has expired"), tampered key (SignatureDoesNotMatch), anonymous GET only on the public bucket, prefix-scoped read-only key (outside prefix and writes refused), revoke and rotate (old key dead in seconds), quota block + unblock, key expiry, lifecycle and CORS round trips, bucket limit, account deletion cascade, non-empty delete refused.
Known gaps / next
OAuth kinds (Drive, Dropbox, OneDrive), FUSE mounts, per-package allowed kinds (storage.policy.set), object version restore UI,
virtual-host-style addressing and custom domains/TLS (need wildcard DNS + ssl; SeaweedFS -s3.domainName), multi-node placement and
replication, SSE, usage history/egress metering, S3 request logs. Object count is capped at 50 000 listed objects per scan.
Vault has no delete: secrets of removed connections/keys are overwritten with an empty value.