> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/soriphoono/homelab/llms.txt
> Use this file to discover all available pages before exploring further.

# Secrets Management

> Managing secrets with agenix and sops-nix

This homelab uses **agenix** for secrets management, allowing you to encrypt secrets with age and store them safely in Git. The configuration supports per-user secrets, team secrets, and shell integration.

## Architecture

The secrets management system consists of:

* **agenix**: Encrypts secrets with age public keys
* **sops-nix**: Alternative secrets backend (configured via `.sops.yaml`)
* **secrets.nix**: Centralized secrets configuration with user/team mapping
* **agenix-shell**: Makes secrets available in development shells

## Secrets Configuration Structure

The `secrets.nix` file defines three key components:

### 1. User Public Keys

```nix theme={null}
users = {
  soriphoono = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEgxxFcqHVwYhY0TjbsqByOYpmWXqzlVyGzpKjqS8mO7";
};
```

These SSH public keys are used to encrypt secrets for specific users.

### 2. Per-User Secrets

```nix theme={null}
userSecrets = {
  github_token = ["soriphoono"];
};
```

Defines which users can access specific secrets.

### 3. Team Secrets

```nix theme={null}
teams = {
  default = {
    users = ["soriphoono"];
    secrets = [];
  };
};
```

Allows shared access across multiple team members.

## Adding a New Secret

<Steps>
  <Step title="Add the secret to secrets.nix">
    Edit the `userSecrets` or team's `secrets` list:

    ```nix theme={null}
    userSecrets = {
      github_token = ["soriphoono"];
      api_key = ["soriphoono"]; # New secret
    };
    ```
  </Step>

  <Step title="Create the encrypted secret file">
    Use `agenix` to create and edit the secret:

    ```bash theme={null}
    agenix -e secrets/api_key.age
    ```

    This opens your `$EDITOR` to input the secret value. The file is automatically encrypted with the appropriate public keys based on your `secrets.nix` configuration.
  </Step>

  <Step title="Commit the encrypted secret">
    The `.age` file is safe to commit:

    ```bash theme={null}
    git add secrets/api_key.age
    git commit -m "Add API key secret"
    ```
  </Step>

  <Step title="Deploy to systems">
    Reference the secret in your NixOS configuration:

    ```nix theme={null}
    age.secrets.api_key = {
      file = ./secrets/api_key.age;
      owner = "myuser";
      group = "users";
    };
    ```

    The decrypted secret will be available at `/run/agenix/api_key` on the target system.
  </Step>
</Steps>

## SOPS Configuration

The `.sops.yaml` file configures sops-nix with age keys for different users and systems:

```yaml theme={null}
keys:
  - &admin_soriphoono age1y4x8gzzcdhxvqaf9matt0eze3z3yxwx607avq4cexfkgwal4psesj39lvn
  - &system_lg_laptop age1yqsdglc9s03k6yhefaqpnpyurj0j9nktlccc8rq2uevpuzn0ea2stx0msr
  - &system_zephyrus age1vz3rjjgwq9t3288mwlt9cdyt83429srm8hwycjrflllhcwkkugvs0jafa0

creation_rules:
  - path_regex: homes/soriphoono(@[^/]+)?/[^/]+\.(yaml|json|env|ini)$
    key_groups:
      - age:
          - *admin_soriphoono
```

### Path-based Encryption Rules

SOPS uses path regex patterns to determine which keys can decrypt files:

* **Home secrets**: `homes/<user>/` files are encrypted for that user and admins
* **System secrets**: `systems/<hostname>/` files include the system's age key

This allows granular control over who can decrypt what.

## Shell Integration

The `agenix-shell` integration automatically loads secrets as environment variables in your development shell:

```nix theme={null}
agenix-shell-secrets = {
  GITHUB_TOKEN = {
    file = ./secrets/github_token.age;
  };
};
```

Secrets are:

* Converted to uppercase for environment variable names
* Only loaded for users with access
* Available in `nix develop` shells

## Security Best Practices

<Warning>
  * Never commit unencrypted secrets to Git
  * Always verify `.age` files are encrypted before committing
  * Rotate secrets if a private key is compromised
  * Use system-specific keys for production systems
</Warning>

## Converting SSH Keys to Age

To get an age public key from an SSH key:

```bash theme={null}
ssh-to-age < ~/.ssh/id_ed25519.pub
# Output: age1y4x8gzzcdhxvqaf9matt0eze3z3yxwx607avq4cexfkgwal4psesj39lvn
```

For the private key:

```bash theme={null}
ssh-to-age -private-key -i ~/.ssh/id_ed25519 > ~/.config/age/key.txt
```

## Editing Existing Secrets

To modify an encrypted secret:

```bash theme={null}
agenix -e secrets/github_token.age
```

This decrypts the secret, opens your editor, and re-encrypts on save.

## Common Issues

### "No decryption key found"

Ensure your private key is available:

* SSH key at `~/.ssh/id_ed25519`
* Age key at `~/.config/age/key.txt`

### "Public key not found in secrets.nix"

Add your user to the `users` mapping in `secrets.nix` with your SSH public key.

### Secrets not loading in shell

Check that:

1. You're in a `nix develop` shell with agenix-shell enabled
2. Your user has access to the secret in `secrets.nix`
3. The secret file exists at `secrets/<name>.age`
