Skip to main content
Credentials represents the authentication information needed to open and access a rustic repository. It supports two authentication methods: password-based and master key-based.

Type Definition

pub enum Credentials {
    Masterkey(MasterKey),
    Password(String),
}

Variants

Masterkey

Masterkey
MasterKey
Direct authentication using a cryptographic master key. This bypasses password-based key derivation and provides direct access to the repository encryption key.
Use cases:
  • Automated/scripted backups without password prompts
  • CI/CD pipelines
  • Service accounts
  • Emergency repository access
Security: The master key must be stored securely. Loss of this key means permanent data loss.

Password

Password
String
Authentication using a password. The password is used with the scrypt key derivation function to decrypt the repository’s master key.
Use cases:
  • Interactive use
  • Human-operated backups
  • Initial repository setup
  • Standard backup operations
Security: Passwords should be strong and unique. rustic uses scrypt with recommended parameters for key derivation.

Constructor Methods

password

Convenience constructor for password-based credentials.
pub fn password(pass: impl AsRef<str>) -> Self
pass
impl AsRef<str>
required
The password string to use for authentication
Example:
use rustic_core::Credentials;

let creds = Credentials::password("my-secure-password");

Usage Examples

Opening with Password

use rustic_core::{Repository, RepositoryOptions, Credentials};
use rustic_backend::BackendOptions;

let backends = BackendOptions::default()
    .repository("/tmp/repo")
    .to_backends()?;

let credentials = Credentials::password("my-password");

let repo = Repository::new(&RepositoryOptions::default(), &backends)?
    .open(&credentials)?;

Opening with Master Key

use rustic_core::{Repository, Credentials, repofile::MasterKey};

// Load master key from secure storage
let key_data = std::fs::read("path/to/masterkey.json")?;
let master_key: MasterKey = serde_json::from_slice(&key_data)?;

let credentials = Credentials::Masterkey(master_key);

let repo = Repository::new(&repo_opts, &backends)?
    .open(&credentials)?;

Initializing a Repository

With Password

use rustic_core::{
    Repository, Credentials, KeyOptions, ConfigOptions
};

let credentials = Credentials::password("new-repo-password");

let repo = Repository::new(&repo_opts, &backends)?
    .init(
        &credentials,
        &KeyOptions::default(),
        &ConfigOptions::default()
    )?;

With New Master Key

use rustic_core::{Credentials, repofile::MasterKey};

// Generate a new random master key
let master_key = MasterKey::new();

// IMPORTANT: Save this key securely before proceeding!
let key_json = serde_json::to_string_pretty(&master_key)?;
std::fs::write("masterkey.json", key_json)?;

let credentials = Credentials::Masterkey(master_key);

let repo = Repository::new(&repo_opts, &backends)?
    .init(&credentials, &key_opts, &config_opts)?;

CredentialOptions

For flexible credential handling, especially in CLI applications, use CredentialOptions:
#[derive(Clone, Default, Debug, Deserialize, Serialize, Setters)]
pub struct CredentialOptions {
    pub key: Option<String>,
    pub key_file: Option<PathBuf>,
    pub key_command: Option<CommandInput>,
    pub password: Option<String>,
    pub password_file: Option<PathBuf>,
    pub password_command: Option<CommandInput>,
}

Fields

key
Option<String>
Master key as a JSON string. Warning: Avoid using this in production as it may expose the key in process lists.
Environment variable: RUSTIC_KEY
key_file
Option<PathBuf>
Path to a file containing the master key in JSON format.
Environment variable: RUSTIC_KEY_FILE
key_command
Option<CommandInput>
Command to execute that outputs the master key to stdout.
Environment variable: RUSTIC_KEY_COMMAND
password
Option<String>
Password string. Warning: Using this option can reveal the password in process lists.
Environment variable: RUSTIC_PASSWORD
password_file
Option<PathBuf>
Path to a file containing the password (first line is used).
Environment variable: RUSTIC_PASSWORD_FILE
password_command
Option<CommandInput>
Command to execute that outputs the password to stdout.
Environment variable: RUSTIC_PASSWORD_COMMAND

credentials Method

Evaluate credential options and return appropriate Credentials.
pub fn credentials(&self) -> RusticResult<Option<Credentials>>
Returns None if no credentials are configured. Example:
use rustic_core::CredentialOptions;
use std::path::PathBuf;

let cred_opts = CredentialOptions::default()
    .password_file(PathBuf::from("/secure/password.txt"));

if let Some(credentials) = cred_opts.credentials()? {
    let repo = Repository::new(&repo_opts, &backends)?
        .open(&credentials)?;
}

Advanced Examples

Password from File

use rustic_core::CredentialOptions;
use std::path::PathBuf;

