Rest-server --append-only : how to delete snapshots?

I have set up a rest-server (on host zoo) and started it with:

rest-server --path /nfs/restic --append-only --private-repos --tls

Creating restic snapshots was successful by a client host and he is not able to delete them, BUT I also cannot delete/forget/prune the snapshots via the server:

root@zoo:~# restic -r /nfs/restic/test forget -n --prune --keep-daily 7
enter password for repository:

For THIS test repository I know the password, because I have created it, but later in production mode I (the rest-server admin) do not know the passwords of the repositories! They are secret by the clients, because they belong to other departments/institutes. They will not share their passwords.

Have I missed something or is the append-only mode only useful if clients and server have the same admin (run by the same institution)?

You have not misunderstanding anything. This is how it works. You cannot BOTH eat the cake AND have it too.

With IBM SP (ex TSM) such a configuration is possible.
But SP’s usage is awkward.

What configuration? That the client can only add backups, but at the same time can also delete backups? :slight_smile:

That the client can only add backups, but the SERVER can delete backups without knowing the secret encryption password of the client. The server must not read (decrypt) the files.

For that to work you either need a backup repository where deduplication is not used on a chunk level, or that the server can somehow determine which parts of the actual data stored matches which snapshots. I suspect SP does not work the same way as restic and is not designed with the same goals in mind. Restic is designed to be completely independent of the server and not trust the server at all.

Maybe you could workaround this problem by implementing a small REST service to handle your scenario without official support in the server or restic?

Just first thoughts on a high level:

  • expose a new https API endpoint in a language of your choice over TLS to ensure secrets are not readable over the network
  • the new API would be hosted on the same server as restic rest server to have access via restic to the local repo
  • the API would get only a HTTP request with the secret and the target repo
  • the retention policy is stored on the server, probably just a config file. The important part is that the client has no control over the retention policy and therefore can’t bypass the append-only mode to delete all backups.

After an successful backup or on a cron schedule, the client could invoke the API over the network, e.g. by using curl and send the password. The password should not be persistent by the API, it should just be passed to the restic CLI invocation to clean up the repo.

If I am not mistaken, this could be a potential solution to your request, but it would require additional coding on your end.
Not sure if the rest server project is willing to add support for something like that, but it would at least not store the secret of the target repo on disk, it would be only available inmemory for the time until the restic call gets submitted. Still, if your server is compromised, you could sniff the secret. But you would be already able to delete files on local disk as well. The difference in the risk profile is, that receiving the secret, even temporary, could still grant an attacker the option to view your files, if the secret gets leaked.

I’m not experienced in cryptography, but this doesn’t seem unreasonable ? Especially if we can imagine this information being encrypted such that the server can decrypt this “index data” (with something like restic key add --access=blob-ownership), while the clients can decrypt everything.

In append-only mode, the client would only be able to link an existing/new blob to a snapshot, but not unlink it (the server could verify that, with its blob-ownership key)

Is there something I’m not thinking about ?

The current design of restic is such that the server cannot tell which blobs exist in a backup. That allows backing up to some storage service without revealing information about the backed up data.

Providing the server with information which blobs exist and are used by which snapshot is a significant deviation from that trust model. Partially disclosing the snapshot structure to the server would also require massive changes in the repository format.

Doesn’t running restic normally (without append-only) and adding/deleting a backup also partially disclose ownership information to the server over time ? e.g., I forget a backup, so I ask the server to delete certain blobs, and now it knows blobs X Y Z were part of that backup. Same thing when creating a backup

Not promising anything, but would you consider a more detailed proposal, with a detailed implementation as well as security considerations ?

And if it is accepted, I can submit a PR for this

No, the server doesn’t know anything about blobs, it only knows pack files. And yes, it could “identify” which pack files were created by which host. However, in later backups, the blobs within such a pack can be re-used by other hosts without the server noticing.

We don’t have the capacity for such a major rework at the moment.

Can you have two rest-servers running with different passwords? One for automated backups with --append-only and one without. The forget --prune part can then be only done with a different password which is not known to the automated part. Two restic keys probably does not help, because nobody prevents you from using the “mutable” rest-server with the other restic key.

I don’t see any reason why not, each would have to listen on a different port of course.
Although you’ve got to weigh the benefits of doing so against the additional attack surface you’re introducing, and whether --append-only still makes sense at that point. Assuming you’re going to run the forget job automatically from the same system as the backup job, I’d argue the answer to that is no.

You could also run the forget/prune job locally on the system running rest-server. The repository is laid out in the regular local format on the system running rest-server, so can also be accessed using the “local” back-end.

That’s what I do. I have an append-only one that “untrusted clients” send their stuff to, and another one for maintenance.

How do you clean up the append-only server ? Do you give it the repository password ?

@iTrooz , I believe that this is the setup which @rawtaz has:

  • One server which is append-only.
  • Another server which is unrestricted. This is used for maintenance. It is only accessed from trusted computers.

Both servers operate on the SAME repository.

That clarifies a bit (Two servers operating on the same repositories is interesting), but AFAIK in any case you’d need the repository password to forget backups. So I assume in this case, the setup would include doing a manual forget of our backups from time to time, from our personal computer ?

You need the repository password for ALL access, including the append-only backups.

  • In addition to that, you might want to configure the append-only rest-server to have a password or not. This password is used to restrict access to this rest-server.
  • The rest-server which is used for maintenance purposes (it does NOT have append-only), you definitely want a good password on that one, which you only use from trusted computers and by trusted persons. This is where you do forget and maybe other kind of maintenance.