Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking multiline formating in yaml as soon as a line end with a space #1180

Open
n0rad opened this issue Mar 5, 2023 · 7 comments
Open

Comments

@n0rad
Copy link

n0rad commented Mar 5, 2023

👋

As soon as a line in a multiline value end with a space, sops breaks the multiline formatting and convert to single line with \n

test: |
  line one
  line two with space at the end 
  line three
$ sops --version
sops 3.7.3 (latest)
$ sops -e test.yaml > test.enc.yaml
$ sops -d test.enc.yaml
test: "line one\nline two with space at the end \nline three\n"
@felixfontein
Copy link
Contributor

The content of the YAML is identical, it's only the YAML formatting that changes. If you load both versions with a YAML parser, you obtain the same result. That's intentional, sops never promised to keep the formatting of YAML, only the content.

@n0rad
Copy link
Author

n0rad commented Mar 5, 2023

Sure, I know that it's the same content, but if I do:

test: |
  line one
  line two **without** space at the end
  line three
$ sops -e test.yaml > test.enc.yaml
$ sops -d test.enc.yaml
test: |
    line one
    line two **without** space at the end
    line three

As anyone would expected.

When using sops to store kubernetes secret configuration file encrypted in git for example, coming back to the configuration file and having it one lined definitely break the user experience.

@felixfontein
Copy link
Contributor

definitely break the user experience.

I strongly disagree on that. The aim is to emit an equivalent YAML file containing the same information (including comments). That's what sops does, and what happens in your case as well.

If you want to retain formatting of the YAML file, you probably have to look for another tool. Alternatively let sops encrypt the YAML file as binary data, then you get the exact same content back.

@n0rad
Copy link
Author

n0rad commented Mar 5, 2023

So let me explain the full workflow with the real use case, maybe I'm doing it wrong:

I'm using sops with age to commit kubernetes secrets to git and let flux applying it.
I setup a .sops.yaml file in a parent folder with the public key and configuration to encrypt data part of secrets.
I'm using vscode-sops VScode plugin to call sops as soon as an encrypted file is open, to edit and re-encrypting file when closing it.

Using this workflow all I have to do to edit a secret in VScode is to open, edit, close, commit.

I hit the issue while trying to encrypt wireguard configuration file.

apiVersion: v1
stringData:
    wg0.conf: |
        [Interface]
        Address = 10.43.0.1/24
        ListenPort = 6530
        PrivateKey = EM2K6hssd2G3snCZqk2LsAe/gzvhtwerMTbKCff7iVNvvv0tWI=

        [Peer]
        # srv42
        PublicKey = faFB5CfMSzxlvfxvfdv7X7CZfFtudGVDr+YxnUitcyMuO57u6i9jU=
        AllowedIPs = 10.43.0.2/32

kind: Secret
metadata:
    name: wireguard-server
    namespace: default

The workflow is working perfectly as expected, until I wanted to add a second peer so I open the file and prepare the configuration block. But I did not had the public key yet so closed the file as is:

apiVersion: v1
stringData:
    wg0.conf: |
        [Interface]
        Address = 10.43.0.1/24
        ListenPort = 6530
        PrivateKey = EM2K6hssd2G3snCZqk2LsAe/gzvhtwerMTbKCff7iVNvvv0tWI=

        [Peer]
        # srv42
        PublicKey = faFB5CfMSzxlvfxvfdv7X7CZfFtudGVDr+YxnUitcyMuO57u6i9jU=
        AllowedIPs = 10.43.0.2/32

        [Peer]
        # srv43
        PublicKey = 
        AllowedIPs = 10.43.0.3/32

kind: Secret
metadata:
    name: wireguard-server
    namespace: default

and re-opened it when I had the key but the unencrypted version is now:

apiVersion: v1
stringData:
    wg0.conf: "[Interface]\nAddress = 10.43.0.1/24\nListenPort = 6530\nPrivateKey = EM2K6hssd2G3snCZqk2LsAe/gzvhtwerMTbKCff7iVNvvv0tWI=\n\n[Peer]\n# srv42\nPublicKey = faFB5CfMSzxlvfxvfdv7X7CZfFtudGVDr+YxnUitcyMuO57u6i9jU=\nAllowedIPs = 10.43.0.2/32\n\n[Peer]\n# srv43\nPublicKey = \nAllowedIPs = 10.43.0.3/32\n"
kind: Secret
metadata:
    name: wireguard-server
    namespace: default

Yes YAML content is technically identical, but it's now unmaintainable.

As you guest it, it would be the same for any plain secret file you want to push to kubernetes and any situation where you would leave a trailing space at any line in the configuration file.

@joel-teratis
Copy link

@n0rad have you found a solution for this? This is unfortunate for maintaining yaml files in git.

@n0rad
Copy link
Author

n0rad commented Jul 1, 2024

Nope, I did look for a solution for now but it's ok for my own usage since I always double check each time by closing the file and opening it back to confirm the format.

On the other side, it's a kind of blocker for pushing sops at work for 250+ engineers where I will not ask them to do the check. I suppose we could implement some CI check to do validation but the workflow will be horrible. In the meantime we stay with sealedSecrets.

@haslersn
Copy link

haslersn commented Sep 29, 2024

@n0rad you can store the Secret's values in sops-encrypted files and assemble them into a Kubernetes Secret by putting the following in your kustomization.yaml:

generators:
  - |
    apiVersion: viaduct.ai/v1
    kind: ksops-exec
    metadata:
      name: secret-generator
    secretFrom:
      - metadata:
          name: wireguard-server
        files:
          - wg0.ini

(This requires KSOPS.)

Since .ini is supported by sops, you can even encrypt only the private key by using the following .sops.yaml:

creation_rules:
  - encrypted_regex: "^(PrivateKey)$"

Then your encrypted wg0.ini will look like this:

[Interface]
Address    = 10.43.0.1/24
ListenPort = 6530
PrivateKey = ENC[AES256_GCM,data:erKILuevnjazTJoxzugfQ9Ss85t0nEaCbK7yyEyCPgJySc94bg+Hy9CQiZSt3f7gZHoX,iv:6gsdFlHDRjTdFJynQ8LEN98UkCDrjD9zDrKbggX4rcw=,tag:qNvwl6Axs6t3HOWR2verOQ==,type:str]

[Peer]
; srv42
PublicKey  = faFB5CfMSzxlvfxvfdv7X7CZfFtudGVDr+YxnUitcyMuO57u6i9jU=
AllowedIPs = 10.43.0.2/32

[sops]
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants