Directory Layout

The nixos-artifacts-agenix backend stores encrypted secrets in a structured directory hierarchy that separates machine-level secrets (NixOS) from user-level secrets (Home Manager) and shared secrets.

Overview

The storage structure follows this pattern:

secrets/
├── per-machine/
│   └── <machineName>/
│       └── <artifactName>/
│           └── <fileName>.age
├── per-user/
│   └── <username>/
│       └── <artifactName>/
│           └── <fileName>.age
└── shared/
    └── <artifactName>/
        └── <fileName>.age

Path Components

Store Directory

The root directory for all encrypted secrets, configured via the storeDir and flakeStoreDir options (NixOS / Home Manager).

Context Directories

per-machine/

Contains secrets for NixOS system configurations. Each machine has its own subdirectory identified by the hostname.

  • Used when: Deploying NixOS system configurations

  • Encryption keys: publicHostKey + optional publicUserKeys

  • Runtime decryption: Automatic using host SSH keys

  • Configured in: NixOS module (artifacts.config.agenix)

per-user/

Contains secrets for Home Manager user configurations. Each user has their own subdirectory.

  • Used when: Deploying Home Manager user configurations

  • Encryption keys: publicUserKeys only

  • Runtime decryption: Requires identityPaths configuration

  • Configured in: Home Manager module (artifacts.config.agenix)

shared/

Contains secrets that are identical across multiple machines or users. Shared artifacts are encrypted with ALL public keys from all targets that reference them.

  • Used when: Multiple machines/users need access to the same secret

  • Encryption keys: All publicHostKey and publicUserKeys from referencing targets

  • Runtime decryption: Any configured identity can decrypt

  • Configured in: Artifact definition with shared = true

Example artifact definition:

artifacts.store.my-shared-secret = {
  shared = true;
  files = {
    "api-key" = { };
  };
};

Example Layout

A typical repository structure:

secrets/
├── per-machine/
│   ├── laptop/
│   │   └── wifi-password/
│   │       └── psk.age
│   └── server/
│       └── database/
│           ├── password.age
│           └── root-password.age
├── per-user/
│   └── alice/
│       └── git-credentials/
│           └── token.age
└── shared/
    └── backup-encryption-key/
        └── key.age

In this example:

  • wifi-password is specific to laptop and encrypted with its host key only

  • database secrets are specific to server

  • git-credentials belong to user alice

  • backup-encryption-key is shared and encrypted with keys from all machines that reference it