When Swift clients need to keep working on Ceph RGW
Existing applications, backup tools and private cloud components that speak the OpenStack Swift API can keep working after their storage moves to Ceph, provided the Ceph Object Gateway (RGW) serves the Swift calls they make. RGW exposes a Swift-compatible API alongside its S3-compatible API, so the storage behind a Swift endpoint can change without changing the client. Compatibility is decided operation by operation, so the first task is to inventory exactly which Swift calls each client issues and test them against a non-production gateway. Treat a client's Swift support as a list to verify, not a label to trust.
The Ceph Object Gateway documentation describes the Swift-compatible API as one of the client interfaces RGW provides, served by the same gateway. Swift clients can authenticate with Swift credentials configured on the gateway or, in OpenStack environments, through Keystone, which RGW supports as an authentication option. Confirm which method your client uses, since the credential setup, token flow and endpoint URL differ and each needs its own test. For a private cloud component, check the OpenStack release and client library version against the RGW release you plan to run, because authentication and object metadata handling are the first places to test.
Teams keep Swift when the client cannot change without code or vendor work, when a private cloud component is built around Swift, or when the same objects must stay reachable through the Swift path during a migration. Teams convert to S3 when the client already supports S3, when they want one API surface and one set of access policies for all applications, or when they need a feature they plan to use only through S3. Either way, do not assume full Swift parity. Check the Swift features RGW documents against the calls your clients make, and test anything outside that list, including behavior your client depends on but does not document, before cutover.
Which Swift features to enable, test or replace
This table compares each Swift API feature area on RGW by what clients use it for, when to keep it, and what to confirm in your Ceph release before cutover. Read it as a checklist: a row marked keep still needs a test against your own clients, and any feature you cannot confirm for Tentacle or Squid should be replaced or tested before go-live.
| Swift feature area | What it is used for | When to keep it | What to confirm before cutover |
|---|---|---|---|
| Core object operations | Account, container and object create, read, list, update and delete calls from Swift clients | Your clients already use these calls and the workload is object storage rather than a Swift-specific feature set | Confirm in the Tentacle or Squid release notes and RGW Swift documentation which core calls your clients send, and run them against a test account |
| ACL subset | Container read and write access granted to users or groups through Swift ACL headers | Access patterns map cleanly to per-container read and write grants | Confirm which ACL forms RGW accepts in your release, and test that denied requests return the status your clients expect |
| Temporary URLs | Time-limited signed links that let a client download or upload an object without its own credentials | Users need short-lived shared links and your clients already generate signatures with the temp URL key | Confirm temp URL support and signature algorithms in your release, and test expiry, key rotation and uploads with the signing tool you use |
| Object versioning | Keeping prior object versions when a container is overwritten or deleted | Recovery from accidental overwrites is a requirement and your clients rely on Swift versioning semantics | Confirm how versioning behaves in your release, including delete markers, listing and any gap compared with S3 versioning, and test restore steps |
| CORS for browser clients | Allowing browser applications on other origins to call Swift endpoints directly | Browser front ends call Swift storage directly and cannot route through a proxy | Confirm CORS handling for Swift in your release, since it may not be available, and plan a proxy or S3 path if it is missing |
| Account and user mapping to RGW identities | Mapping Swift accounts, users and tenants to RGW users and their quotas, keys and permissions | Each team or customer needs isolated storage and the mapping can be defined once and kept stable | Confirm how Swift users map to RGW users and tenants in your release, and check that quotas, keys and ACLs follow the same identity |
| Shared data between Swift and S3 | Reading the same buckets or containers through both APIs during migration or for mixed applications | Applications on both APIs must see one data set and you have tested naming and metadata behavior | Confirm which metadata, ACL and versioning results appear identically through each API in your release, and test each application on both paths |
How RGW serves Swift and S3 from the same buckets
Running Swift and S3 against the same data is a design choice you have to verify, not a default. The Ceph Object Gateway (RGW) exposes both a Swift-compatible and an S3-compatible API on top of the same gateway daemons and the same underlying object store, so a client written for either protocol can read and write the same content. That shared storage is the reason the combination works, and it is also the reason it needs a deliberate plan. Each API was designed around its own model of containers, buckets, ACLs, versioning and metadata, and RGW translates between those models rather than giving each one a native view of everything. Before you point production clients at the same data from both sides, confirm the exact mapping for your release in the Ceph Object Gateway documentation, because translation rules have changed across releases and differ for each feature.
Start by mapping the four objects that every client will touch: object names, containers and buckets, metadata, and authentication identities. A Swift container and an S3 bucket are both represented by RGW buckets, and object names are the keys that both APIs address, but the way prefixes, pseudo-directories and listings behave can differ between the two clients. Metadata is the most fragile point. Swift custom metadata headers and S3 user metadata are stored and returned through different paths, so a value written through one API may not appear, or may appear with a different header name, when read through the other. Authentication identities have the same problem: a Swift user, a Swift subuser and an S3 user are not interchangeable, and the access and secret keys or Swift credentials you issue must be tied to the right RGW user and bucket ownership. Write down which identity owns each bucket and which API each application uses.
The main risk is a mismatch in ACLs, versioning or metadata between the two APIs. A Swift ACL on a container can grant access that an S3 bucket policy or ACL does not express the same way, and the reverse holds too, so an access rule set in one API can be silently narrower or broader than intended when read through the other. Object versioning is another divergence point: an S3 client that enables versioning and a Swift client that overwrites the same object may produce results that neither team expects. Test these cases with the actual clients in a non-production zone: write from each side, read from the other, change an ACL, enable versioning, and confirm what a third client sees. If the mismatch is unacceptable for a workload, give it one API only and document the exception.
Setting up Swift access on RGW, step by step
This sequence takes a Ceph cluster from a confirmed release and a running Object Gateway to Swift clients that read and write containers and objects, with each optional feature tested on its own and the unsupported gaps written down before any application is cut over.
Confirm the Ceph release and RGW deployment
Check that the cluster runs an actively maintained release, Tentacle (20.2.x) or Squid (19.2.x), and that cephadm manages the Object Gateway daemons as containers. Run
ceph versionsto confirm every daemon reports the same release, then runceph orch ls rgwto confirm an RGW service exists and is running. Done when every RGW daemon shows as running and the version matches the release you plan to support. If the cluster was built outside cephadm, confirm with your platform team how RGW is managed before you change its configuration.Enable the Swift endpoint and TLS
Confirm the RGW frontend answers on the address and port your Swift clients will use, and that the Swift API is served alongside S3 on that endpoint. Put the endpoint behind TLS using the certificate method your organization has approved, and make sure the certificate covers the hostname clients will use. Test from a client subnet with
curl -Iagainst the Swift path of the endpoint. Done when the request returns an HTTP response over TLS without certificate warnings. Confirm the exact configuration keys with the Ceph Object Gateway documentation for your release, since frontend options change between versions.Create the RGW users and Swift keys
Create the RGW user that will own the Swift containers, then generate a Swift subuser and secret key for it with
radosgw-admin subuser createandradosgw-admin key create. Store the secret in your secrets manager, not in application configuration files. Test authentication by requesting a token or sending an authenticated request with the Swift client. Done when the subuser authenticates and receives a storage URL, and a request with a wrong secret is rejected. Record the user, subuser and key ownership so that rotation later has a clear owner.Map accounts or tenants to Swift namespaces
Decide how each Swift account maps to an RGW tenant or user, because the mapping controls which containers a client can see and how quotas apply. Create the tenant or user namespace for each consuming team, then confirm that a container created by one account is not listed for another. Use
radosgw-admin user infoto check the tenant and user IDs. Done when two test accounts each create a container and neither can list the other's container. If your organization uses IAM accounts for multi-tenant S3, check how that model lines up with the Swift mapping before you go further.Test basic container and object operations
Using the same Swift client library or CLI your application uses, run the core cycle: create a container, upload an object, list the container, download the object, compare its checksum with the source file, and delete the object and container. Keep the test script in version control so it can be rerun after upgrades. Done when every operation returns the expected status and the checksum matches. Record any operation that fails, because those gaps belong in the final contract, not in the application code.
Test ACLs, temporary URLs, versioning and CORS separately
Test each advanced feature on its own, with one test per feature: set a container read ACL and confirm an unauthenticated read succeeds or fails as expected, generate a temporary URL and confirm it expires, enable versioning and confirm an overwrite keeps the prior version, and send a cross-origin request to confirm whether CORS headers are returned. Compare each result against the Ceph Object Gateway Swift documentation for your release. Done when each feature has a pass, a partial result or a fail recorded with the exact request and response. Do not assume a feature works because the client library exposes a method for it.
Record the excluded features in the client contract
Write a short contract listing what the Swift endpoint supports for each consuming application, which ACL forms and temporary URL or versioning behaviors are in scope, which features are missing or partial, and which application workflows must change. Name the owner of the contract and the release it was tested against. Share it with the application teams and the platform team. Done when each application team signs off on the list and knows which operations to avoid. Revisit the list after every Ceph upgrade, because feature coverage changes between releases.
Choosing a Swift path by client situation
Applications that call the Swift API and cannot change in the near term are the strongest reason to keep the Swift endpoint on RGW. The goal is to keep the client working without widening the gap between the calls it makes and the operations the gateway supports. Start by listing every Swift request the application issues, because the supported set is narrower than the full object API and gaps often appear only under real traffic. Check the current Swift behavior in the Ceph Object Gateway documentation before you assume a call works.
- Keep on Swift: the account, container and object calls the application already makes, along with its existing authentication flow and token handling.
- Move to S3: nothing by default. Move only batch jobs or new services that your team can change, and keep the legacy path on the same data until the client is retired.
- Test across both APIs: each operation the client issues, container ACL behavior for shared data, and any feature the client depends on that the documentation describes as partial or missing.
- Sign off: the application owner confirms functional behavior, the platform team confirms endpoints and authentication, and the security team confirms how credentials are stored and rotated.
Before a cutover date is set, run the client against a staging copy of the data and record every failed call with its Swift operation name.
OpenStack services such as image storage and backup can be configured with a Swift backend, a Ceph backend or both, depending on the component and the release you run. Keystone usually handles identity for these services, so the endpoint catalog entry for RGW matters as much as the storage driver. Treat each component as its own decision, because a change that suits image storage can break backup restores. Confirm the driver each component uses in your deployed release before you change any endpoint.
- Keep on Swift: the backend configuration for any component whose driver supports only the Swift API, and the Keystone service catalog entry that points to RGW.
- Move to S3: image or backup paths only where the component's own documentation shows S3 support in your release, and only inside an agreed change window.
- Test across both APIs: a full image upload, download and delete, a volume backup and restore, and the listing or expiry jobs that the component runs on a schedule.
- Sign off: the OpenStack operations lead approves service configuration, the storage team approves the endpoint and capacity impact, and the backup owner approves the restore test.
A backup is only proven when a restore has succeeded on the new path, so schedule that restore test before any backup target is changed.
New applications that can choose their storage API should start on S3 from the first build. The Object Gateway documents its S3 coverage in more depth than its Swift coverage, and most current SDKs and tooling assume an S3 endpoint. Keep Swift out of the design unless a dependency forces it, and record any exception with an owner and a review date. The decision is easier to defend when it is made at design review, before code, buckets and credentials exist.
- Keep on Swift: nothing, unless a required third-party component can only use Swift. Document that exception in the design record.
- Move to S3: the application's storage calls from day one, using the S3 features listed in the Object Gateway documentation as the design baseline.
- Test across both APIs: only when a Swift client must read the same bucket or container. In that case, verify that a write through one API is visible through the other.
- Sign off: the architecture review group approves the storage design, the security team approves credential scope and tenancy, and the engineering lead approves the SDK version.
Check the SDK version your language runtime pins against the gateway's feature list before the design is approved, because client library releases can change default behavior.
Securing Swift credentials, endpoints and shared data
Serving Swift and S3 from the same RGW daemons widens what an attacker or a careless client can reach. The cards below cover the credentials, transport, access rules, logs and network paths that connect the two APIs, with a check for each so the controls are verified rather than assumed.
Swift credential lifecycle and rotation
Swift clients authenticate with a subuser and a Swift secret key that sit alongside the user's S3 keys. Each secret is long-lived unless someone rotates it, and it often ends up in CI variables, backup scripts and client configuration files that nobody tracks. Set a rotation schedule for every Swift key, record which application holds it, and remove keys for subusers that no longer have a consumer. Confirm the procedure by rotating one key in a test account and verifying that the old key is rejected.
TLS on the Swift endpoint
Swift requests carry tokens and object payloads over the same HTTP frontend as S3, so plain HTTP exposes both to anyone on the path. When a proxy or load balancer terminates TLS in front of RGW, the traffic between the proxy and the daemon may still be unencrypted, and some clients will accept an endpoint without verifying its certificate. Confirm that every client uses HTTPS with certificate validation enabled, and test the path from the proxy to RGW as well as the public name.
Separate Swift and S3 keys
A single identity can hold both Swift and S3 credentials, so a leaked S3 access key may be used to reach the same buckets, and a Swift secret may grant the same reach under a different API. Treat each key as a separate credential with its own owner, scope and rotation date. Where possible, give each application only the interface it uses, and check which key an application actually sends before you rotate it.
ACL and policy review across both APIs
Swift uses container ACLs, while S3 uses bucket policies and ACLs, and the two do not always produce the same result for the same object. A permission granted in one API can be broader than the team expects when the other API reads the data. Review the effective access for each container or bucket from both interfaces, and test read and write as each credential. Record any gap between the two models so that the owning team knows which API governs the final decision.
Logging and audit of Swift requests
Operators often review S3 access logs and overlook Swift traffic, which means reads and writes made through Swift may leave weaker evidence. Confirm that RGW access logging captures Swift operations, including the user, container, method, status and source address, and that logs are forwarded to a store that retention rules cover. Test by making a known Swift write and read, then finding both events in the central log system.
Network exposure of RGW daemons
RGW daemons serve Swift and S3 on the same listening ports, so a daemon bound to a broad interface can be reached from networks that should only see the load balancer. Restrict the frontend to the addresses that need it, keep the RADOS cluster network off the client path, and filter access to the Swift port at the host or network firewall. Confirm the exposure by scanning the daemon address from a network outside the approved client range and checking that the connection is refused.
What to confirm before pointing production Swift clients at RGW
The cutover decision rests on one question: does the application's own Swift client, at the exact version it runs in production, behave the same against RGW as it does against the current store? Run a compatibility test with the actual client library and version, not a generic Swift CLI or a lab script. Pin the library version, point it at a test RGW endpoint with the same authentication path the application uses, and record every request the application makes. Confirm that authentication tokens, account and container naming, and error handling match what the code expects, since a client that tolerates a different error response in testing can fail under load.
Next, replay representative operations that reflect real workload shape. Include large uploads that use segmentation, because multi-part behavior and manifest handling are where Swift implementations most often differ from what clients assume. Include container listings at the size production produces, with prefix and marker pagination, and deletes of objects that sit in segmented containers. Confirm temporary URL and versioning behavior separately: check whether the application signs temporary URLs, which hash keys and expiry handling it relies on, and whether it depends on version history being kept or restored. Where a feature is partial or absent, record that as a blocking finding or a documented change to the application, and check the current status against the Ceph release notes and the Ceph Object Gateway documentation for the exact release you will run, since support levels change between versions.
Finally, agree the rollback path before the first production write. Decide whether the application can switch its storage endpoint back by configuration alone, how objects written to RGW during the window will be read or copied back, and who approves the switch in each direction. Confirm that the team can verify data integrity after a rollback, for example by comparing object counts and checksums for a sample of containers, and that the old store stays readable until that check passes. Write the answers down as acceptance criteria, so the cutover is judged against the agreed tests rather than against whether the first day looked clean.
Swift gaps to test and confirm in your environment
The Swift API in RGW covers a subset of OpenStack Swift behavior, and the gaps that matter depend on what your application actually calls. The cards below group the areas most likely to break a workload, with a check you can run before cutover. Confirm each one against the Ceph release you plan to run, because implementation coverage changes between releases.
Temporary URL behavior
Applications that hand out presigned Swift temporary URLs depend on the signing key, the HMAC method and the expiry handling being accepted exactly as the client sends them. Test a URL generated by your client library, then fetch it from outside the application network and confirm expiry is enforced. If the signing scheme differs for your client, change the client library version or move the download path to S3 presigned URLs.
Versioning semantics
Confirm whether your workload expects Swift-style versioned containers, and whether listing, restore and delete of prior versions behave as your code assumes. Write a test that overwrites, deletes and restores an object, then compare the listing output with what your application parses. If versioning differs, keep versioning on the S3 side for that data or change the restore logic in the application.
ACL subset coverage
Swift container ACLs are narrower than the policy model many applications assume, so grants that work on another Swift endpoint may not map cleanly. List every ACL your tenants and service accounts rely on, apply each one in a test container, and verify access from each identity. If a grant is missing, reduce the scope to what the Swift subset supports or move access control for that bucket to IAM policies over S3.
Missing or partial CORS
Browser-based clients that upload or read objects directly need CORS preflight responses and allowed headers. Send a preflight request from the exact origin your web application uses, and check the returned headers and methods. If CORS is missing or partial for your Swift calls, route browser traffic through an application proxy or use the S3 endpoint for those operations.
Container and object metadata
Confirm which custom container and object metadata headers are stored, returned and preserved through copy and overwrite operations. Set metadata with your client, read it back through a second client, and compare the result after a server-side copy. If a header is dropped or altered, store that value in an application database or use object tags over S3 instead.
Application-specific API calls
List every Swift operation your application calls, including bulk operations, large object manifests and account-level calls, and test each one against the RGW endpoint. Mark any call that returns an error or a different response shape as a blocker or a workaround. A blocked call can be changed in the client, served through S3 for the same data, or accepted as a documented gap with an owner and a review date.
What buyers ask before moving Swift clients to Ceph RGW
Can Swift and S3 clients read and write the same data in Ceph RGW?
Yes, in many setups, but the two APIs do not map one to one, so confirm the behavior for your own workload before relying on it. RGW stores objects in buckets and exposes them through both S3 and Swift-compatible interfaces, and the Ceph Object Gateway documentation describes both API families. Differences show up in metadata, ACLs, versioning, temporary URLs and CORS, so a Swift client may not see every attribute an S3 client set, and the reverse can also hold. Test the exact read and write paths your applications use, including object overwrite and deletion, in a non-production zone first. Ask the team that will run the cluster to document which operations are shared and which are API-specific.
How is compatibility testing scoped for a Swift client migration?
Compatibility testing is scoped from the inventory of Swift operations your clients actually call, not from the full API. Start by listing every client library, script and third-party tool that talks to the Swift endpoint, then map each call to a supported, partial or unsupported behavior in the RGW documentation. Gaps such as temporary URL handling, versioning, CORS and some ACL forms need explicit test cases with pass and fail criteria agreed in advance. Testing also covers authentication flow, large object uploads, error responses that client retry logic depends on, and how the application behaves when a gap is hit. The output should be a written test matrix that the buyer signs off before cutover.
What drives the effort of moving Swift clients onto RGW?
The main drivers are the number of client applications, how many of them depend on Swift-only behavior, and how much of that behavior has no direct equivalent. Applications that use only basic container and object operations usually need the least change. Applications that rely on temporary URLs, versioning, CORS for browser uploads, or specific ACL patterns need code changes, a workaround, or a different design, and each one adds test cycles. Other factors include how many credentials and accounts must be mapped, whether data must be copied or served in place, the size of the data set, and the number of teams who must sign off. Ask any partner to break its estimate down along these drivers, and ask which items are one-time work and which recur.
Does a fixed-scope engagement cover Swift client migration?
It can, provided the scope is written down before work starts, because DeployOpen most often works on fixed-scope engagements with scope, deliverables and timelines agreed in writing. A reasonable written scope for this topic lists the Swift operations in use, the client applications covered, the compatibility test matrix, the workarounds or code changes to be delivered, the cutover approach and the handover documents. Items outside that list, such as new client applications, additional gateway features or extended support, would be scoped separately. Ongoing support, upgrades and continuous testing are available as retainers. Ask for the scope document and check that each application in your inventory appears in it.
What does the buyer team need to provide for the work?
The buyer needs to supply accurate knowledge of how its applications use Swift and access to the environments where testing happens. Specifically, that means a list of client applications and owners, sample requests or traffic captures, the account and user model that maps to Swift access, test data that resembles production, and named people who can approve behavior changes. The team also needs a staging RGW environment that matches the production release, because results on a different Ceph release may not match. Confirm the Ceph release you run, since the Ceph releases page lists the maintained series and their end-of-life dates that affect planning. Late identification of a single client is one of the most common causes of schedule slip.
Can our own team migrate Swift clients without a partner?
A capable team with RGW and application experience can do this in-house, and the decision depends on skills, capacity and risk tolerance rather than on the protocol alone. An internal team needs knowledge of the RGW Swift implementation, the ability to build a complete test matrix, and time to fix application code. The work is often underestimated because gaps surface only during testing, and a second pass is common. A partner adds more value when many applications are involved, when compliance evidence is required, or when the internal team lacks spare capacity. Whichever route you take, ask for a written list of supported and unsupported operations before committing.
How do Ceph upgrades affect Swift behavior on RGW?
Upgrades can change which Swift behaviors work, so every upgrade needs a regression run of your Swift test matrix. The Ceph releases page states that maintained releases receive periodic backports and security fixes, but backports do not guarantee identical API behavior across minor or major versions. Check the release notes for the target version for changes to Swift, ACL, versioning or authentication behavior before scheduling the upgrade. Keep the staging environment on the same release as production so that you test what you deploy. Plan the upgrade path with the maintained release lines in mind, and confirm with the Ceph project which behaviors changed for your version.
What are the main risks when clients rely on Swift-only features?
The main risk is silent behavior change: a client appears to work but returns different results for temporary URLs, versioned objects, browser uploads or permissions. Other risks include clients that treat unexpected error responses as success, retry storms when an endpoint returns errors, and credentials that grant broader access than intended after mapping. Reduce these risks by testing failure paths, not only happy paths, reviewing ACL translations with the application owners, and keeping a rollback option until the matrix passes. Document the workarounds you accept, because they become part of the operating model that your team must maintain.
How DeployOpen scopes and delivers Swift on Ceph RGW
DeployOpen starts by confirming which Swift clients and operations your applications actually use, then checks those against what RGW supports. We build and test the Swift endpoint inside your own infrastructure, document the gaps you accept, and hand over a configuration your team can run.
How we scope
- The written scope lists each Swift client, library and operation your applications use, with the expected request volume.
- Scope records which ACL, temporary URL, versioning and CORS behaviors are required, and which gaps your teams have accepted in writing.
- Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts, and a quote follows from that scope.
How we build
- We configure the RGW Swift endpoint, its users and account mapping on your Ceph cluster, in the environments you control.
- We run a test matrix of your Swift clients against the same buckets used by S3 applications, covering reads, writes and deletes.
- We check the Swift and S3 access paths against one data set, and record every case where behavior differs between the two APIs.
How we hand over
- You receive a written compatibility report listing supported operations, partial behavior and missing features, with test evidence for each.
- Runbooks cover client configuration, credential rotation, load balancer settings and the steps for adding a new Swift tenant.
- Knowledge transfer sessions walk your platform and application teams through the configuration and the known limits before handover.
How we support
- Ongoing support, Ceph upgrades and continuous testing are available as retainers, so compatibility checks can run after each release.
- Retainer work can include re-running the Swift client test matrix when applications, SDKs or Ceph versions change.
- Ask in the quote which support hours, response paths and upgrade testing are included, and who on your side approves changes.

