Sops-nix: attribute 'path' missing

I’m trying to use sops-nix to protect the environment variables used in oci-containers. From my testing, the secrets files get created properly, but now I’m trying to integrate them into the rest of my configuration.

I think I’ve got it setup, but when I try to rebuild, I get the following error:

[root@zen:~]# nixos-rebuild boot --flake /persist/nixos#zen
building the system configuration...
error: attribute 'path' missing

       at /nix/store/w104a6cjyypqazh7frcnagqk93prkj04-source/hosts/zen/default.nix:79:13:

           78|           environmentFiles = [
           79|             sops.secrets."env-frigate".path
             |             ^
           80|           ];
(use '--show-trace' to show detailed location information)

From the documentation, I thought .path was an automatic field created by sops-nix to provide the file path to the secret. I’ve gone through it a few times but don’t see any mention of something else I need to do to get that to appear, and all of my searches show people accessing it similarly to what I have here.

What am I missing?

Below is an abbreviated copy of the nixos config I’m building with.

flake.nix

{
  description = "NixOS config";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";

    fps = {
      url = "github:wamserma/flake-programs-sqlite";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    sops-nix = {
      url = "github:Mic92/sops-nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { nixpkgs, ... }@inputs: {
    nixosConfigurations = {
      zen = nixpkgs.lib.nixosSystem {
        specialArgs = { inherit inputs; }; # Pass flake inputs to our config
        modules = [ ./hosts/zen/default.nix ];
      };
    };
  };
}

default.nix

{ inputs, lib, config, pkgs, ... }:
let
  hostName = "zen";
in rec {
  imports = [
    ./hardware-configuration.nix
    ../common.nix
    inputs.sops-nix.nixosModules.sops
  ];

  # ...

  sops = {
    defaultSopsFile = ./secrets.yaml;
    age = {
      keyFile = "/persist/keys/${hostName}/age-key.txt";
      generateKey = false;
    };
    secrets = {
      "env-frigate" = {};
      # ...
    };
  };

  virtualisation = {
    oci-containers = {
      backend = "podman";
      containers = {
        # ...

        "frigate" = {
          image = "ghcr.io/blakeblackshear/frigate:stable";
          extraOptions = [
            "--shm-size=64m"
            "--device=/dev/bus/usb:/dev/bus/usb"
            "--mount type=tmpfs,target=/tmp/cache,tmpfs-size=1000000000"
          ];
          volumes = [
            "/etc/localtime:/etc/localtime:ro"
            "/docker/frigate:/config:ro"
            "/media/frigate:/media/frigate"
          ];
          ports = [ "5000:5000" ];
          environmentFiles = [
            sops.secrets."env-frigate".path
          ];
        };
      };
    };
    podman.enable = true;
  };
}

You want to use config.sops.secrets."env-frigate".path instead of sops.secrets."env-frigate".path.

1 Like

That did the trick! Thank you!

It seems confusing that I define the sops data right there in the same file, but have to actually use it via config.sops. I guess that is just Nix lazy evaluation at work to do the building of the secrets?

It’s more the architecture of nixpkgs/ the module system than lazyness: sops.secrets."env-frigate".path tries to access an attribute path in the recursive attrset your module-function returns. The config argument passed into modules can be thought of as the complete merged configuration of all nixos modules.

1 Like