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
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
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
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
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
Path to a file containing the master key in JSON format.
Environment variable: RUSTIC_KEY_FILE
Command to execute that outputs the master key to stdout.
Environment variable: RUSTIC_KEY_COMMAND
Password string. Warning: Using this option can reveal the password in process lists.
Environment variable: RUSTIC_PASSWORD
Path to a file containing the password (first line is used).
Environment variable: RUSTIC_PASSWORD_FILE
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
- Key Derivation: rustic uses scrypt with secure default parameters (N=2^15, r=8, p=1)
- Salt: Each key file uses a random 64-byte salt
- Brute Force Resistance: scrypt’s memory-hard properties make brute-force attacks expensive
Master Key Authentication
- Storage: Master keys must be stored securely (encrypted filesystem, secret manager, HSM)
- Backup: Keep secure backups of master keys - loss means data loss
- Access Control: Limit access to master key files/commands
- 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