Skip to content
downpipes docs

Offboarding and a clean, no-custody exit

This page is for the self-hoster decommissioning a downpipes deployment, whether you are leaving the product, consolidating an organisation, or migrating to another provider. Leaving is meant to be boring. It is the no-custody model working as designed: when you are done, your archives are still yours and still recoverable, with neither the engine nor the vendor in the loop.

There is no one-click exit, and that is deliberate. Exit is a short, composed workflow over surfaces you already use, and the order matters. Done in order, it never strands your data. Done out of order, you could delete the engine before you have proven you can still read what it wrote. Read the sequence once before you start, then work it top to bottom.

What you keep, and why it is a complete recovery capability

Before the teardown, understand what survives it, because that is the whole point. Four things, kept together, are a complete recovery capability that needs no engine, no licence, and no vendor.

What you keep Why it matters
The destination bucket Your archives. They are ciphertext object-store bytes, portable to any S3-compatible store.
The downpipe CLI binary The offline reader. It verifies and restores directly from the bucket bytes.
The printed recovery sheet Your public fingerprints and the pins the reader checks against, with no secret on it.
The break-glass private key The one key that decrypts your archives. It was never in the account and never sent to the vendor.

The reason these four are enough is structural, not a promise. The archive format is open and versioned, a versioned format pointer (FORMAT.md) and recovery instructions live in the bucket itself under the _RECOVERY/ prefix, next to the data, while the full specification and the reader are the open-source downpipe project, and the offline CLI reads the bytes wherever they sit using only your break-glass key. So your recoverability does not depend on the vendor being reachable, the licence being active, or the engine still running. It depends only on the format and your own keys, both of which you are keeping.

Getting the Go CLI, and keeping a copy that lasts

The downpipe reader is the open-source CLI, and you can get it either with go install github.com/downpipes/downpipe/cmd/downpipe@latest (Go 1.26 or newer, needs network access to fetch the module) or by building from a clone of the default branch, which needs no network access at all. Either way, before you rely on the binary for a real recovery, run downpipe --help and confirm prune, recombine and unseal-export are all listed: @latest currently resolves to v0.2.0, which carries all three, but a cached module resolution can still hand you an older binary. A GitHub Release exists for v0.2.0 with signed binaries, but it is a maintainer-reviewed draft, not yet a public download, so keeping a clone of the repository alongside the binary is still the more durable choice for something you are holding for the long term: it needs no module proxy and no release page to still work years from now. Neither go install nor a from-source build stamps a release version, so both report dev. The tool follows 0ver, so its version stays below 1.0 and will not become v1.0.0 under that policy. The on-disk archive format string is downpipe/0.1.0, which is the format version the reader understands and is a separate thing from the tool’s own version. Keep the binary alongside your recovery sheet and it will read your archives offline for as long as you retain them. See the command reference for the build and the verify and restore invocations.

The ordered teardown

Work these in order. Each step either captures something you may need later or removes something you no longer should keep, and the ordering guarantees you never remove a capability before you have what replaces it.

  1. Take a final backup and wait for it to land

    Run a final backup of anything you still want captured, and wait for it to complete. The Runs screen shows it ok when the run has sealed to the destination. This is the last point at which the engine writes for you, so make sure the thing you most want preserved is in this run before you go further.

  2. Prove recoverability one last time

    Do not take the final backup on faith. Prove it. Either run a drill from the console, or run downpipe verify against the destination from a clean machine with your break-glass key. A verify recomputes every hash, checks the signed root against your pinned signer, and confirms completeness, so a green result is evidence that the bytes you are about to depend on are genuine and whole. This is the step that turns “we have a bucket” into “we have a recovery capability”. See prove recoverability for the drill and the offline verify.

  3. Export the evidence you may need later

    Export the records that make a later argument or audit possible, and store them off the account. Pull the audit log as JSON with its head hash included (GET /admin/audit/export), the config history (GET /admin/config/history), and a support bundle (GET /admin/support/bundle) for the versions and provenance snapshot. These are small and redaction-safe for customer data, though the audit export does carry operator identity such as emails and addresses, so store it as a sensitive operational record. The head hash is what lets you prove later that the exported chain was not rewritten. These are evidence for a later argument or audit, not a restore artefact; rebuilding a working environment from the signed control-plane export is a separate path, described in recovering downpipes itself.

  4. Revoke the vendor-facing surfaces

    Now wind down the two things that touch the vendor. Revoke any owner-minted pull credentials, so no feed remains live after you leave. There are three scopes and they are not all in one place: the diagnostics scope is under Settings, and the audit-feed and metrics scopes moved onto their own tiles on the Integrations screen. Check all three; revoking the one under Settings leaves the other two live. Each revoke needs a fresh step-up re-authentication. Then let the licence lapse, or remove LICENCE_TOKEN. Nothing operational changes when the licence goes: backups, restores, drills, and the offline reader all keep working exactly as before, because the licence is an assurance and support entitlement, never a key. See licensing and the control plane for precisely what does and does not change.

  5. Disable the schedules

    Pause every downpipe so nothing writes after your final run. With schedules off, the engine is quiet and the destination is frozen at the state your final backup left it in. This is also the point of no further change to the bucket, which is what you want before you start removing compute.

  6. Delete the two Workers and their secrets

    Delete the engine and the console Workers, and their secrets, from your Cloudflare account. This removes all of the compute. Because the vendor holds nothing of yours, there is nothing on the vendor side to cancel beyond the licence subscription itself. The destination bucket is untouched by this step; you are removing the engine that wrote to it, not the archives it wrote.

