This guide helps you migrate from the deprecated accessKey and secretKey options to the secure accessKeyFile and
secretKeyFile options.
The old accessKey and secretKey options store secrets directly in your NixOS configuration, which means:
- Secrets are copied to the Nix store - readable by all users on the system
- Secrets may end up in Git repositories - potentially exposing them publicly
- No encryption - secrets stored in plain text
- Difficult to rotate - changing secrets requires rebuilding the system
The new file-based approach:
- ✅ Keeps secrets out of the Nix store
- ✅ Uses proper Unix permissions (readable only by service user)
- ✅ Supports encryption via sops-nix, agenix, etc.
- ✅ Easier secret rotation
- ✅ Better audit trail
services.rustfs.accessKeyoption has been REMOVEDservices.rustfs.secretKeyoption has been REMOVEDservices.rustfs.accessKeyFileis now REQUIREDservices.rustfs.secretKeyFileis now REQUIRED
Pick one of these options:
- Encrypted secrets
- Git-friendly
- Multi-environment support
- See SECURITY.md for full setup
- Age-encrypted secrets
- Simple setup
- Good for smaller deployments
- Simple but requires manual management
- Good for testing or simple setups
- Not recommended for production
-
Install sops and age:
nix-shell -p sops age
-
Generate age key:
age-keygen -o ~/.config/sops/age/keys.txt -
Create
.sops.yaml:keys: - &admin age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p creation_rules: - path_regex: secrets/.*\.yaml$ key_groups: - age: - *admin
-
Create encrypted secrets file:
mkdir -p secrets sops secrets/rustfs.yaml
Add:
rustfs_access_key: your-access-key-here rustfs_secret_key: your-secret-key-here
-
Generate age key pair on your server:
ssh your-server "age-keygen -o /var/lib/age/key.txt" -
Encrypt secrets:
age -r age1... -e -o secrets/rustfs-access-key.age <<< "your-access-key" age -r age1... -e -o secrets/rustfs-secret-key.age <<< "your-secret-key"
On your server:
sudo mkdir -p /run/secrets
echo "your-access-key" | sudo tee /run/secrets/rustfs-access-key
echo "your-secret-key" | sudo tee /run/secrets/rustfs-secret-key
sudo chown rustfs:rustfs /run/secrets/rustfs-*
sudo chmod 400 /run/secrets/rustfs-*services.rustfs = {
enable = true;
accessKey = "rustfsadmin"; # ❌ INSECURE!
secretKey = "rustfsadmin"; # ❌ INSECURE!
volumes = "/tmp/rustfs";
address = ":9000";
};{ config, pkgs, ... }:
{
# Add sops-nix import to your flake.nix first!
sops = {
defaultSopsFile = ./secrets/rustfs.yaml;
age.keyFile = "/var/lib/sops-nix/key.txt";
secrets = {
rustfs-access-key = {
owner = config.services.rustfs.user;
group = config.services.rustfs.group;
mode = "0400";
};
rustfs-secret-key = {
owner = config.services.rustfs.user;
group = config.services.rustfs.group;
mode = "0400";
};
};
};
services.rustfs = {
enable = true;
accessKeyFile = config.sops.secrets.rustfs-access-key.path; # ✅ SECURE
secretKeyFile = config.sops.secrets.rustfs-secret-key.path; # ✅ SECURE
volumes = "/var/lib/rustfs"; # Use persistent storage
address = ":9000";
consoleAddress = "127.0.0.1:9001"; # Localhost only
};
}{ config, pkgs, ... }:
{
# Add agenix import to your flake.nix first!
age.secrets = {
rustfs-access-key = {
file = ./secrets/rustfs-access-key.age;
owner = config.services.rustfs.user;
group = config.services.rustfs.group;
mode = "0400";
};
rustfs-secret-key = {
file = ./secrets/rustfs-secret-key.age;
owner = config.services.rustfs.user;
group = config.services.rustfs.group;
mode = "0400";
};
};
services.rustfs = {
enable = true;
accessKeyFile = config.age.secrets.rustfs-access-key.path;
secretKeyFile = config.age.secrets.rustfs-secret-key.path;
volumes = "/var/lib/rustfs";
address = ":9000";
};
}services.rustfs = {
enable = true;
accessKeyFile = "/run/secrets/rustfs-access-key";
secretKeyFile = "/run/secrets/rustfs-secret-key";
volumes = "/var/lib/rustfs";
address = ":9000";
};Update your flake.nix:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
rustfs.url = "github:rustfs/rustfs-flake";
rustfs.inputs.nixpkgs.follows = "nixpkgs";
# Add sops-nix OR agenix
sops-nix.url = "github:Mic92/sops-nix";
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
# OR
# agenix.url = "github:ryantm/agenix";
# agenix.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, rustfs, sops-nix, ... }: {
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
rustfs.nixosModules.rustfs
sops-nix.nixosModules.sops # or agenix.nixosModules.default
./configuration.nix
];
};
};
}-
Test locally first (if possible):
nixos-rebuild build --flake .#myhost -
Deploy to server:
nixos-rebuild switch --flake .#myhost --target-host root@your-server -
Verify the service is running:
ssh your-server sudo systemctl status rustfs sudo journalctl -u rustfs -n 50
-
Test functionality:
curl http://your-server:9000/ -u "access-key:secret-key"
After confirming the service works:
-
Remove old configuration:
- Delete any files with plain-text secrets
- Remove old commits from Git history (if secrets were committed)
-
Rotate secrets (recommended):
# Generate new keys NEW_ACCESS_KEY=$(openssl rand -base64 32) NEW_SECRET_KEY=$(openssl rand -base64 32) # Update in sops sops secrets/rustfs.yaml # (Update the values manually) # Redeploy nixos-rebuild switch --flake .#myhost --target-host root@your-server
The service user can't access the secret file. Check:
# Check if file exists
ls -la /run/secrets/rustfs-*
# Should show:
# -r-------- 1 rustfs rustfs ... rustfs-access-key
# -r-------- 1 rustfs rustfs ... rustfs-secret-key
# Fix ownership if needed:
sudo chown rustfs:rustfs /run/secrets/rustfs-*
sudo chmod 400 /run/secrets/rustfs-*Age key not found or wrong key. Check:
# Verify key file exists
ls -la /var/lib/sops-nix/key.txt
# Verify the public key matches .sops.yaml
sudo cat /var/lib/sops-nix/key.txt
# Re-encrypt with correct keys
sops updatekeys secrets/rustfs.yamlCheck logs:
sudo journalctl -u rustfs -n 100 --no-pagerCommon issues:
- Secret file doesn't exist
- Wrong permissions
- Service can't read LoadCredential paths
If something goes wrong:
# Rollback to previous generation
nixos-rebuild switch --rollback
# Or use generation number
nixos-rebuild switch --switch-generation 123After migration, verify:
- Service starts successfully:
systemctl status rustfs - No errors in logs:
journalctl -u rustfs -n 50 - API responds:
curl http://server:9000/ - Console accessible (if enabled)
- Can authenticate with new credentials
- No secrets in
/nix/store:grep -r "your-secret" /nix/store(should find nothing) - Secret files have correct permissions (400)
- Secret files owned by rustfs user
If you encounter issues:
- Check the SECURITY.md documentation
- Review the example configuration
- Check service logs:
journalctl -u rustfs -f - Open an issue on GitHub with:
- Your sanitized configuration (remove all secrets!)
- Error messages from logs
- NixOS version:
nixos-version