Use case · Encrypted recovery copy
Create an Encrypted Backup of Coding-Agent Sessions
Reinstate RC8 can create a client-encrypted recovery copy of selected Claude Code or Codex sessions in your own S3-compatible bucket. It encrypts before upload, excludes known credential material, and can restore through the same vendor—but it is not a complete backup system, so keep independent, restore-tested backups too.
- Last verified
- Current release
- v0.1.0-rc.8
- Release status
- pre-1.0 release candidate
- Owner
- Harjot Singh Rana
A narrow encrypted recovery copy, not a general backup product
RC8 snapshots explicitly selected, supported Claude Code or Codex CLI session artifacts and uploads them only after local age passphrase encryption. The provider receives ciphertext, opaque snapshot keys, sizes, timing, account identity, and bucket metadata. It does not receive the encryption passphrase.
“Backup” here means a recoverable encrypted copy of supported agent-session state. Reinstate does not back up repositories, uncommitted work, home directories, vendor accounts, credentials, every agent, or the complete execution environment. It does not promise provider retention, point-in-time recovery, or automatic background scheduling in RC8.
| Included | Excluded or separate |
|---|---|
| Selected supported Claude Code or Codex session artifact | Other agents and unsupported or untested layouts |
| Encrypted manifest and immutable snapshot metadata | Git repository, branch, worktree, and uncommitted changes |
| Portable known structural project paths | Free-form paths inside transcript prose or tool output |
| Conflict and local replacement safety | Vendor login, API keys, OAuth, .env, keyrings, or credential stores |
| Same-vendor restore | Native Claude Code-to-Codex or Codex-to-Claude conversion |
Where encryption and trust boundaries sit
- A supported adapter discovers the selected local vendor artifact and known structural path fields.
- Reinstate normalizes configured project paths, packages the immutable snapshot, and encrypts it locally with an age scrypt recipient derived from the passphrase.
- HTTPS carries ciphertext to the private bucket under
profiles/PROFILE_ID/snapshots/<opaque-id>.age. - The encrypted
manifest.agerecords the current remote session revisions. - A restore downloads and fully authenticates/decrypts the artifact before any vendor file is mutated.
Storage credentials entered interactively are stored in macOS Keychain, Windows Credential Manager, or the supported OS keyring. The passphrase is not stored by Reinstate. Losing it means losing the ability to decrypt the remote profile by design.
Create the encrypted copy deliberately
First configure a private bucket with the narrow read, list, write, and delete access required by RC8. TheAmazon S3 guideandCloudflare R2 guideseparate provider setup from Reinstate setup.
After rein init, setup checks, and a synthetic self-test pass:
rein list --agent AGENT
rein push --agent AGENT --session SESSION_ID --dry-run
rein push --agent AGENT --session SESSION_ID
rein statusChoose exactly one harmless session for the first run. The dry-run must saywould push and must not create a snapshot. The mutating push should report the selected count and a remote revision. Avoid --all until the full discovered scope has been reviewed.
Encryption cannot un-publish a secret already in a transcript.
Known credential files are excluded, but a token pasted into agent conversation is session content and will be protected as part of the encrypted snapshot. If such a token was exposed, rotate it; do not treat encryption as remediation.
Verify ciphertext and recoverability separately
A .age suffix alone is not proof. Perform two controlled checks without publishing transcript data.
1. Inspect the provider boundary
- The profile prefix contains
manifest.ageand opaquesnapshots/*.ageobjects. - No plaintext JSON/JSONL transcript,
.env,auth.json, token, or credential object exists. - A privately downloaded snapshot does not contain a known harmless marker in plaintext.
- The temporary initialization probe has been deleted.
- The bucket remains private and uses no public website or development URL.
2. Test a destination restore
On a separately configured compatible device—or an isolated Reinstate home with an approved test target—join the exact profile UUID, map the same project ID, and run:
rein setup check
rein doctor --self-test
rein status
rein pull --agent AGENT --session SESSION_ID --dry-runConfirm the planned native destination and backup root. Close the same-vendor agent, perform the pull, then use claude --resume SESSION_ID orcodex resume SESSION_ID. A backup is credible only after a controlled recovery drill reaches the intended session.
Current physical Mac/Windows and other native-device acceptance rows remain open for RC8. Personal restore evidence must not be represented as project-wide stable certification.
What protects an existing destination
- Pull offers a non-mutating
--dry-runthat reports destinations and the backup root. - A wrong passphrase fails authentication before agent-file mutation.
- An active same-vendor process causes safety exit
7before replacement. - An existing destination is copied into a timestamped local backup before atomic replacement.
- Diverged local and remote revisions produce conflict exit
6, not silent last-writer-wins. rein conflicts resolve CONFLICT_ID --keep-bothcan preserve both branches.
These controls protect restore operations; they do not prevent a bucket administrator or compromised write credential from deleting, replacing, or rolling back ciphertext.
Failure and recovery decisions
| Failure | What remains safe | Next action |
|---|---|---|
| Storage probe fails | RC8 does not save a usable-looking config | Correct endpoint, Region, bucket, credential, or delete access; retry init. |
| Push dry-run fails | No remote session snapshot was written | Resolve compatibility, selection, path, keyring, or provider access first. |
| Passphrase is lost | Local vendor files and independent backups may remain | Do not overwrite local history; the remote ciphertext cannot be decrypted. |
| Remote manifest disappears | Additional devices fail closed instead of treating the profile as empty | Preserve snapshots and restore the manifest through an approved provider recovery process. |
| Local and remote copies diverge | Pull records a conflict without overwriting local state | Inspect metadata and choose keep-local, keep-remote, or keep-both explicitly. |
| Provider credential is exposed | Session plaintext still requires the separate passphrase | Revoke or rotate the credential, audit objects, preserve local copies, and investigate tampering. |
RC8 has no general undo or remote-session deletion command. Provider cleanup must target only a reviewed profiles/PROFILE_ID/ tree after participating devices stop and required evidence or backups are preserved. Never delete only manifest.age.
Build an independent backup plan around it
The encrypted Reinstate profile and the independent backup should fail differently. Keeping both in the same bucket, account, credential boundary, and retention policy can turn one provider mistake into total loss.
- Keep source code and repository history in the approved Git workflow.
- Protect uncommitted work with a separately reviewed endpoint or workstation backup.
- Retain the encryption passphrase in a password manager with an authorized recovery path.
- Decide provider versioning, lifecycle, Object Lock, or bucket-lock policy deliberately.
- Test retention controls before applying them: the manifest changes, init probes need delete access, and archival tiers can make ordinary pull unavailable.
- Schedule harmless restore drills and record only redacted metadata and pass/fail evidence.
Current limitations
- RC8 uses explicit pushes and pulls; it is not an automatic backup daemon.
- It has no built-in schedule, retention policy, remote pruning, or provider version restore.
- Snapshots are complete immutable session artifacts rather than block- or delta-level backups.
- Only recognized Claude Code and Codex CLI same-vendor workflows can mutate state.
- Project path mapping does not reproduce Git, runtimes, shells, environment, or agent configuration.
- Remote confidentiality does not protect a compromised local device or guarantee availability.
- A formal pre-1.0 security audit is not claimed.
Encrypted session backup FAQ
Can the storage provider read my session?
The provider should receive age-encrypted manifests and snapshots, not plaintext session contents or the passphrase. It can still observe account, bucket, object keys, sizes, request timing, and access patterns.
Does provider-side encryption replace Reinstate encryption?
No. S3 or R2 encryption at rest is useful defense in depth. Reinstate's client-side encryption creates the boundary in which the provider receives ciphertext.
Are agent credentials backed up?
No. Known auth files, OAuth material, API keys, .env files, credential stores, and keyring contents are excluded. Configure vendor authentication independently on a restored device.
Can I restore the session into another agent vendor?
No. RC8 restores Claude Code state to Claude Code and Codex state to Codex CLI. Explicit portable handoffs are later product direction, not a hidden conversion performed by backup restore.
Should I enable immutable retention on the profile?
Not without testing. The encrypted manifest changes as sessions are pushed, and the initialization probe requires deletion. Object Lock or bucket-lock rules can block those operations. Provider versioning can be valuable, but cleanup and restore procedures must account for old versions and delete markers.
How often should I test recovery?
Use a cadence appropriate to the value and change rate of the sessions. Every test should use harmless data, preview restore, verify the mapped destination, preserve existing state, and prove native resume without exposing transcript contents.