🚀
goでgithub actionsのsecretをencryptしてterraformでapplyする
つい先日terraformでgithub actionsのsecretを管理できることを知り、goでencrypt -> terraform apply -> actionsで動作確認まで行ったのでまとめ。
terraformのoutputでrepositoryのpubkeyを取得
data "github_repository" "example" {
full_name = "seita-uc/example"
}
data "github_actions_public_key" "example" {
repository = data.github_repository.example.name
}
output "public_key" {
value = data.github_actions_public_key.example.key
}
outputでbase64 encodedのrepository public keyが取得できる。
pubkeyで任意の文字列をencryptする
github actions apiのdocumentで述べられている通り、github actionsのsecretはLibSodiumという暗号ライブラリによって作成されているので、このライブラリの暗号方式に準拠した方法でsecretを作成してあげる必要があります。
documentでも複数言語でのsnippetが提示されていますが、goのsampleは今のところないので、terraformのgithub actionsのdocumentで紹介されているGo '/crypto/box' moduleを用いてsecretのencrypted valueを作成します。
以下の<base64-encoded-github-repository-public-key>
に上のstepで取得したbase64 encodedのrepository public keyを渡せば、pubkeyで署名したplain-text-secret
をbase64でencodeした値が得られます。
package main
import (
"bytes"
"crypto/rand"
"encoding/base64"
"fmt"
"io"
"golang.org/x/crypto/nacl/box"
)
func main() {
decodedPubKey, err := base64.StdEncoding.DecodeString("<base64-encoded-github-repository-public-key>")
if err != nil {
panic(err)
}
var serverPubKey = new([32]byte)
_, err = io.ReadFull(bytes.NewReader(decodedPubKey), serverPubKey[:])
if err != nil {
panic(err)
}
var (
msg = []byte("plain-text-secret")
out []byte
)
rawEncryptedValue, err := box.SealAnonymous(out, msg, serverPubKey, rand.Reader)
if err != nil {
panic(err)
}
fmt.Println(base64.StdEncoding.EncodeToString(rawEncryptedValue))
}
terraform apply
先ほどのterraformファイルに以下の定義を追加します。
resource "github_actions_secret" "example_secret" {
repository = data.github_repository.example.name
secret_name = "example_secret_name"
encrypted_value = "<上で取得した値>"
}
actionsでsecretを確認
以下のactionをdispatchして設定したsecretがmatchするか確認できます。
name: Echo
on: workflow_dispatch
jobs:
echo:
runs-on: ubuntu-latest
steps:
- name: Echo
if: ${{ env.EXAMPLE_SECRET_NAME == 'plain-text-secret' }}
run: echo "match"
env:
EXAMPLE_SECRET_NAME: ${{ secrets.EXAMPLE_SECRET_NAME }}
Reference
github provider
github actions api
Discussion