Sops-nix clarification

Hi there.

I have sops-nix installed, the .sops.yaml created, and a secret file created.

I have added the sops-nix.nixosModules.sops to my modules for each machine (in my flake).

Reading the docs (which I found confusing as the “and/or” approach is not formatted to indicate the grouping) and looking at many repos, I have become confused about leveraging the secrets in home-manager and in configuration.nix.

Some have a sops = { type configurations that are quite extensive; others I either missed or they “seem” to not have. I have noted a few different approaches, etc.

Some of the instructions in the original docs did not work as indicated. For example, running the sops secrets/example.yaml would not work. I had to cd secrets; sops example.yaml. I guess I am just at the “reset” point and want to start over with a more clear source. My brain is not quite getting it - even though overall, the docs are good. I am just not jiving with it.

Can someone drop in a link for either:

  • a good clear tutorial (the ones I hit on Google were missing details)
  • or a repo with a “simple” approach. My use case is pretty simple and likely does not need the “extras.”

More than willing to read and do the work. Just looking for a better source of info.

Thank you!

Using

  • flakes
  • home-manager
  • multi-system
  • yaml in sops (vs json)

Secret file

hosts/common/secrets/bashfulrobot.yaml

Unencrypted

openai_api_key: sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
dustin_email: me@there.com
git_signing_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Encrypted

openai_api_key: ENC[AES256_GCM,data:mYCwoNMv0rkawoSTrnFT7KhkGPBUCQwcMzHaOet6L6nVAj/TwQR5SqDKM1eBmWem4sU8,iv:32fJsrvzUo62Z7XM1rBfhW3s23FvmtW2JK8TZTg+L/o=,tag:t82aNJIgOf+5FENO+KHBxA==,type:str]
dustin_email: ENC[AES256_GCM,data:g2NGtbKRrG1m9MRFU4X451x2HvHBOTc=,iv:V1XamLasmkibRkCsUC1G8mFKL8l8wkHOI19Z7AeODDk=,tag:u4oC+uuhokTLkzA0dxnHmA==,type:str]
git_signing_key: ENC[AES256_GCM,data:CnZeMZ5t90UJfOnJG6Yc9DAn2BPq0s1Rs/MTbeVZWFb7zR2Wv7ueMg==,iv:D5UHE7IUnMYyQMeUJrqx3sdnX5+ae8Lnzm0TOfpbXMs=,tag:Fpo1Uj+1KhI1VdNwN0g+Ag==,type:str]
sops:
    kms: []
    gcp_kms: []
    azure_kv: []
    hc_vault: []
    age:
        - recipient: age1qqveqstqurtaznmykpc3gntmrlrnyvlnahq4j2ldwlcjs2kqn9ysdj3rpq
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----
            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtOHYyMXpPOXVxZDhFV3g2
            dFkwMUZoNWJLM3N3Nmc2eis3eTcranIySFRJCmd0Y1BnVHRTY0ZUQ29IU0hDbHZE
            QU9lV0YvL3FRRWdheTBUVHBhREUzeGcKLS0tIDNEK2w2TzQvSFdXRFM5dlJDUjd4
            YnU3UzJhVnFqWjM2OWoxVFVWaU9qY1UKnDh/O99V1xjW3qyVRTPrYUte1aS18PMm
            qm6iFVQuA7imSFrjMcB5nsaVjli41wZeXhCfy+C8uZFNrSUCinYJ5g==
            -----END AGE ENCRYPTED FILE-----
        - recipient: age1qqveqstqurtaznmykpc3gntmrlrnyvlnahq4j2ldwlcjs2kqn9ysdj3rpq
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----
            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMWHdVeDQ4Uml0OU05UE1m
            d1VZVFhYY0M4M3ZCTnBIMWVWNlVxMndxdWwwCmFscFZwb0dYVnhveWsxMWVHM0VE
            QkNTejMraTRCMjM3djF5QUlMcmQrOW8KLS0tIFRMY0hBS2JVVUFDeGRkNWRqM1Rp
            dlNjNDFxUk5CWnZYNVgyUFdFVWJSMUEKVqjpdBbpJXRuHarGMTlPQJf0X3PwQSHs
            OGJJtz+bnbNY0S2W7V9RH5CDKTcDu/yv+xCdehPyWseBwPuY1qWpKg==
            -----END AGE ENCRYPTED FILE-----
        - recipient: age1qqveqstqurtaznmykpc3gntmrlrnyvlnahq4j2ldwlcjs2kqn9ysdj3rpq
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----
            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4b1NLamFpeDk2cldxVGkz
            VnNVZHZnUWdxbVlDbldaTTErZFIzbjJ2TWxNCk9CTkNIanE4QjVFVndiUVJaVnFo
            ZEZVa1NLV0N1d3dTbkRSUTZJYlBTbFEKLS0tIEJyd3p5MmttSzNZRmFlN0xISDkw
            UnZTbDJlb3FHQjF0Q0x5YUZtY0w3b0EKGvV9U8dIYK++jWSXECbI5YvYHaIGqGxJ
            YwQb6A9OjIHqLye3QS8Z+VpeUAZLl3xzc7yF6InxQqMSxfsVNPoaIg==
            -----END AGE ENCRYPTED FILE-----
        - recipient: age1qqveqstqurtaznmykpc3gntmrlrnyvlnahq4j2ldwlcjs2kqn9ysdj3rpq
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----
            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzRHlDYnpmYlhnVGowei9Z
            bk5Wdys0L3A4UHNROGRPbGpmYjJ2bThIbkFVCnlJYkhxeXZtQW54cnBjTlZmT2dL
            bnhFY0xTcVIrejhldXZEVTE2RTYxTVkKLS0tIGx3K1VBK0QyMmZ3eEpxVjZ0L2gy
            Qk5raUZqREpKNzdaMEtmMk1CR2RzZnMK/4aKdBPlb56ureOD7aCsWT9QaS7NQr8i
            PYcX29cyG1o0lLraMbC/JNgEYDHQBV1E5H9NDqjtid5bapgI55xzqQ==
            -----END AGE ENCRYPTED FILE-----
    lastmodified: "2023-07-19T04:47:03Z"
    mac: ENC[AES256_GCM,data:tncT6tXCIEZFTmCLc6uxF+iRvrO0Q61nLuJushviW3VCm7azHHXTCiGALUiVcDv2/VCSXNP7tjBByya+QQSU40rvCE0hxPry3y8+OvOK2cAM+C9fhnTsAaji6fMI+yUHJP2QbYBYJtMnHj1mVb6H9QQLatT71ImjsuUB6sUATGA=,iv:OFdZksi7kCx2stskiytiVG77c1Z7dDBw/ozu0kFIio4=,tag:m+zGRAMhatUeC/pgj4OoKw==,type:str]
    pgp: []
    unencrypted_suffix: _unencrypted
    version: 3.7.3

My nixos-configs repo uses sops-nixs on three hosts: meteion (a NAS), web-server, and zhloe (a router). There is varying levels of complexity in how the secrets are used, but the actual definitions are pretty straightforward. I also use multiple keys for my secrets (both a PGP key for maintenance and server-specific AGE keys), but I don’t think that matters for usage in my configs.

  • All of them use sops.defaultSopsFile = ./secrets.yaml;; and
  • Secrets are defined using sops.secrets.<name>.<settings> with appropriate permissions, users and groups, etc.
1 Like

I started having a look. Curious, why do you not have a .sops.yaml file? Still evaluating, may have followup questions. :+1:

1 Like

OK, so if I look at this example

sops.secrets.smbpasswd.mode = "600"; sets the permissions on the /run/secrets/smbpasswd (expanded form the secrets.yaml, and the /run/secrets/smbpasswd file will literally contain the un-encrypted value?

And when you reference a secrets file, a rebuild is intelligent enough to sub it in where the file is referenced?

So could I do something like:

  programs = {
    git = {
      enable = true;
      userName = "username";
      userEmail = /run/secrets/dustin_email;

<snip>

Now I will look for a home-manager example if my assumptions are correct.

Thank you.

1 Like

Do you mean .sops.yaml? I keep that in a separate repo. When I update secrets, I manually copy the new secrets file over the old one in my configs repo.

Correct.

It will have the path to the secret, and the service will need to be able to read from the file to use it. If rebuilding the config copied the value from the secret, that would copy the secret into the store, which would defeat the point of using something like sops-nix.

That won’t work because programs.git.userEmail needs to be a string not a path.

How would you reference a value then? That’s like 95% of my use case. Declaring the secret, in the secrets.yaml (like my git email example).

The one I pointed out is a great example for apps that will take a password file. I get that part. (Thank you).

I imagine it would be handy to understand how to replace a value in a text file declared with something like foo = ''.

As for .sops.yaml - bang on. I typod it when I posted previously.

I appreciate your time.

Unfortunately, I’m not aware of a way to do secrets for values that doesn’t also copy them to the store.

Well thanks so much for the info you did provide. I’ll keep investigating. :+1:

You do not access a secrets value at evaluation time, you only prepare your configration to find the file at runtime.

If your software can not read the secret from the file you can not use sops or agenix natively for that.

There is scalpel though, which promises to be able to use a secrets value from within the configuration though. It is mentioned in the sops-nix readme and from what I have heard it is also able to use agenix secrets.

I never used it or looked at it in detail.

1 Like

Thank you for the clarification! This helps a ton. I’ll continue to read up.