I wanted to use this library to push secrets from my env to my github repo easily, and eventually got it figured out. But It would be very helpful to have an example of how to do that since it requires sodiumlib which is extremely difficult to parse if you are trying to figure out the bare minimum needed to encrypt a secret for posting to github.
essentially what I had to do to update the repo's secret was
Authenticate with github
func GithubAuth() (context.Context, *github.Client, error) {
token := os.Getenv("API_GITHUB_TOKEN")
if token == "" {
return nil, nil, errors.New(`no API_GITHUB_TOKNE was found in the environment variables.
This is needed to authenticate with github. Please generate a github token that has access to do what you are trying to do
and export it as an environment variable.
ex:
export API_GITHUB_TOKEN="<token contents string>"
`)
}
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: token},
)
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)
return ctx, client, nil
}
Get the base64 encoded public key of the repo to encrypt a secret using sodiumlib
publicKey, _, err := client.Actions.GetRepoPublicKey(ctx, owner, repo)
encrypt the secret string with the public key
func encryptSecretWithPublicKey(publicKey *github.PublicKey, secretName string, secretValue string) (*github.EncryptedSecret, error) {
decodedPublicKey, err := base64.StdEncoding.DecodeString(publicKey.GetKey())
if err != nil {
return nil, errors.New(fmt.Sprintf("base64.StdEncoding.DecodeString was unable to decode public key: %v", err))
}
secretBytes := []byte(secretValue)
encryptedBytes, exit := sodium.CryptoBoxSeal(secretBytes, decodedPublicKey)
if exit != 0 {
return nil, errors.New("sodium.CryptoBoxSeal exited with non zero exit code")
}
encryptedString := base64.StdEncoding.EncodeToString(encryptedBytes)
keyID := publicKey.GetKeyID()
encryptedSecret := &github.EncryptedSecret{
Name: secretName,
KeyID: keyID,
EncryptedValue: encryptedString,
}
return encryptedSecret, nil
}
bring it all together with AddRepoSecret function
func AddRepoSecret(owner string, repo string, secretName string, secretValue string) (string, error) {
ctx, client, err := GithubAuth()
if err != nil {
return "", err
}
publicKey, _, err := client.Actions.GetRepoPublicKey(ctx, owner, repo)
if err != nil {
return "", err
}
encryptedSecret, err := encryptSecretWithPublicKey(publicKey, secretName, secretValue)
if err != nil {
return "", err
}
_, err = client.Actions.CreateOrUpdateRepoSecret(ctx, owner, repo, encryptedSecret)
if err != nil {
return "", errors.New(fmt.Sprintf("Actions.CreateOrUpdateRepoSecret returned error: %v", err))
}
return secretName, nil
}
Hopefully this helps someone, if there is a direction I should take I can work to contribute this back in some form or another.
I wanted to use this library to push secrets from my env to my github repo easily, and eventually got it figured out. But It would be very helpful to have an example of how to do that since it requires sodiumlib which is extremely difficult to parse if you are trying to figure out the bare minimum needed to encrypt a secret for posting to github.
essentially what I had to do to update the repo's secret was
Authenticate with github
Get the base64 encoded public key of the repo to encrypt a secret using sodiumlib
encrypt the secret string with the public key
bring it all together with AddRepoSecret function
Hopefully this helps someone, if there is a direction I should take I can work to contribute this back in some form or another.