Github Actions API が公開され、 Secrets を API 経由で更新できるようになりました
Github Actions で利用する Secrets はこれまで手作業で更新する必要がありました。
たくさんのレポジトリを管理していてそれぞれに Actions を仕込むときに更新がとても大変でした。
そんな中、 Github Actions API が公開(2020/1/27)され、 Secrets の更新が API 経由で行えるようになりました
Secrets | Github Developer Guide
Secrets API の概要
Secrets は秘密鍵、公開鍵を用いて暗号化しているのですが、 Github Actions では libsodium を使って実現しているようです。
- 暗号化に使う公開鍵を Github Actions API を使って取得します。
- key_id と key が取得できます。 (libsodium で Secrets を暗号化するための公開鍵です)
- key は base64 でエンコードされているのでデコードしてバイナリに戻します。
- 公開鍵を用いて Secrets を暗号化します。
- Github Actions API を使って Secrets 名と暗号化された Secrets を送信します。
- Github Actions で用いるときに秘密鍵で復号化して Secrets を利用しているものと思われます。
Go で API を叩いてみます
Go には google/go-github という Github API のライブラリが存在します。
ただ、 2020/1/31 現在、まだこのライブラリでは Github Actions API をサポートしてない模様です。
調べてみると、既にサポート PR が出ていたので試してみました。
go.mod
replace github.com/google/go-github/v29 => github.com/martinssipenko/go-github/v29 v29.0.3-0.20200130054045-bbe3d535861d
func UpdateSecret(owner, repo, name, secret string) error {
// Github Client を用意
sts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
)
oc := oauth2.NewClient(context.Background(), sts)
cli := github.NewClient(oc)
// 公開鍵を取得
pubKey, _, err := cli.Actions.GetPublicKey(context.Background(), owner, repo)
if err != nil {
fmt.Println("error GetPublicKey:", err.Error())
return err
}
pkBase64 := pubKey.GetKey()
pk := make([]byte, 32)
_, err = base64.StdEncoding.Decode(pk, []byte(pkBase64))
if err != nil {
fmt.Println("base64 decode error:", pkBase64, err.Error())
return err
}
// sodium で暗号化を施す
encSec := sodium.Bytes(secret).SealedBox(sodium.BoxPublicKey{Bytes: pk})
encSecBase64 := base64.StdEncoding.EncodeToString(encSec)
// Secret を更新
es := &github.EncryptedSecret{
Name: name,
KeyID: *pubKey.KeyID,
EncryptedValue: encSecBase64,
}
_, err = cli.Actions.CreateOrUpdateSecret(context.Background(), owner, repo, es)
if err != nil {
fmt.Println("failed to update secret", err.Error())
return err
}
return nil
}
これで無事 Secret を API 経由で更新できました