How to securely manage Restic passwords in Win11

I’m posting this here to help document the way I found to use the Windows Credential Manager to manage the passwords I use with Restic. I do this in the hope that Google can help me find this the next time I need it, because it took a bit of work to figure out.

There is very little documentation on how to manage Restic passwords securely in Windows. You can store them in bat files, or in environment variables, or in text files that get sucked in with RESTIC_PASSWORD_FILE, but I wanted something more secure (but still fairly easy).

My solution stores passwords in the Windows Credential Manager, which you access this via the Credential Manager widget on the Control Panel.

Step 1: Credentials Manager

The Credentials Manager has two sections: Web Credentials and Windows Credentials. We want Windows Credentials. Under that are three poorly demarked sections, Windows Credentials, Certificate-Based Credentials, and Generic Credentials. Click Add a generic credential (just to the right of the Generic Credentials heading), and enter restic (or whatever you want to call it) for Internet or network address, put something (it doesn’t really matter) for User Name, and put your password under Password. Click OK, and now you’ve stored a credential for Restic to use. You can modify or delete this credential later if you like.

Step 2: Powershell Script

Now we need a way to tell Restic how to extract and use the credential we just created. There are probably several ways to do this, but we’ll use a short Powershell script. Create a file called restic_password.ps1 in a convenient location, and copy the following script to it:

param (
    [string]$Target
)

$cred = Get-StoredCredential -Target $Target
$pass = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
    [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($cred.Password)
)

Write-Output $pass

This script takes a single parameter and outputs your password to the console. You can test it by opening a cmd.exe window (not Powershell), and running the command:

powershell.exe "restic_pw.ps1 restic"

(note that the quotes surround both arguments)

where restic_pw.ps1 is the full path to the script file you created, and restic is the name of the credential you created in Step 1. Note that you can use this same file to extract different credentials by changing restic to the name of another credential.

Note that if this returns an error, you might need to install the CredentialsManager Powershell module, which you can do with the following command issued from a Powershell prompt:

Install-Module -Name CredentialManager -Scope CurrentUser

Step 3: Restic

Finally, to use this password, set the environment variable RESTIC_PASSWORD_COMMAND from the cmd prompt:

set RESTIC_PASSWORD_COMMAND=powershell.exe "restic_pw.ps1 restic"

(again, pay attention to the quotes). Restic will now use the password you stored in Windows Credential Manager.

Example:

restic -r rclone:Goog:Restic snapshots

Alternatively, you can pass the command directly to restic with the --password-command option:

Example:

restic -r rclone:Goog:Restic snapshots --password-command="powershell.exe \"restic_pw.ps1 restic\""

(again, note the use of quotes, and, this time, backslashes)

I use this with Backrest, leaving the repository password blank and using the Environment Variable option. Flags would probably work too, except Backrest will object to your lack of password.

6 Likes

Thanks, this is great! Some suggestions:
To retain the environment variable through reboots, you can run Command Prompt as Administrator and use SETX instead of SET: SETX /M RESTIC_PASSWORD_COMMAND “pwsh.exe -File C:\restic-backups\restic_password.ps1 restic”

Also, “powershell.exe” is legacy. I recommend using pwsh.exe unless you’re on an older version of Windows.

At least on Unix systems the standard pattern is to write a wrapper script for restic that automatically sets the necessary environment variables and then just calls restic with whatever parameters were passed to the script. That probably also works with powershell and has the huge benefit of not requiring system-wide changes.