GCP service account identity tokens for workload federation and svc account json #4736
salrashid123
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
While updating docs for gcp based signing in sigstore/docs#416, i noticed that plain service account JSON and and GCP workload federation JSON files are not supported.
I'm not submitting a pull request related to that because i suspect its very rare usecase. In the event this does come up, the snippet below shows the changes i used to make it work for the various credential types on gcp
Basically, GCP credentials can bootstrap from a number of different ways ( metadata server, user auth, impersonation, svcaccount JSON, workload federation JSON).
When using google application defautl credentials, you can "just reference" a JSON file which can within it contain other credentials like
"type": "service_account",<< not really recommended"type": "external_account",<<< this will allow bootstrap from any environment aws,azure, onprem to acquire a gcp creds to cosign"type": "impersonated_service_account",<< really rare and already implicitly supported in cosigncurrently,
cosigndoens't use the JSON file based credentials values to acquire id_tokens. and bit below describes one way to do this.ServiceAccount JSON
Note, this credential reference actually includes the RSA key material...its not recommended to save keys like this but it is one of the types supported
eg:
to use this mode, set the env var to bootstrap off of the credentials and it'll automatically acqurie an id_token
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/svc_account.json $ go run cmd/cosign/main.go sign-blob --bundle /tmp/artifact.sigstore.json /tmp/message.txtthe cert will have the SAN:
X509v3 Subject Alternative Name: critical email:yoursa%40yourproject.iam.gserviceaccount.com 1.3.6.1.4.1.57264.1.1: https://accounts.google.comExternal Account
GCP workload federation configs has an optional step to assume a user's credentials here: https://docs.cloud.google.com/iam/docs/workload-identity-federation#impersonation
for a standalone test example using an oidc provider here:
sts-creds.json{ "type": "external_account", "audience": "//iam.googleapis.com/projects/9950811111/locations/global/workloadIdentityPools/fake-oidc-pool-1/providers/fake-oidc-provider-1", "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", "token_url": "https://sts.googleapis.com/v1/token", "credential_source": { "file": "/tmp/oidccred.txt" }, "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/oidc-federated@yourproject.iam.gserviceaccount.com:generateAccessToken" }then allow the federated creds to impersonate
gcloud iam service-accounts add-iam-policy-binding oidc-federated@core-eso.iam.gserviceaccount.com \ --role roles/iam.serviceAccountTokenCreator \ --member "principal://iam.googleapis.com/projects/995081019036/locations/global/workloadIdentityPools/fake-oidc-pool-1/subject/alice@domain.com"then set the env var and run
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/sts-creds.jsonthe cer'ts SAN is:
Impersonation
While the cosign docs already describes impersonation, this mechanism uses the JSON file based approach:
With the following, your local user credentials is used to impersonate the SA which intrun gets its id_token via IAM APIs.
gcloud auth application-default login $ cat /home/srashid/.config/gcloud/application_default_credentials.json { "account": "", "client_id": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com", "client_secret": "d-FL95Q19q7MQmFpd7hHD0Ty", "quota_project_id": "core-eso", "refresh_token": "--redacted--", "type": "authorized_user", "universe_domain": "googleapis.com" }( opitonally delete the creds
rm /home/srashid/.config/gcloud/application_default_credentials.json)then specify the
impersonated_creds.jsonfile with the values in adc (this represents your user account as the source credentials; thesource_credentailscan also be another service account...)$ cat /path/to/impersonated_creds.json { "type": "impersonated_service_account", "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/yorusvcaccount@your_project.iam.gserviceaccount.com:generateAccessToken", "source_credentials": { "account": "", "client_id": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com", "client_secret": "d-FL95Q19q7MQmFpd7hHD0Ty", "quota_project_id": "your_project", "refresh_token": "redacted", "type": "authorized_user", "universe_domain": "googleapis.com" } }to allow this mechansim, your user needs to impersonate the serrvice account and that service account needs to get its id_token.
(the second level of impersonation is required because the client library right now assumes the active credetnials for the impersonated sa w/o knowing about its actual source. that could be an upstream improvement in google creds...)
to use
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/impersonated_creds.json go run cmd/cosign/main.go sign-blob --bundle /tmp/artifact.sigstore.json /tmp/message.txtthe cert has SAN:
the diff's included here
Beta Was this translation helpful? Give feedback.
All reactions