Claude-skill-registry-data Managing Secrets

How secrets are stored, decrypted, and used on the devbox. Use when adding, removing, or debugging secrets.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry-data
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry-data "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/managing-secrets" ~/.claude/skills/majiayu000-claude-skill-registry-data-managing-secrets && rm -rf "$T"
manifest: data/managing-secrets/SKILL.md
source content

Managing Secrets

Secrets are managed with sops-nix using age encryption. They're encrypted in the repo and auto-decrypted at boot.

Current Secrets

SecretUsageHow it's consumed
github_ssh_key
Git operationsDeployed to
~/.ssh/id_ed25519_github
cloudflared_tunnel_token
Cloudflare tunnelSystemd service reads from
/run/secrets/
cloudflare_api_token
Wrangler CLIExported as
CLOUDFLARE_API_TOKEN
in bash
op_service_account_token
1Password bootstrapAvailable at
/run/secrets/
for scripts
claude_personal_oauth_token
Headless Claude CodeExported as
CLAUDE_CODE_OAUTH_TOKEN
in bash

How Secrets Flow

secrets/devbox.yaml (encrypted in git)
        ↓
sops-nix decrypts at boot using /persist/sops-age-key.txt
        ↓
/run/secrets/<secret_name> (plaintext, mode 0400)
        ↓
Consumed by: systemd services, bash exports, or file deployment

Adding a New Secret

Step 1: Add to sops file

# Edit encrypted file (requires age key access)
sudo nix-shell -p sops --run "SOPS_AGE_KEY_FILE=/persist/sops-age-key.txt sops secrets/devbox.yaml"

# Or use sops set for non-interactive:
sudo nix-shell -p sops --run "SOPS_AGE_KEY_FILE=/persist/sops-age-key.txt sops set secrets/devbox.yaml '[\"my_new_secret\"]' '\"secret-value\"'"

Step 2: Declare in NixOS config

Edit

hosts/devbox/configuration.nix
, add to
sops.secrets
:

sops.secrets = {
  # ... existing secrets ...

  my_new_secret = {
    owner = "dev";
    group = "dev";
    mode = "0400";
    # Optional: deploy to specific path instead of /run/secrets/
    # path = "/home/dev/.config/app/secret";
  };
};

Step 3: Consume the secret

Option A: Export as env var (for CLI tools)

Edit

users/dev/home.linux.nix
:

programs.bash.initExtra = lib.mkAfter ''
  if [ -r /run/secrets/my_new_secret ]; then
    export MY_ENV_VAR="$(cat /run/secrets/my_new_secret)"
  fi
'';

Option B: Use in systemd service (for daemons)

systemd.services.my-service = {
  serviceConfig = {
    ExecStart = "${pkgs.writeShellScript "run" ''
      exec my-command --token "$(cat /run/secrets/my_new_secret)"
    ''}";
  };
};

Option C: Deploy as file (for apps expecting file path)

Set

path
in the secret declaration (Step 2).

Step 4: Apply changes

git add secrets/devbox.yaml hosts/devbox/configuration.nix
git commit -m "feat: add my_new_secret"

sudo nixos-rebuild switch --flake .#devbox
home-manager switch --flake .#dev  # if you added bash export

Removing a Secret

Step 1: Remove from consumers

  • Remove any bash exports from
    users/dev/home.linux.nix
  • Remove any systemd service references
  • Remove declaration from
    hosts/devbox/configuration.nix

Step 2: Remove from sops file

sudo nix-shell -p sops -p yq-go --run "
  cd /home/dev/projects/workstation
  SOPS_AGE_KEY_FILE=/persist/sops-age-key.txt sops -d secrets/devbox.yaml > /tmp/secrets-plain.yaml
  yq -i 'del(.secret_to_remove)' /tmp/secrets-plain.yaml
  SOPS_AGE_KEY_FILE=/persist/sops-age-key.txt sops encrypt --age age1kyd7dzxtgte0rcd0nj3chfvcfvammhywe63f25tlsrf8knhf3u8sxp8z9n --input-type yaml --output-type yaml /tmp/secrets-plain.yaml > secrets/devbox.yaml
  rm /tmp/secrets-plain.yaml
"

Step 3: Apply and commit

git add -A && git commit -m "chore: remove secret_to_remove"
sudo nixos-rebuild switch --flake .#devbox

Key Files

FilePurpose
secrets/devbox.yaml
Encrypted secrets (committed to git)
secrets/.sops.yaml
sops config (which keys can decrypt)
/persist/sops-age-key.txt
Age private key (never in git, root-only)
hosts/devbox/configuration.nix
Secret declarations for sops-nix
users/dev/home.linux.nix
Bash exports for env vars

Troubleshooting

"permission denied" when editing secrets

The age key is root-only. Use

sudo
with nix-shell:

sudo nix-shell -p sops --run "SOPS_AGE_KEY_FILE=/persist/sops-age-key.txt sops secrets/devbox.yaml"

Secret not appearing after rebuild

  1. Check it's declared in
    sops.secrets
    in configuration.nix
  2. Run
    sudo nixos-rebuild switch
    (not just home-manager)
  3. Verify:
    ls -la /run/secrets/

Env var not exported

  1. Check the export is in
    home.linux.nix
    (not
    home.nix
    - that's shared with Darwin)
  2. Run
    home-manager switch
  3. Start a new shell (exports only apply to new shells)

Security Notes

  • Secrets are encrypted at rest with age (AES-256)
  • Decrypted secrets are mode 0400 (owner read-only)
  • The age key lives on
    /persist/
    which survives rebuilds but not re-provisioning
  • Never commit the age private key or decrypted secrets
  • Env var exports are in
    home.linux.nix
    so they only apply on devbox, not Darwin