an hour ago
Purpose: obtain an official Railway/provider capability statement before any custodian implementation. This is not a request for Railway to provision, mutate, deploy, inspect customer data, access our application targets or troubleshoot application code.
Please answer each item with YES / NO / NOT AVAILABLE / CONDITIONAL, and cite the exact Railway platform behavior or limitation. Where CONDITIONAL, state the exact prerequisite.
-
SERVICE_STORAGE_ISOLATION — Can a dedicated Railway service with an attached volume be isolated such that other project services (including root inside their containers) cannot mount, enter, access, attach or obtain writable access to that volume or the custodian service's mount/PID namespace? Please include relevant privilege, host/device/socket and cross-container boundaries.
-
EXCLUSIVE_VOLUME_ATTACHMENT — Can the volume be attached only to the custodian service, with ordinary API-service credentials/processes unable to attach, remount or enter it? What Railway-level permissions or control-plane identities can attach/detach a volume?
-
AFFIRMATIVE_OLD_OWNER_REVOCATION — Before a volume is reassigned/redeployed, can Railway provide or expose an affirmative platform signal/evidence that all old container/process holders are terminated, outstanding I/O is disposed of, and the old volume attachment is detached before a new owner becomes active? A configured replica count or sent SIGTERM/SIGKILL alone is insufficient for this requirement.
-
STABLE_PROVIDER_VOLUME_IDENTITY — What immutable/stable identifiers exist for a Railway volume/storage incarnation, and how do backup restore, clone, replacement, redeploy and recovery affect those identifiers? Can a workload distinguish the same original volume incarnation from a restored/replaced clone?
-
RUNTIME_STORAGE_OBSERVABILITY — Which of these identities/observations are available to a workload or read-only provider API: deployment ID, replica/container/process identity, boot identity, mount namespace identity, mount ID, filesystem ID/fsid, device identity, volume ID, attachment generation, parent/root device+inode? Please mark unavailable fields explicitly rather than omitting them.
-
PRIVATE_TMP_MAPPING_FEASIBILITY — Can a Railway volume be mounted at a private path used only inside the custodian service (including a dedicated /tmp-style mapping) without sharing the API service's /tmp or host filesystem, while keeping a control journal and governed targets on the same durable filesystem?
-
DURABILITY_SEMANTICS — What guarantees apply to file fsync and directory fsync on Railway volumes? What happens to acknowledged writes across container crash, host failure, redeploy, volume detach/reattach and power-loss-equivalent events? Are these semantics documented/testable, and are there cases where fsync success does not imply persistence through those events?
-
PRIVATE_AUTHENTICATED_PROTOCOL_IDENTITY — Railway private networking provides transport isolation, but can the platform support a separate custodian service identity/credential boundary such that API services can call a bounded private protocol without receiving storage/attach/admin credentials? Please distinguish network membership from application authentication/authorization.
Already documented separately: Railway volume services do not use replicas and multiple active deployments are prevented from being mounted to the same service/volume. We treat that only as NO_OVERLAPPING_VOLUME_OWNERS; it does not by itself satisfy old-owner revocation.
This is a general platform-capability question for a future architecture. No access to our project, services, data, or credentials is required.
We would especially appreciate confirmation from Railway staff or links to official Railway documentation for each answer.
No provider mutation or customer-data inspection is requested.
3 Replies
an hour ago
This thread has been opened as a bounty so the community can help solve it.
Status changed to Open Railway • about 1 hour ago
an hour ago
I’d solve it by making the custodian the only service that ever mounts the volume.
"API Service -> private authenticated request -> Custodian -> Railway Volume"
"SERVICE_STORAGE_ISOLATION" — CONDITIONAL. Other services should not share the custodian’s filesystem, "/tmp", mount namespace or PID namespace. Just make sure your API services never receive Railway admin/API credentials.
"EXCLUSIVE_VOLUME_ATTACHMENT" — CONDITIONAL. Attach the volume only to the custodian. Your API services should only call the custodian and should never have permission to attach/detach storage themselves.
"AFFIRMATIVE_OLD_OWNER_REVOCATION" — NO. Railway prevents overlapping volume deployments, but it does not expose a strong fencing signal proving the previous process and all I/O are completely gone. I’d handle that with your own ownership generation/journal.
"STABLE_PROVIDER_VOLUME_IDENTITY" — PARTIAL. I’d create a UUID inside the volume and combine it with an external generation counter and "RAILWAY_DEPLOYMENT_ID". Don’t rely only on the volume name or mount path.
"RUNTIME_STORAGE_OBSERVABILITY" — PARTIAL. Deployment/service IDs are available, but I wouldn’t depend on mount IDs, fsid, device IDs or attachment generation as stable Railway identities.
"PRIVATE_TMP_MAPPING_FEASIBILITY" — YES. Mount the volume at something like "/custodian" and use "/custodian/tmp", "/custodian/journal" and "/custodian/data". The API service keeps its own separate "/tmp".
"DURABILITY_SEMANTICS" — CONDITIONAL. Use "fsync", atomic rename and a recovery journal, but don’t assume Railway gives a formal guarantee that successful "fsync()" survives every possible host/power-loss failure.
"PRIVATE_AUTHENTICATED_PROTOCOL_IDENTITY" — YES. Use Railway private networking for transport, then add your own HMAC or mTLS authentication. The API only gets permission to call the custodian, not permission to manage the volume.
So yes, Railway can support the custodian pattern, but I wouldn’t rely on it for storage fencing. I’d keep ownership, generation and crash recovery inside the custodian design itself.
an hour ago
- Yes, volumes can only be accessed by and mounted to one service at a time.
- Again, yes, volumes can only be accessed by and mounted to one service at a time. By API, if you mean Railway's GQL API, then anyone with write access to the project would be able to use the API to detach the volume.
- Yes, the service must be redeployed when a volume is detached. (Services with a volume attached can't have more than one replica)
- Services won't know if the volume has been restored from a backup or replaced with a clone.
- You can see the available variables here: https://docs.railway.com/variables/reference#railway-provided-variables.
- Yes, though some things may break if specific paths are used.
- Railway only guarantees 3000 read/write IOPS.
- You can add your mTLS or HMAC scheme. Also, services will only be able to attach/detach/manage Railway service configurations only if a valid Railway token is provided.
31 minutes ago
Six of your eight are answered above and I am not going to restate them. Ben's are the authoritative ones and nadielo's UUID-inside-the-volume plus generation counter is the right shape for item 4, since Ben confirmed a service cannot tell a restored volume from the original. Two are still open though, and one of them only looks answered.
Item 7 is the one that looks answered. The 3000 read/write IOPS figure is a throughput guarantee, not a durability guarantee, so it does not speak to your question. Your question was whether an acknowledged fsync survives container crash, host failure, detach and reattach, and power loss equivalent events. Railway does not document durability or fsync semantics anywhere. What the volumes reference actually documents is the IOPS number, backups, the 48 hour deletion grace period, and the rule that two deployments are prevented from being active and mounted at once. None of that is a write-durability statement. So the literal answer to "are these semantics documented" is no, explicitly, and you should treat the absence as the answer rather than assume a guarantee exists and is merely unwritten.
On testable, partly, and it is worth knowing which half. Container crash and redeploy and detach and reattach you can test yourself, because you can cause all three on demand. Host failure and power loss you cannot induce from inside a container, so that half is not testable by you at any price and has to come from Railway as a statement. That is the specific thing worth pressing them for, rather than the whole item.
Item 5 asked for the fields marked explicitly rather than omitted, so here they are in three groups.
Provided by Railway as environment variables, confirmed against the variables reference today: RAILWAY_DEPLOYMENT_ID, RAILWAY_REPLICA_ID, RAILWAY_SNAPSHOT_ID, RAILWAY_SERVICE_ID, RAILWAY_PROJECT_ID, RAILWAY_ENVIRONMENT_ID, RAILWAY_REPLICA_REGION, RAILWAY_VOLUME_NAME, RAILWAY_VOLUME_MOUNT_PATH. RAILWAY_SNAPSHOT_ID is worth noticing, it has not come up in this thread yet.
Available to your workload from the kernel rather than from Railway, which is the distinction your question turns on: mount ID and the mount's parent from /proc/self/mountinfo, mount namespace identity from /proc/self/ns/mnt, device identity as st_dev from stat() on the mount path, filesystem ID as f_fsid from statfs(), root device and inode from stat() on / and on the mount path, boot identity from /proc/sys/kernel/random/boot_id, and PID namespace from /proc/self/ns/pid. These are all real and readable today. The catch is that they are kernel-local identifiers scoped to one boot and one attachment, so they tell you whether something changed under you, not which provider-side volume incarnation you are holding.
Not available, stated as absences rather than omitted: there is no volume ID variable at all, only the name and the mount path, so the volume's provider-side identity is not exposed to the workload. There is no attachment generation counter anywhere I can find, in the variables or in the public API. And there is no incarnation identity, which is the same conclusion Ben reached from the other direction when he said a service will not know if the volume was restored or cloned.
Which means your item 3 conclusion holds and item 5 does not rescue it. None of the kernel-local values above can serve as a fencing token, because a fresh attachment of the same volume can present the same st_dev and f_fsid and tell you nothing about whether the previous holder is gone. If you need affirmative old-owner revocation, it has to be your own generation number written inside the volume and checked on every start, exactly as nadielo said.
Volumes reference, for the IOPS and the single active mount rule: https://docs.railway.com/volumes/reference
Variables reference, for the provided list: https://docs.railway.com/variables/reference