let cred_opts = CredentialOptions::default()
    .password_file(PathBuf::from("/etc/rustic/password"));

let credentials = cred_opts.credentials()?
    .expect("No credentials configured");

let repo = Repository::new(&repo_opts, &backends)?
    .open(&credentials)?;

Password from Command

use rustic_core::{CredentialOptions, CommandInput};

// Use password manager or secret service
let cred_opts = CredentialOptions::default()
    .password_command("pass show backup/repo".into());

let credentials = cred_opts.credentials()?
    .expect("No credentials configured");

let repo = Repository::new(&repo_opts, &backends)?
    .open(&credentials)?;

Master Key from File

use rustic_core::CredentialOptions;
use std::path::PathBuf;

let cred_opts = CredentialOptions::default()
    .key_file(PathBuf::from("/secure/masterkey.json"));

let credentials = cred_opts.credentials()?
    .expect("No credentials configured");

let repo = Repository::new(&repo_opts, &backends)?
    .open(&credentials)?;

Master Key from Secure Command

use rustic_core::{CredentialOptions, CommandInput};

// Retrieve from secure vault
let cred_opts = CredentialOptions::default()
    .key_command("vault kv get -field=key secret/backup".into());

let credentials = cred_opts.credentials()?
    .expect("No credentials configured");

let repo = Repository::new(&repo_opts, &backends)?
    .open(&credentials)?;

CLI Integration

With the clap feature:
use clap::Parser;
use rustic_core::CredentialOptions;

#[derive(Parser)]
struct Cli {
    #[clap(flatten)]
    cred_opts: CredentialOptions,
}

let cli = Cli::parse();

let credentials = cli.cred_opts.credentials()?
    .ok_or_else(|| "No credentials provided")?;

let repo = Repository::new(&repo_opts, &backends)?
    .open(&credentials)?;

Security Considerations

Password-Based Authentication

  1. Key Derivation: rustic uses scrypt with secure default parameters (N=2^15, r=8, p=1)
  2. Salt: Each key file uses a random 64-byte salt
  3. Brute Force Resistance: scrypt’s memory-hard properties make brute-force attacks expensive

Master Key Authentication

  1. Storage: Master keys must be stored securely (encrypted filesystem, secret manager, HSM)
  2. Backup: Keep secure backups of master keys - loss means data loss
  3. Access Control: Limit access to master key files/commands
  4. Rotation: Consider key rotation strategies for long-lived repositories

Best Practices

For Interactive Use

// Prompt user for password
let password = rpassword::prompt_password("Repository password: ")?;
let credentials = Credentials::password(password);

For Automated Systems

// Use environment variable or secure command
let cred_opts = CredentialOptions::default()
    .key_command("get-secret backup-masterkey".into());

let credentials = cred_opts.credentials()?
    .expect("Credentials must be configured for automated backups");

For CI/CD

// Use secret management integrated with CI/CD platform
std::env::set_var("RUSTIC_KEY_COMMAND", "vault kv get -field=key ci/backup");

let cred_opts = CredentialOptions::default();
let credentials = cred_opts.credentials()?
    .expect("CI credentials not configured");

Warnings

Never commit passwords or master keys to version control.
Using --password or setting RUSTIC_PASSWORD may expose credentials in process lists or shell history.
Always securely back up your master key when using Credentials::Masterkey. Loss of this key means permanent data loss.

Key Management Operations

Adding Additional Keys

// Open with existing credentials
let repo = Repository::new(&repo_opts, &backends)?
    .open(&Credentials::password("current-password"))?;

// Add new password-based key
let new_key_id = repo.add_key(
    "additional-password",
    &KeyOptions::default()
)?;

println!("Added new key: {}", new_key_id);

Removing Keys

let repo = Repository::new(&repo_opts, &backends)?
    .open(&credentials)?;

// Remove a specific key (cannot remove the currently used key)
repo.delete_key(&old_key_id)?;

MasterKey Structure

The MasterKey type wraps the repository’s encryption keys:
pub struct MasterKey {
    pub mac: Mac,
    pub encrypt: Vec<u8>,
}

pub struct Mac {
    pub k: Vec<u8>,  // MAC key
    pub r: Vec<u8>,  // Random value
}

Creating a MasterKey

use rustic_core::repofile::MasterKey;

// Generate new random key
let master_key = MasterKey::new();

// Serialize for storage
let json = serde_json::to_string_pretty(&master_key)?;
std::fs::write("masterkey.json", json)?;

Loading a MasterKey

use rustic_core::repofile::MasterKey;

let json = std::fs::read_to_string("masterkey.json")?;
let master_key: MasterKey = serde_json::from_str(&json)?;

let credentials = Credentials::Masterkey(master_key);

See Also

Build docs developers (and LLMs) love