OpenStack Swift API for RustFS
Swift-compatible object storage API implementation for RustFS.
Features
The lists below are bounded to what router.rs / handler.rs dispatch and
what the test suite exercises. A module existing under src/swift/ does not
by itself mean the feature is reachable over HTTP.
Wired through the router and handler
- ✅ Account listing (
GET /v1/AUTH_{project}, JSON) and additive account metadata updates (POST,X-Account-Meta-*/X-Remove-Account-Meta-*) - ✅ Container CRUD (create, list, head, update metadata, delete)
- ✅ Object CRUD with streaming downloads, HTTP Range requests (206 / 416),
and server-side copy via the
COPYmethod - ✅ Keystone token authentication and multi-tenant isolation with SHA256-based bucket prefixing
- ✅ Custom metadata (
X-Object-Meta-*,X-Container-Meta-*); container and account POSTs are additive, object POSTs replace the set - ✅ Container ACLs (
X-Container-Read/X-Container-Write, set and remove on container POST, reported on HEAD). Enforcement is account-level plus referrer checks; per-user grants are not evaluated because credentials carry no user id - ✅ CORS:
OPTIONSpreflight on container and object routes, and response header injection driven byX-Container-Meta-Access-Control-* - ✅ TempURL (
temp_url_sig/temp_url_expireson object GET, HEAD, PUT; key stored as account metadata; optional client-IP restriction) - ✅ FormPost (container POST with
multipart/form-data, signed with the account TempURL key) - ✅ Large objects: Static Large Objects (
?multipart-manifest=put|get|delete) and Dynamic Large Objects (X-Object-Manifest) - ✅ Bulk operations:
DELETE /v1/AUTH_{project}?bulk-deleteandPUT /v1/AUTH_{project}/{container}?extract-archive=tar|tar.gz|tar.bz2 - ✅ Object versioning in the Swift
X-Versions-Locationstyle: the previous copy is archived on PUT / DELETE and restored on DELETE - ✅ Symlinks (
X-Symlink-Targeton PUT, resolved on GET / HEAD with loop and depth checks) - ✅ Container quotas (
X-Container-Meta-Quota-Bytes/-Quota-Count), enforced on object PUT - ✅ Static website serving on object GET when
web-index/web-listingscontainer metadata is set - ✅ Object expiration headers:
X-Delete-At/X-Delete-Afterare validated, stored, and returned on GET / HEAD
Not yet wired, or partially wired
- ⏳ Account
HEADreturns501 Not Implemented; no account-level usage statistics are exposed - ⏳ Automatic deletion of expired objects:
expiration_worker.rsexists but the server never starts it, so objects pastX-Delete-Atare not removed - ⏳ Container sync (
sync.rs): noX-Container-Sync-*header handling and no background worker; the module is unit-tested only - ⏳
X-Copy-Fromon object PUT (only theCOPYmethod is supported) - ⏳
X-History-Locationversioning mode - ⏳ Static website index / listing pages at the container root (only the object GET route consults static-web settings)
- ⏳ XML / plain-text listing formats; the
format=query parameter is ignored and listings are always JSON
Test coverage
- Unit tests live next to each module (
acl.rs,bulk.rs,cors.rs,dlo.rs,slo.rs,tempurl.rs,formpost.rs,staticweb.rs,symlink.rs,quota.rs,expiration.rs,versioning.rs,router.rs,handler.rs, and others) and run in the CIswiftfeature lane crates/protocols/tests/swift_metadata_persistence.rsruns account, container, ACL, TempURL-key, and versioning metadata writes against a real ECStore and reloads them from diskcrates/protocols/tests/swift_versioning_integration.rs,swift_listing_symlink_tests.rs,swift_simple_integration.rs, andswift_phase4_integration.rscover version naming, listing parameters, symlink parsing, and module-level helpers without a serverrustfs/tests/swift_container_integration_test.rsandswift_object_integration_test.rsexercise the HTTP surface end to end but are#[ignore]and need a running server (TEST_RUSTFS_SERVER); they are not part of CI
Enable Feature
Swift API is opt-in and must be explicitly enabled.
Build with Swift support:
cargo build --features swift
Or enable all protocol features:
cargo build --features full
Note: Swift is NOT enabled by default to avoid unexpected API surface changes in existing deployments.
Configuration
Swift API uses Keystone for authentication. The variables below are read by
crates/keystone/src/config.rs; that file is the authoritative list.
| Variable | Description |
|---|---|
RUSTFS_KEYSTONE_ENABLE |
Set to true to enable Keystone authentication (default false; nothing else is read while disabled) |
RUSTFS_KEYSTONE_AUTH_URL |
Keystone authentication endpoint URL (required once enabled) |
RUSTFS_KEYSTONE_VERSION |
Keystone API version, v3 or v2.0 (default v3) |
RUSTFS_KEYSTONE_ADMIN_USER |
Admin username (optional) |
RUSTFS_KEYSTONE_ADMIN_PASSWORD |
Admin password (optional) |
RUSTFS_KEYSTONE_ADMIN_PROJECT |
Admin project name (optional) |
RUSTFS_KEYSTONE_ADMIN_DOMAIN |
Admin domain name (optional) |
RUSTFS_KEYSTONE_VERIFY_SSL |
Verify the Keystone TLS certificate (default true) |
RUSTFS_KEYSTONE_ENABLE_CACHE / RUSTFS_KEYSTONE_CACHE_SIZE / RUSTFS_KEYSTONE_CACHE_TTL |
Token cache toggle, entry count, and TTL in seconds (defaults true, 10000, 300) |
RUSTFS_KEYSTONE_TENANT_PREFIX |
Prefix bucket names with the tenant hash (default true) |
RUSTFS_KEYSTONE_IMPLICIT_TENANTS |
Allow implicit tenant creation (default true) |
RUSTFS_KEYSTONE_TIMEOUT |
Keystone request timeout in seconds (default 30) |
API Endpoints
Swift API endpoints follow the pattern: /v1/AUTH_{project_id}/...
Account Operations
GET /v1/AUTH_{project}- List containers (JSON)HEAD /v1/AUTH_{project}- Get account metadata (returns 501, not yet implemented)POST /v1/AUTH_{project}- Update account metadata and TempURL keyDELETE /v1/AUTH_{project}?bulk-delete- Bulk delete
Container Operations
PUT /v1/AUTH_{project}/{container}- Create container (?extract-archive=for bulk upload)GET /v1/AUTH_{project}/{container}- List objects (JSON;limit,marker,end_marker,prefix,delimiter)HEAD /v1/AUTH_{project}/{container}- Get container metadataPOST /v1/AUTH_{project}/{container}- Update container metadata, ACLs, versioning location; FormPost whenmultipart/form-dataDELETE /v1/AUTH_{project}/{container}- Delete containerOPTIONS /v1/AUTH_{project}/{container}- CORS preflight
Object Operations
PUT /v1/AUTH_{project}/{container}/{object}- Upload object (SLO manifest with?multipart-manifest=put, DLO withX-Object-Manifest, symlink withX-Symlink-Target)GET /v1/AUTH_{project}/{container}/{object}- Download object (Range, SLO/DLO assembly, symlink resolution,?multipart-manifest=get)HEAD /v1/AUTH_{project}/{container}/{object}- Get object metadataPOST /v1/AUTH_{project}/{container}/{object}- Update object metadataDELETE /v1/AUTH_{project}/{container}/{object}- Delete object (?multipart-manifest=deleteremoves SLO segments)COPY /v1/AUTH_{project}/{container}/{object}- Server-side copyOPTIONS /v1/AUTH_{project}/{container}/{object}- CORS preflight
Object GET, HEAD, and PUT also accept TempURL query parameters without an auth token.
Architecture
The Swift API is implemented as a Tower service layer (SwiftService) that wraps the S3 service:
HTTP Request
│
▼
┌───────────────┐
│ SwiftService │ ← Routes /v1/AUTH_* requests
└───────┬───────┘
│
┌────┴────┐
│ │
▼ ▼
Swift S3 Service
Handler (fallback)
Key Components
- handler.rs - Main service implementing Tower's Service trait and method dispatch
- router.rs - URL routing and parsing for Swift paths
- container.rs - Container operations with tenant isolation
- object.rs - Object operations including copy and range requests
- account.rs - Account validation, tenant access control, account metadata and TempURL key
- acl.rs, cors.rs - Container ACL evaluation and CORS config
- slo.rs, dlo.rs - Static and dynamic large objects
- tempurl.rs, formpost.rs - Signed URL and form upload validation
- bulk.rs - Bulk delete and archive extraction
- versioning.rs, symlink.rs, quota.rs, staticweb.rs, expiration.rs - Per-feature helpers called from the handler
- expiration_worker.rs, sync.rs - Background workers that are not started by the server (see above)
- metadata_update.rs - Additive account/container metadata merge
- errors.rs - Swift-specific error types
- types.rs - Data structures for Swift API responses
Tenant Isolation
Swift containers are mapped to S3 buckets with a secure hash prefix:
Swift: /v1/AUTH_abc123/mycontainer
↓
S3 Bucket: {sha256(abc123)[0:16]}-mycontainer
This ensures:
- Complete tenant isolation at the storage layer
- No collision between tenants with similar container names
- S3-compatible bucket naming (lowercase alphanumeric + hyphen)
Documentation
There is no separate Swift reference document in the repository. Use these sources instead:
- Module-level
//!comments in eachcrates/protocols/src/swift/*.rsfile describe the headers and metadata keys that feature reads crates/protocols/tests/swift_*.rsandrustfs/tests/swift_*_integration_test.rsshow the expected request and response shapesdocs/testing/ci-gates.mddescribes the CI lane that builds and tests with--features swift
License
Apache License 2.0