Security

What we can see, and what we cannot

A backup vendor asks for the most sensitive copy of everything you own. The right response to that request is scepticism, so this page is written to be checked rather than believed, and it says plainly what we have not done yet.

The short answer

Assume we are breached. What did they get?

This is the only threat model worth designing against, because it is the one where our promises stop helping you. The answer is ciphertext and metadata.

We cannot

  • Read the contents of any artifact
  • Recover your data if you lose your private key
  • Shorten or remove a retention hold once it is set
  • See a source credential on the push or self-hosted paths

We can

  • See artifact sizes, checksums, timestamps and run history
  • See backup names, source types, schedules and retention policies
  • See your public key fingerprint
  • Hold a source credential, only when you ask us to run the backup
YOURS, AND IT STAYS YOURSprivate halfnever uploaded, never escrowedlosing it is unrecoverable, by you and by usPUBLIC HALFOURSthe public key and its fingerprintenough to encrypt to you,never enough to read anything backno decryption path exists on our side
Controls

The mechanisms, not the adjectives

PushWE HOLD NOTHINGyou connect, we get a fileYour workerWE HOLD NOTHINGpayload stays in your configManagedWE HOLD A CREDENTIALin a secrets managerTHE ONLY PATH WHERE WE HOLD A CREDENTIAL IS THE ONE WHERE YOU ASK US TO CONNECT.

Encryption

Applied on the machine that produces the data, using a public key you upload. We hold public keys only. There is no escrow, no recovery path through us, and no configuration in which we receive plaintext. A breach of our storage yields ciphertext and file sizes.

Key handling

The private half never leaves your side. That has a real cost, and we would rather you hear it from us: lose the private key and the artifacts encrypted to it are unrecoverable, by you and by us. Key management is your responsibility because the alternative is us holding something worth stealing.

Retention locks

A hold is stamped onto an artifact when it is written, and it can be lengthened but never shortened or removed, by you or by us. That defeats the attack the feature exists for: an intruder with your saved.sh credentials cannot loosen the policy and then delete. It is enforced in our code, so read the limit below before you rely on it.

Credential custody

On the push path we never receive one. On the self-hosted path the source payload lives only in your worker's config, and our API rejects it if sent. On the managed path it goes to a secrets manager, is never a persisted database field, and is released only to the run that needs it.

Access control

Authorization is on permissions, never on a role name. Machine access uses organization-scoped API keys that resolve to a workspace and a permission set, and the same checks apply whether a request arrives from the dashboard, the CLI, the API or a worker.

Data separation

A workspace is the tenant boundary, and it is flat. Backups you execute and backups we execute are driven by two independent orchestration clusters, so a customer-side worker never joins the cluster running our own systems.

Retention

A hold even we cannot lift

Set a hold on a backup and it is stamped onto every artifact written from then on. It can be lengthened. It cannot be shortened or removed, through any API, by you, by anyone holding your credentials, or by us answering a support request.

LOCKED FOR 90 DAYSwrittenexpiresswept on scheduleCANNOT BE SHORTENED, BY YOU OR BY US

The attack it stops

Someone with your account loosens the retention policy, then deletes. Every backup product where protection is inferred from the current policy is open to it. Here the stamp is taken at write time and never recomputed, so editing the policy tomorrow cannot reach back to what is already stored.

Why it binds us too

There is no privileged path, no admin override and no internal tool that clears a hold. Our own retention sweep skips a held artifact rather than deleting it. A protection with a support ticket that undoes it is not a protection.

Where it stops

The hold is enforced in our code, not by the storage layer. It binds every path through our API and our own sweep, and it does not bind someone holding our storage credentials directly. A full compromise of us is still a route to deletion. That is a real gap, it is deliberate, and closing it means a storage-layer lock we have not turned on.

Verify it yourself

The encryption boundary is open source

Everything above is a claim about where encryption happens and what crosses the network. The components that do that work, the worker and the CLI, are open source, so the claim is auditable rather than asserted. They are the only parts that touch plaintext or your key, which is exactly why they are the parts we opened.

Found something wrong here?

Security reports go to security@saved.sh. Tell us what you found and how to reproduce it. We will confirm receipt and keep you updated until it is closed.