2
votes

I have a Python Cloud Function which uses a KMS key to decrypt some authentication tokens for other services from the environment, as in https://dev.to/googlecloud/using-secrets-in-google-cloud-functions-5aem

I keep getting a 403 Permission Denied whenever I run my function. When I call the function locally on my computer it works fine. I've tried adding the "Cloud KMS CryptoKey Decrypter" role to the default Compute Engine service account but that didn't work.

Any other ideas?

Edit: here's some code that shows what I'm doing. The environment variables are stored in an environment.yaml file which I point to when I gcloud functions deploy

def decrypt_secret(key: str, secret: str):
    kms_client = kms.KeyManagementServiceClient()
    decrypted = kms_client.decrypt(key, base64.b64decode(secret))
    return decrypted.plaintext.decode("ascii")

def do_kms_stuff():
    key = os.environ["KMS_RESOURCE_NAME"]
    session = boto3.Session(
        profile_name="my-profile",
        aws_access_key_id=decrypt_secret(
            key, os.environ["AWS_ACCESS_KEY_ID_ENCRYPTED"]
        ),
        aws_secret_access_key=decrypt_secret(
            key, os.environ["AWS_SECRET_ACCESS_KEY_ENCRYPTED"]
        ),
    )
    # ...

And here's the error from the Cloud Functions console:

File "<string>", line 3, in raise_from: google.api_core.exceptions.PermissionDenied: 403 Permission 'cloudkms.cryptoKeyVersions.useToDecrypt' denied on resource 'projects/my-project/locations/my-location1/keyRings/my-keyring/cryptoKeys/my-key' (or it may not exist). at error_remapped_callable (/env/local/lib/python3.7/site-packages/google/api_core/grpc_helpers.py:59) at func_with_timeout (/env/local/lib/python3.7/site-packages/google/api_core/timeout.py:214) at retry_target (/env/local/lib/python3.7/site-packages/google/api_core/retry.py:182) at retry_wrapped_func (/env/local/lib/python3.7/site-packages/google/api_core/retry.py:277) at
__call__ (/env/local/lib/python3.7/site-packages/google/api_core/gapic_v1/method.py:143) at decrypt (/env/local/lib/python3.7/site-packages/google/cloud/kms_v1/gapic/key_management_service_client.py:1816) at decrypt_secret (/user_code/kms_stuff.py:17) at do_kms_stuff (/user_code/kms_stuff.py:48) at my_cloud_function (/user_code/main.py:46) at call_user_function (/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py:214) at invoke_user_function (/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py:217) at run_background_function (/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py:383)
1
Please edit the question to show the code that isn't working the way you expect, and what you're doing to invoke it. If you're invoking it using some tool on your computer, be sure that you've enabled public access to the function. - Doug Stevenson
Is this better? - Jon Cohen
is your key exists when you perform a gcloud kms keys list --location <your location> ? - guillaume blaquiere
Two issues: (1) Cloud Functions run under the appspot service account (cloud.google.com/functions/docs/securing/function-identity) not compute engine default; (2) Unless you've intentionally obfuscated, the key location appears incorrect: projects/my-project/locations/my-location1/keyRings/my-keyring/cryptoKeys/my-key - DazWilkin
I have obfuscated, but I don't see the difference between your key and my key. Anyways, I don't think that's the issue as it works when I run the function on my dev machine. I think using the appspot service account will make the difference - Jon Cohen

1 Answers

2
votes

As @DazWilkin and @pessolato mentioned, the issue was that I was using the wrong service account. Once I changed to use the default AppSpot account everything worked smoothly.