node.jsgoogle-cloud-platformgoogle-secret-manager

Secret manager access denied despite correct roles for service account


I'm writing a cloud function in Nodejs (10), and trying to access a secret like so:

const [secret] = await new SecretManagerServiceClient().accessSecretVersion({
    name: `projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/latest`
})

I created the secret in the web console and the name used in code matches that of the existing secret. On the page for the cloud function details, it states that the service account is PROJECT_ID@appspot.gserviceaccount,com, so I added the secretmanager.secretAccessor role to it. However, I'm still getting the same error every time:

Error: 7 PERMISSION_DENIED: Permission 'secretmanager.versions.access' denied for resource 'projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/latest' (or it may not exist).

It makes no difference if I specify a concrete version or just use latest.


Solution

  • HTTP cloud function code:

    const { SecretManagerServiceClient } = require('@google-cloud/secret-manager');
    
    const secretManagerServiceClient = new SecretManagerServiceClient();
    const name = 'projects/shadowsocks-218808/secrets/workflow/versions/latest';
    
    exports.testSecretManager = async (req, res) => {
      const [version] = await secretManagerServiceClient.accessSecretVersion({ name });
      const payload = version.payload.data.toString();
      console.debug(`Payload: ${payload}`);
      res.sendStatus(200);
    };
    

    Deploy:

    gcloud functions deploy testSecretManager --runtime nodejs10 --trigger-http --allow-unauthenticated
    
    Deploying function (may take a while - up to 2 minutes)...done.                                                                                                                                                                                                                        
    availableMemoryMb: 256
    entryPoint: testSecretManager
    httpsTrigger:
      url: https://us-central1-shadowsocks-218808.cloudfunctions.net/testSecretManager
    ingressSettings: ALLOW_ALL
    labels:
      deployment-tool: cli-gcloud
    name: projects/shadowsocks-218808/locations/us-central1/functions/testSecretManager
    runtime: nodejs10
    serviceAccountEmail: shadowsocks-218808@appspot.gserviceaccount.com
    sourceUploadUrl: https://storage.googleapis.com/gcf-upload-us-central1-43476143-b555-4cb2-8f6f-1b2d1952a2d7/42c4cda4-98a8-4994-a3be-d2203b9e646a.zip?GoogleAccessId=service-16536262744@gcf-admin-robot.iam.gserviceaccount.com&Expires=1596513795&Signature=kbLw5teN8EoYmj4fEweKKiIaakxcrhlUg2GGHV4jWJjvmeEfXePpRNOn9yz2zLn%2Fba0UqM9qdJMXujs5afBk%2BVBmywPEiptAZe2qgmldpr%2BsYejFu0woNgsPHVqtJ0NoWDo6W2dq4CuNNwO%2BaQ89mnhahUUQTInkJ55Y3wCIe9smk%2BqWtcvta3zICiToA7RQvPKY5MS6NViyj5mLxuJtDlTY9IKPL%2BqG6JAaQJSFYKYVgLyb6JfirXk8Q7%2FMvnHPpXPlhvsBLQksbF6jDPeefp2HyW4%2FSIQYprfpwKV3hlEIQyRQllz5J9yF83%2FxDPh%2BQPc5QmswKP5XAvYaszJPEw%3D%3D
    status: ACTIVE
    timeout: 60s
    updateTime: '2020-08-04T03:34:32.665Z'
    versionId: '2'
    

    Test:

    gcloud functions call testSecretManager --data '{}'
    

    Got error same as you:

    error: |-
      Error: function terminated. Recommended action: inspect logs for termination reason. Details:
      7 PERMISSION_DENIED: Permission 'secretmanager.versions.access' denied for resource 'projects/shadowsocks-218808/secrets/workflow/versions/latest' (or it may not exist).
    

    solution:

    You can find the serviceAccountEmail: shadowsocks-218808@appspot.gserviceaccount.com from the deployment information details of cloud function.

    go to IAM & Admin web UI, click ADD ANOTHER ROLE button, add Secret Manager Secret Accessor role to this service account.

    enter image description here

    Test again:

    > gcloud functions call testSecretManager --data '{}'
    
    executionId: 1tsatxl6fndw
    result: OK
    

    Read the logs for testSecretManager cloud function:

    gcloud functions logs read testSecretManager
    

    You will see the logs for the secret payload string.