Skip to content

sops-install-secrets decrypts the same sops file once per secret, causing repeated FIDO2/YubiKey prompts #956

Description

@schroedermatthias

pkgs/sops-install-secrets/main.go in decryptSecret (current master, also present in earlier tags) has a broken decrypt cache:

func decryptSecret(s *secret, sourceFiles map[string]plainData) error {
    sourceFile := sourceFiles[s.SopsFile]
    if sourceFile.data == nil || sourceFile.binary == nil {
        plain, err := decrypt.File(s.SopsFile, string(s.Format))
        ...

The intent is "decrypt the file once, reuse for all subsequent secrets from the same sopsFile". The actual condition fires every time: for YAML/JSON secrets with a non-empty key, only sourceFile.data is populated and sourceFile.binary stays nil. For binary/dotenv/INI secrets it's the opposite. So data == nil || binary == nil is always true for a single source file, and decrypt.File is invoked once per secret entry.

For age-plugin-based hardware tokens (age-plugin-fido2-hmac, age-plugin-yubikey) each decrypt.File triggers a fresh PIN/touch prompt. A host with 5 secrets in one secrets.yaml therefore has to PIN+touch the YubiKey/Security Key 5 times per darwin-rebuild switch / home-manager switch, even though the manifest references a single sopsFile.

Repro

sops.defaultSopsFile = ./secrets.yaml;
sops.secrets = {
  a = { };
  b = { };
  c = { };
};

with a FIDO2 age recipient. Observe 3× PIN+touch instead of 1.

Fix proposal

Use a real existence check, e.g.

if _, cached := sourceFiles[s.SopsFile]; !cached {
    plain, err := decrypt.File(...)
    ...
    sourceFiles[s.SopsFile] = sourceFile
}

A minimal one-character fix (||&&) also works for the common cases where each sopsFile is accessed uniformly via key or as a whole file, but does not cover mixing the two access modes against the same file.

Workaround

Override sops.package with a postPatch build that flips || to &&. Drops 5× FIDO2 prompts to 1× on a Darwin/home-manager host with a single consolidated secrets.yaml.

Environment

  • Platform: aarch64-darwin, home-manager module
  • sops-nix: c591bf665727040c6cc5cb409079acb22dcce33c
  • age plugins: age-plugin-fido2-hmac 0.5.0, age-plugin-yubikey 0.5.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions