1

I'm trying to give a given GCE instance the permission to get one specific secret stored inside the secret manager. Not the WHOLE set of secrets, just one.

So, I added this binding in my terraform code for the service account which in turn is used inside my GCE:

resource "google_secret_manager_secret_iam_binding" "secret_iam_binding" {
  project   = <my project>
  # I also used google_secret_manager_secret.<my secret>.secret_id here, but nothing changed     
  secret_id = google_secret_manager_secret.<my secret>.name
  role      = "roles/secretmanager.secretAccessor"
  members   = [
    "serviceAccount:${<the service account used by the GCE instance>.email}"
  ]
}

This is the relevant code into the GCE creation terraform block: the scope should be enough I guess...

service_account {
    email = <the service account used by the GCE instance>.email
    scopes = ["cloud-platform"]
  }

Then, i ssh into the GCE node and tried to make some checks (since i have Container OS there, i had to use curl for testing)

  • Check if GCE is using the right service account: OK
curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email" -H "Metadata-Flavor: Google"
  • Getting a valid token: OK (well, I assume so)
TOKEN=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google" | jq -r .access_token)
  • Getting the secret value: KO
curl -s "https://secretmanager.googleapis.com/v1/projects/<my project id>/secrets/<my secret name>/versions/latest" -H "Authorization: Bearer $TOKEN" | jq -r .payload.data | base64 -d

with this error:

{
  "error": {
    "code": 403,
    "message": "Permission 'secretmanager.versions.get' denied for resource 'projects/<my project id>/secrets/<my secret name>/versions/latest' (or it may not exist).",
    "status": "PERMISSION_DENIED"
  }
}

thus, I guess I'm not granting enough roles to the service account....but I've no clue on which one I'm missing...

EDIT: outside the GCE node, I tried this command:

gcloud secrets get-iam-policy <my secret id> --project <my project id>

and the output is the expected:

bindings:
- members:
  - serviceAccount:<my service account name>>@<my project id>.iam.gserviceaccount.com
  role: roles/secretmanager.secretAccessor
etag: BwX8DrYyZtw=
version: 1
Gabriele B
  • 2,665
  • 1
  • 25
  • 40
  • 1
    Check the VM's Access Scopes in the web console GUI. It must be set to cloud platform all APIs. https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances#changeserviceaccountandscopes – John Hanley May 19 '23 at 16:53
  • 1
    @JohnHanley tnx, I did...all API's are granted – Gabriele B May 19 '23 at 17:05
  • 1
    The error is `secretmanager.versions.get`. The IAM role `roles/secretmanager.secretAccessor` does not have that permission [link](https://cloud.google.com/secret-manager/docs/access-control). – John Hanley May 19 '23 at 21:27
  • 1
    Verify that `` is a valid Secret ID. – John Hanley May 19 '23 at 21:31
  • 1
    double checked that...but maybe i've an idea still to check (i'm going to provide an answer if it will solve the issue). Tnx in the meantime for your support! – Gabriele B May 19 '23 at 22:54

1 Answers1

0

It went out that the endpoint I was using to get the payload was incomplete. In facts, the structure was totally wrong:

curl -s "https://secretmanager.googleapis.com/v1/projects/<my project id>/secrets/<my secret name>/versions/latest:access" -H "Authorization: Bearer $TOKEN" | jq -r .payload.data | base64 -d

In other words, I was missing the ":access" trail.

Gabriele B
  • 2,665
  • 1
  • 25
  • 40