Installation

using homebrew
brew install sops
manual download

download from GitHub https://github.com/getsops/sops/releases

Using SOPS

  1. Create a sops.yaml

    sops.yaml
    creation_rules:
      # encrypt stuff in .secrets
      - aws_profile: default
        kms: arn:aws:kms:eu-central-1:1234567890:key/abcdefg-0123456-abcdefg (1)
        path_regex: ^./secrets/.*$ (2)
    1. We are using AWS KMS for encryption/decryption

    2. All files in the directory .secrets will be encrypted

  2. Inplace Encrypt

    sops -e -i .secrets/mysecret.yaml
  3. Inplace Decrypt

    sops -d -i .secrets/mysecret.yaml

Complete Example using PGP

Install GPG and create a new Key

  1. Install the GPG binaries .Linux / apt

    sudo apt install gnupg
    Mac / brew
    brew install gpg
  2. Generate a new PGP Key

    gpg --full-generate-key
  3. Verify key and note the secret ID

    gpg --list-secret-keys xxxxxx@hascode.io
    sec   rsa3072 2024-04-19 [SC]
          463489240487817F515EC356ECF2BEF801F87203
    uid           [ultimate] Micha Kops <xxxxxx@hascode.io>
    ssb   rsa3072 2024-04-19 [E]

Create a new Secret

create a new Kubernetes secret
cat <<EOF > secret.yaml
apiVersion: v1
kind: Secret
metadata:
    name: my-funny-secret
    namespace: my-namespace
stringData:
    the-password: 123456
EOF

Configure SOPS

we’re configuring SOPS in the working directory to only encrypt data under the data and stringData keys and to use the generated PGP key for encryption.

cat <<EOF > .sops.yaml
---
creation_rules:
- encrypted_regex: '^(data|stringData)$'
  path_regex: ^*.yaml$
  pgp: >-
    463489240487817F515EC356ECF2BEF801F87203
EOF

Encryption and Decryption

We can now encrypt our secret like this:

print encrypted secret to STDOUT
sops -e secret.yaml
inplace encrypt the secret
sops -e -i secret.yaml

our encrypted secret.yaml looks like this now:

apiVersion: v1
kind: Secret
metadata:
    name: my-funny-secret
    namespace: my-namespace
stringData:
    the-password: ENC[AES256_GCM,data:W3w4Rac4,iv:fCwaxjG8K7R0U83Vjmq7zKIq6YxTjdKloesYvMz+/ik=,tag:SzBdfSjvinwSn2QrPvAyxQ==,type:int]
sops:
    kms: []
    gcp_kms: []
    azure_kv: []
    hc_vault: []
    age: []
    lastmodified: "2024-04-19T07:20:44Z"
    mac: ENC[AES256_GCM,data:Q15jBeqpRXtn2GUykxmRW7L6PdDuWpAyijmm+llM1n1j0BMpInWlSeAVjw5xmM9Fg38omRKoARjWx/tkIJUj3Yn8J2TevVGXSuPMA0zS6bYreQLZHw0tOP6+ntk3CW5RxNp90PNwzn3dFSaPJJMCPzh1OZv5dGVSm8k1zromBdw=,iv:jK/89xDNlVF2io74Zu3HwKas66mN2WE/jc+ypgJkwE4=,tag:XkXddzyQHMvF6QHP8kSJig==,type:str]
    pgp:
        - created_at: "2024-04-19T07:20:44Z"
          enc: |-
            -----BEGIN PGP MESSAGE-----

            hQGMA4WZoN27DlrUAQwAgsbOpK28rXLkw05zb/hzUq1wSXmLdF9d6P0wTEzpK6sD
            ZrltoDKPsTlV0pDeNtZ6BGDMFfMEaJ9xPQ7AHf2kveRyjBomCLObbxxzdy9HqdRd
            7CyShz6WRZMbeDDMbIV/nxY9xFvnpJNS7Y6zWalrj0xJHlekJrxGazXAxGK245dX
            bDstF9zBWrLpGtnrWuJXfypDkR9EHkHnv41C2m7HEafAyzMa1DutFmM4ElZrE016
            g0S5dNV94zTdCs8NHLHjXDscoUJm7QvMebdjvsNlAvn34nDUcF175gHklnicQdTE
            5tjCKf5QrmKZBbW430ahXUj6ifLVEUAudc6l11X2lQGi38xKGJHLji1onVLvsc8t
            hepCXnkY5V2ksKmpuyyYXzZryt/nd3rfluGZvdVNHzScBKlE2gnwaEFFRcKEfvyf
            6yFOLLxf9kQH/UThCJULuynhBQ+dNFFtrm0DT/dattxIA7nsgnuy3W4q6Corpbjb
            iZ+dIooff84O+5nFLh5M1GYBCQIQ9UCIktdrPuHK24JHwH8a+vU2JO+cBIvJXPRs
            Rk2qNnPXBAIw0bXC5EbvBfhZod+8y1G/7gbkS5g2bl02y2lJM/7o8RuN4zS+tJsA
            O7J1Cx4lBtXwC1yOS8EBXp6FIyKJCiw=
            =s999
            -----END PGP MESSAGE-----
          fp: 463489240487817F515EC356ECF2BEF801F87203
    encrypted_regex: ^(data|stringData)$
    version: 3.8.1

If we want to decrypt the secret, we can use:

print decrypted secret to STDOUT
sops -d secret.yaml
inplace decrypt the secret
sops -d -i secret.yaml