or...how to use ADC and run your own STS token broker
An STS server will exchange one token for another. This protocol is used by GCP Workload Federation.
THis example runs your own STS server with GCP where the STS server accepts a source token, validates it and the returns a gcp access_token
For more information about STS servers, see
- Serverless Security Token Exchange Server(STS) and gRPC STS credentials
- Security Token Service (STS) Credentials for HTTP and gRPC (rfc8693)
- External Account Credentials (https://google.aip.dev/auth/4117)
- Certificate Bound Tokens using Security Token Exchange Server (STS)
- Envoy WASM and LUA filters for Certificate Bound Tokens
If you just want to see a quick sample, use the STS Server running at https://stsserver-3kdezruzua-uc.a.run.app/token
.
All this STS server does is returns iamthewalrus
if the provided token is iamtheeggman
, thats is
cat <<EOF >> /tmp/sts-req.json
{
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
"resource": "//storage.googleapis.com/projects/_/buckets/bucket_name",
"audience": "//iam.googleapis.com/projects/995081019036/locations/global/workloadIdentityPools/fake-oidc-pool-1/providers/fake-oidc-provider-1",
"requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
"subject_token": "iamtheeggman",
"subject_token_type": "urn:ietf:params:oauth:token-type:access_token"
}
EOF
curl -s -H "Content-Type: application/json" -d @/tmp/sts-req.json https://stsserver-3kdezruzua-uc.a.run.app/token
| jq '.'
{
"access_token": "iamthewalrus",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"token_type": "Bearer",
"expires_in": 60
}
then for GCP:
echo -n iamtheeggman > /tmp/creds.txt
cat <<EOF >> /tmp/sts-creds-file.json
{
"universe_domain": "googleapis.com",
"type": "external_account",
"audience": "//iam.googleapis.com/projects/995081019036/locations/global/workloadIdentityPools/fake-oidc-pool-1/providers/fake-oidc-provider-1",
"subject_token_type": "urn:ietf:params:oauth:token-type:access_token",
"token_url": "https://stsserver-3kdezruzua-uc.a.run.app/token",
"credential_source": {
"file": "/tmp/creds.txt",
"format": {
"type": "text"
}
},
"token_info_url": "https://sts.googleapis.com/v1/introspect"
}
EOF
export GOOGLE_APPLICATION_CREDENTIALS=/tmp//sts-creds-file.json
export GOOGLE_CLOUD_PROJECT=your-project-id
$ gcloud auth application-default print-access-token
iamthewalrus
One application maybe to use the kubernetes service account token and exchange that for a GCP credentials. The STS server would run as a kubernetes Service, validate the token provided by the client using its TokenReview API, the return the actual service account.
eg.
- each client pod's workload federation read its own
/var/run/secrets/kubernetes.io/serviceaccount/token
- sends that token over the STS server (which may run as another kubernetes service)
- sts server uses the tokenreview api to validate the token
- sts server mints an
access_token
that is appropriate for that client kubernetes pod - retruns
access_token
to the pod - pod uses that to access gcp
Ofcourse if you're using kuberentes, you're better off using other mechanisms than an STS server:
- OIDC Federation Using Kubernetes Service Accounts for Google Workload Identity Federation
- MTLS Federation GCP Workload Federation using Kubernetes SPIFFE mTLS
- Metadata Serivce Istio Kubernetes GCE Metadata Proxy