Open4

sops+age

fujiwarafujiwara

age-keygen で秘密鍵を作成

$ age-keygen
# created: 2025-04-02T11:23:31+09:00
# public key: age1cv3dr3v47j50f2x7pqc52rytpc4wu5njfemjl5szmfstq6s7qurs3z3rdt
AGE-SECRET-KEY-185YM8X9YZU5X6KYAZGC25ZA6RQSVVH***(略)

sopsがデフォルトで見るのは $XDG_CONFIG_HOME/sops/age/keys.txt or $HOME/.config/sops/age/keys.txt なのでそこにこの出力を置いておく。

暗号化したいファイル

foo:
  value: secret
  description: 秘密の値だよ

descriptionは暗号化したくないので .sops.yaml を置く

# .sops.yaml (.sops.yml だと動かないので注意)
creation_rules:
  - unencrypted_regex: 'description'

sops --age で公開鍵を指定して暗号化

$ sops --encrypt --age age1cv3dr3v47j50f2x7pqc52rytpc4wu5njfemjl5szmfstq6s7qurs3z3rdt example.yml
foo:
    value: ENC[AES256_GCM,data:Z/mK9Mah,iv:pieD5wyPMf/6zOSA7uMlmbKsJf+kp2fi7O0DDIlqwpU=,tag:Cvyw489ie/LHbaFAYwAstg==,type:str]
    description: 秘密の値だよ
sops:
    age:
        - recipient: age1cv3dr3v47j50f2x7pqc52rytpc4wu5njfemjl5szmfstq6s7qurs3z3rdt
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----
            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZSWdSZ20yQkhBWHhHdEI4
            dk1NeE0xejNXbi9MZURUbTJpc0NxNWtheWx3CldnOVlhN0N3UFJFazlNZ1NzMHcx
            RXcyVjhXKzlNSms1cTFiSURvSHhUZzgKLS0tIEd4aWd4ejhNdjIwWmVZYnJWdzFu
            N1VJMHhwTHVyUU8xanpPS2dkb0Q5Zk0Kw7dILWAclnU7yAJWs9XObWzyfB70KdRV
            GFEdInNSZmeK+LcaDdMzfxalvIc300t0jqkMNF3VXNI+UOpmbQequQ==
            -----END AGE ENCRYPTED FILE-----
    lastmodified: "2025-04-02T02:29:23Z"
    mac: ENC[AES256_GCM,data:2i+Q/iFAUA3wzlCVCxtDRk1b2WQwhVoDBieLHgCE7Hi803L5VFHmGt5jzIAFopApl5JRU0d/NA1NVV1PtAuKUf+ZSlMH6Mn5E4wP0Z4Yt7Abz3MkjCcglSkR2Ag0XfXjPbM16/8z7TbeFhcrsQWL0t/MSo69fGp1eIUxTxCSkTM=,iv:nEer9x0ZQp1hecwsclUJyLmYGIn2OxyFoReuKtTf4E0=,tag:rL6VCyRyuPEyjl6C8avbQw==,type:str]
    unencrypted_regex: description
    version: 3.10.1

暗号化された sops の出力には公開鍵が書いてあるので、秘密鍵が所定の場所(~/.config/sops/age/keys.txtとか)にあれば複合はオプションなしでできる。ファイル名を指定したい場合は環境変数 SOPS_AGE_KEY_FILE、秘密鍵を直接(AGE-SECRET-KEY-...)指定したい場合は SOPS_AGE_KEY で指定可能。

$ sops --encrypt --age age1cv3dr3v47j50f2x7pqc52rytpc4wu5njfemjl5szmfstq6s7qurs3z3rdt example.yml > example.enc.yml
$ sops --decrypt example.enc.yml 
foo:
    value: secret
    description: 秘密の値だよ
fujiwarafujiwara

GoでDecryptはできる。依存pacakgeが多いのがちょっと難点(バイナリがかなり大きくなる)。

https://pkg.go.dev/github.com/getsops/sops/v3/decrypt

設定(鍵のありか)などを指定したい場合は環境変数で設定。

package main

import (
	"os"

	"github.com/getsops/sops/v3/decrypt"
)

func main() {
	b, err := decrypt.File("example.enc.yml", "yaml")
	if err != nil {
		panic(err)
	}
	os.Stdout.Write(b)
}
fujiwarafujiwara

Goに組み込まなくても、bashのプロセス置換を使って sops -d を実行したstdoutをファイルとして読めばいいのでは?

$ somecommand --config <(sops -d example.enc.yaml)