Search code examples
gogithub-actionsgithub-api

How to encrypt repository secret for Github Action Secrets API


To use the Github Action Secrets API for creating repository secret, we have to encrypt the secret key using sodium library. Github docs. Example for Go is not provided. Could anybody help me out by writing a function to encrypt the secret?

My current implementation is as follows:

func EncodeWithPublicKey(text string, publicKey string) (string, error) {
    // Decode the public key from base64
    publicKeyBytes, _ := base64.StdEncoding.DecodeString(publicKey)
    fmt.Printf("%x\n\n", publicKeyBytes)

    // Generate a key pair
    _, privateKey, _ := box.GenerateKey(rand.Reader)
    fmt.Printf("Private key: %x\n\n", *privateKey)

    // Convert publickey to bytes
    var publicKeyDecoded [32]byte
    copy(publicKeyDecoded[:], publicKeyBytes)

    // Encrypt the secret value
    nonce := new([24]byte)
    encrypted := box.Seal(nil, []byte(text), nonce, &publicKeyDecoded, privateKey)
    fmt.Printf("%x\n\n", encrypted)

    // Encode the encrypted value in base64
    encryptedBase64 := base64.StdEncoding.EncodeToString(encrypted)
    fmt.Printf("%x\n\n\n", encryptedBase64)

    return encryptedBase64, nil
}

I am using golang.org/x/crypto/nacl/box.

The action secret is set incorrectly as of current implementation because the build process prompts me with an error "apiToken not found". However, if I set the secret using GitHub's website, the deployment works.


Solution

  • I had to change Seal to SealAnonymous

    func EncodeWithPublicKey(text string, publicKey string) (string, error) {
        // Decode the public key from base64
        publicKeyBytes, err := base64.StdEncoding.DecodeString(publicKey)
        if err != nil {
            return "", err
        }
    
        // Decode the public key
        var publicKeyDecoded [32]byte
        copy(publicKeyDecoded[:], publicKeyBytes)
    
        // Encrypt the secret value
        encrypted, err := box.SealAnonymous(nil, []byte(text), (*[32]byte)(publicKeyBytes), rand.Reader)
    
        if err != nil {
            return "", err
        }
        // Encode the encrypted value in base64
        encryptedBase64 := base64.StdEncoding.EncodeToString(encrypted)
    
        return encryptedBase64, nil
    }