0

I am using golang as backend language using Google Cloud KMS. I have enabled KMS service and created keyrings in Cryptographic Keys tabs. Assigned Cloud KMS CryptoKey Encrypter/Decrypter role to google user and service account, though it returns error when running app after google authentication.

KMS Service: googleapi: Error 403: Permission 'cloudkms.cryptoKeyVersions.useToEncrypt' denied on resource 'projects/PROJECTID/locations/KEYRING/keyRings/KEYNAME/cryptoKeys/**' (or it may not exist)., forbidden

kms.go


import "context"

type KmsConfig struct {
    ProjectID   string `json:"project_id"`
    LocationID  string `json:"location_id"`
    KeyRingID   string `json:"key_ring_id"`
    CryptoKeyID string `json:"crypto_key_id"`
}

type Service interface {
    Encrypt([]byte) ([]byte, error)
    Decrypt([]byte) ([]byte, error)
}

func Init(ctx context.Context, conf *KmsConfig, mock bool) (Service, error) {   
    return initKmsImpl(ctx, conf)
}

service_kms.go


import (
    "context"
    "encoding/base64"
    "errors"
    "fmt"

    "golang.org/x/oauth2/google"
    cloudkms "google.golang.org/api/cloudkms/v1"
)

type kmsImpl struct {
    keyName    string
    kmsService *cloudkms.Service
}

func initKmsImpl(ctx context.Context, c *KmsConfig) (Service, error) {
    var service = new(kmsImpl)
    service.keyName = fmt.Sprintf(
        "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s",
        c.ProjectID, c.LocationID, c.KeyRingID, c.CryptoKeyID)

    // Create an HTTP client with Google oAuth2
    // var ctx = context.Background()
    client, err := google.DefaultClient(ctx, cloudkms.CloudPlatformScope)
    if err != nil {
        return nil, err
    }

    // Initialize the KMS service
    kmsService, err := cloudkms.New(client)
    if err != nil {
        return nil, err
    }
    service.kmsService = kmsService

    // Validate the key and crypto ops are available
    var test = "test"
    encrypted, err := service.Encrypt([]byte(test))
    if err != nil {
        err = fmt.Errorf("KMS Service: %s", err)
        return nil, err
    }

    decrypted, err := service.Decrypt(encrypted)
    if err != nil {
        err = fmt.Errorf("KMS Service: %s", err)
        return nil, err
    }

    if string(decrypted) != test {
        return nil, errors.New("KMS Service: malfunction")
    }

    return service, nil
}

func (k *kmsImpl) Encrypt(in []byte) ([]byte, error) {
    req := &cloudkms.EncryptRequest{
        Plaintext: base64.StdEncoding.EncodeToString(in),
    }

    var fn = k.kmsService.Projects.Locations.KeyRings.CryptoKeys.Encrypt
    var resp, err = fn(k.keyName, req).Do()
    if err != nil {
        return nil, err
    }

    return base64.StdEncoding.DecodeString(resp.Ciphertext)
}

func (k *kmsImpl) Decrypt(in []byte) ([]byte, error) {
    req := &cloudkms.DecryptRequest{
        Ciphertext: base64.StdEncoding.EncodeToString(in),
    }

    var fn = k.kmsService.Projects.Locations.KeyRings.CryptoKeys.Decrypt
    resp, err := fn(k.keyName, req).Do()
    if err != nil {
        return nil, err
    }

    return base64.StdEncoding.DecodeString(resp.Plaintext)
}
user6016913
  • 181
  • 2
  • 10
  • Please share code. Where are you running this? What service account? How are you assigning the service account? Did you auth with the cloud-platform scope? – sethvargo Jan 23 '20 at 15:22
  • @sethvargo, updated the source code in above. – user6016913 Jan 23 '20 at 15:30
  • What are you running this code? Which service account did you grant access? – sethvargo Jan 23 '20 at 17:13
  • Running in local using dev_appserver.py command. This is the service account i was granted the access "SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com" – user6016913 Jan 24 '20 at 05:48
  • Solved the issue after setting .json file in environment variable. Getting another error ````googleapi: Error 400: Decryption failed: the ciphertext is invalid., badRequest```` – user6016913 Jan 24 '20 at 12:15
  • It could be the env flags that needed to be edited? – Anthony Leo Jan 25 '20 at 16:04
  • @sethvargo, getting the same **Error 403 permission ..** after deployment done in gcloud, The same source working fine the LOCAL. – user6016913 Feb 01 '20 at 08:17

0 Answers0