After the last step, the engine is gone and your four kept artefacts remain. That is the exit complete: no vendor involvement is required for you to retain recoverability, because the kept artefacts are a complete recovery capability on their own.

If you are removing people rather than the whole account

Offboarding individual members is a different job, and it has a guard worth knowing before you start: the engine refuses to remove the last remaining Owner, answering 400 would remove the last Owner, and the same refusal applies whether the removal comes from the console or from a SCIM deprovision. So an account can never be left with no one able to administer it. Under dual control the floor is two Owners rather than one, because a lone Owner could otherwise arm four-eyes approval and have no second Owner to approve anything.

Nothing above is affected by that guard, because deleting the Workers removes the whole control plane rather than a grant within it. See offboard a member for the per-person path and SCIM and deprovisioning for the automated one.

Why the order is what it is

The sequence is not arbitrary. Each early step is a capture, and each late step is a removal, and you never remove before you have captured.

The final backup and the recoverability proof come first because they are the only steps that need a working engine. Once you have a proven-recoverable final run and the evidence exported, the engine has done everything it can do for you, and deleting it costs you nothing. Revoking the vendor surfaces and disabling schedules come next because they stop new activity without removing any capability. Deleting the Workers comes last because it is the irreversible removal, and by the time you reach it you have already proven you do not need them.

The same logic decides what you keep versus what you remove. You remove the things that grant access into the account, the Workers, their secrets, the support credentials, and the standing licence. You keep the things that grant access to your data offline, the bucket, the reader, the recovery sheet, and the break-glass key. The cut runs exactly along the no-custody line.

Two exit shapes: migration and proof-of-deletion

Two endings need a small variation on the last steps.

If the exit is a migration to a new provider or an organisation consolidation, copy the bucket the way you would copy any object-store data. The archives are portable bytes and the reader reads them wherever they sit, so a migration is a bucket copy plus the recovery sheet and key travelling with it. Nothing about the format ties it to the original account.

If the exit must instead prove deletion, do the deletion deliberately and last. Empty and delete the bucket after the evidence exports in the steps above, and record the final audit export, with its head hash, as the closing evidence. That way the deletion is itself attested in a tamper-evident record, and you are not destroying the archives before you have captured the proof that you held and then removed them.

Member offboarding and retiring the bootstrap token are separate ceremonies

Decommissioning the whole deployment is distinct from removing a single person, and distinct again from retiring the one-time bootstrap credential. Both of those have their own pages, and neither is part of the exit teardown above.

Removing a member does two things in the engine and leaves one thing to you. The console removes the departing person’s in-app role immediately and, in the same step, terminates their native downpipes sessions: it bumps the per-email session epoch and the per-subject not-before instant, so any of their sessions fail closed on the very next request, whether held by passkey, recovery code, OIDC, or SAML. The role downgrade no longer leaves the inventory, audit, reports, and roster read surface live until the session TTL expires. What the engine still cannot do is deprovision your identity provider or end a Cloudflare Access session at the edge, because those are Cloudflare-edge tokens the engine does not mint, so that part is yours to do. Nor does removing the role remove the ways that person signs in: their passkey credentials, their banked recovery codes and any unredeemed invite in their name all survive it, and the last two are bearer secrets that each lead back to a fresh credential. Revoking those is a separate action, on the Roles and access tab under Sign-in factors, and on the admin API as POST /admin/signin-factors/revoke. See offboard a member for the ceremony, the three sign-in stores and the hard boundary.

Retiring the bootstrap token belongs to setup hygiene, not exit. The ADMIN_TOKEN is a one-time bootstrap for the first Owner; once your Owner passkey or Cloudflare Access works and you have saved your recovery codes offline, retire it in the Security Centre (immediate, no redeploy) or delete the secret. The engine refuses to retire it until a way back in exists, either recovery codes for an Owner or a second Owner, so retiring it can never strand you. A live shared bearer is one human holding two identities, which quietly defeats dual control, which is why the Security Centre raises a dispose-bootstrap-token finding while it remains live.

Where this fits

For the broader guided wind-down of leaving downpipes, including the no-custody guarantee stated as a promise, see leaving downpipes. For removing a single team member and the identity-provider boundary, see offboard a member. For exactly what does and does not change when the licence lapses, see licensing and the control plane. For the offline verify and restore that prove the kept artefacts are a real recovery capability, see prove recoverability and break-glass offline recovery. For why the kept artefacts are enough on their own, see the no-custody trust model.

Last updated .