I’ve been in front of this problem for several months now and can’t seem to find a proper solution.
Plan:
I want to use macOS local APFS snapshots as the source of restic backups.
So whenever restic is scheduled to run a backup command, my idea is to make a local APFS snapshot, mount it and then point restic at this read only mounted APFS snapshot.
All this logic is put in a bash script and being scheduled with launchd.
Problem:
In order to automatically mount a local APFS snapshots with this script, I have to add bash to the list of FDA (Full Disk Access) applications in the macOS settings pane.
I have tried all the tricks I could think of but couldn’t find a way other than the above.
From a security perspective I absolutely don’t want to give bash full disk access to my machine.
That’s just not going to happen.
So I guess this isn’t restic specific I guess, but around it heh
Here is a little screenshot showing how I set it up and reproduced it:
I only ever backed up ~ or stuff thereunder, in case that matters. But what I can say is that without giving that .app FDA it will produce a lot of read errors during backup runs, and having given it FDA it’s happy. I’ve tried other methods too through the years but this one always works for me.
The thing is, I know of another backup software which has allowed access to Apples private APFS APIs and I am super jealous that they are gatekeeping it from others.
Making an .app bundle using the software you recommended worked to mount the local APFS snapshot! Thank you
Now I need to see if using launchd to schedule this, works as well. But a first test by simply starting the .app with the bash script which invokes restic, tmutil and mount_apfs commands worked perfectly.
Hey all Another year went by and another major macOS release comes around the corner bringing all kinds of “joy”. So this post seems rather unrelated to Restic itself, but as I’m trying to figure out how to use a macOS feature to do macOS backups via Restic, I thought I post it here in the case others have ventured out this route as well.
Apple must have changed things around FDA (Full Disk Access) and TCC (Transparency, Consent, and Control) with apps.
For some reason some things broke. So if someone is using a similar setup with:
Shell script bundled in an app like Platypus
The Shell script creates a local APFS snapshot AND mounts it for use with Restic
I would love to hear if and how you got that working.
Creating a snapshot is not an issue, but mounting it results in an error. The script from the beginning of the post is able to reproduce the problem.
What I’m confused about is this: If I add my Terminal app, in this case Alacritty, to the list in FDA and execute the Bash script manually, everything works as expected. Below is the output of the script running and the commands that are executed.
I see some errors in the console.app regarding this and I have a hunch that this is because of some security flag. Not sure if it’s SIP but I bet it’s related.
Ha! I think I solved it. Man this is somewhat involved if you don’t know your ways around and have some understanding of the security features of macOS.
The solution was: Signing the Platypus created app bundle with a self signed Code Signing certificate.
Here is what I did:
In the Keychain Access app using the Certificate Assistant, I created a local Code Signing certificate which is trusted only by my computer as it is the CA issuing the certificate
Created an app bundle via Platypus which contains the Bash script and put it in /Applications/
Signed the app bundle like this: codesign -s 'Restic B2 (test) - Moritz Dietz' '/Applications/Restic B2 - 3.app'
Check the man page for codesign for more info
3.1 For good measure I checked that it worked:
codesign --verify --verbose '/Applications/Restic B2 - 3.app'
/Applications/Restic B2 - 3.app: valid on disk
/Applications/Restic B2 - 3.app: satisfies its Designated Requirement
Removed an earlier entry of the app bundle from the FDA list in the Systems Settings app (they renamed it with macOS Ventura )
Re-added the new app bundle to the FDA list and switched the toggle to on
Then started the app and here’s a screenshot of it working
In a setup like this (with snapshots), your restic backup doesn’t contain /Users but /tmp/restic/backup, right?
If so, restoring from such a backup cannot be done ‘in place’. Or is there something I am missing? E.g. can I tell during backup/restore to change every path? E.g. on backup make sure that /tmp/restic/backup becomes /Users so that a restore can be in place?
Funny. I am curious what exactly happened when I used restore -t / to restore /opt/local from a snapshot last week, as in my experience it did just that (but maybe it worked only partly and I was just lucky)
Are you sure your permission problem isn’t due to the fact that / has been changed to /System/Volumes/Data several macOS releases ago (and thus your /Users should be /System/Volumes/Data/Users)?
That’s what I had to do to make it work—I didn’t have to code-sign.
Yeah I’m pretty sure, because of what I see in the console log (see the post above the solution).
Additionally I want to point out that I don’t backup /Users/ on the live system, I backup a mounted APFS Snapshot of / which is mounted at /tmp/restic/backup/ and makes my home directory accessible at /tmp/restic/backup/Users/.