twpayne / chezmoi

Manage your dotfiles across multiple diverse machines, securely.

Home Page:https://www.chezmoi.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SOPS Support

mhalano opened this issue · comments

Is your feature request related to a problem? Please describe.

I want to use SOPS to encrypt the secrets from my infrastructure (actually just my personal laptop).
The detail is: I want for the system secrets, like my default login password that will be put under /etc/shadow during the provision, as well the user secrets, like the API keys present in the environment variables that are part of my shell config file and will be populated during the system provision.

The problem is how to easily template the values from SOPS file using Chezmoi?

It would be ok to use custom command, but SOPS doesn't return a JSON formatted exit if the secret file isn't using JSON. I'm using YAML, for instance, so the exit would be YAML.

Describe the solution you'd like

I would like to have a template option where I can call SOPS, and it's correspondent key to get the value, something like {{ sops "apis.openai" }} and return the value from the YAML, or JSON.
It could be implemented as an encryption tool too as well, to decrypt on-the-fly .sops files, similar to what is done today with .gpg files.

I'm using SOPS because I like the feature where it's just encrypt the fields, not the whole file. That's why I'm not using GnuPG directly (it's the backend, though).

Describe alternatives you've considered

I considered storing all the chezmoi.yaml file that has my secrets under data section out of my repository because of the secrets.
I also considered encrypting with GnuPG, but I would lose the vision of the YAML (since SOPS just encrypts the values) and I would need to use GnuPG basically for good (SOPS has multiple backends so I can change when I want).

Additional context

What I'm doing is to use SOPS to encrypt/decrypt the secrets that are imported by my Ansible playbook to be used in my infrastructure configuration. I would like to use the same file, to keep secrets centralized, and be able to decrypt from Chezmoi directly to use the values in the templates.

If you have any questions, please, let me know. I saw a discussion about SOPS some years ago, but I think I can provide a more concrete user case for the feature.

I would like to have a template option where I can call SOPS, and it's correspondent key to get the value, something like {{ sops "apis.openai" }} and return the value from the YAML, or JSON.

Are you sure that this is possible with SOPS? I haven't used SOPS, but from looking at its README.md, it looks like SOPS can only handle whole files and cannot decrypt individual secrets.

Specifically, if you have {{ sops "apis.openai" }} in your template, what command should chezmoi run to get the secret?

You're right. SOPS decrypt all the file. Maybe we could have a secretYAML, similar to secretJSON, that could parse the value?
If this isn't possible, we can still have a .sops file that runs sops -d <filename>.

There's already a fromYaml template function so you can set the secret.command chezmoi configuration variable to sops and then do something like:

{{ (secret "-d" "my-sops-file.yaml" | fromYaml).apis.openai }}

Understood. Nice to know. Maybe then we could just implement the support for .sops files?

Understood. Nice to know. Maybe then we could just implement the support for .sops files?

That would require re-implementing sops, so no.

Given that you can use the above example in your templates, or call the sops binary from a run_ script, I'll close this issue as not planned.

commented

Hi, i just got here looking to do the same, Im looking to use encrypted variable stored in my dotfiles.

For what I've been reading, there is no direct support for this however looking at this issue I've comeup with a small change to what you proposed:
{{- $secret_vars:= (joinPath .chezmoi.sourceDir ".chezmoi_vars.yaml.age" | include | decrypt |fromYaml) -}}

my idea is to be able to use (for example) "{{ .secret_vars.mypassword }}" in a template.

is this ok?
I've also noticed I need to place this snippet on top of every template, can this be done globally and define these vars upon chezmoi execution ?

thanks!

is this ok?

Yes-ish. It works, but you're effectively writing your own password manager at this point, one that stores all your secrets in an encrypted YAML file.

I've also noticed I need to place this snippet on top of every template, can this be done globally and define these vars upon chezmoi execution ?

No, this cannot be done globally (unless you want to store your secrets unencrypted in your chezmoi config file).