This is an example how to use an Azure Service Principal identity to access Google Cloud resources using Workload Identity Federation. Google documentation on workload identity federation from Azure can be found at https://cloud.google.com/iam/docs/workload-identity-federation-with-other-clouds#azure and Azure documentation on service principals can be found at https://learn.microsoft.com/en-au/entra/identity-platform/howto-create-service-principal-portal#register-an-application-with-azure-ad-and-create-a-service-principal
import * as aws from '@pulumi/aws'; | |
import { all, output, secret } from '@pulumi/pulumi'; | |
const serviceAccount = output('[email protected]'); | |
const audience = output('*****'); | |
const awsRoleArn = output('arn:aws:iam::999999999999:role/pulumi-aws-federation'); | |
const token = secret( | |
all([serviceAccount, audience]).apply(async ([serviceAccount, audience]) => { | |
const client = await auth.getClient(); |
Some identity providers support OAuth client authentication using the private_key_jwt
authentication method. This means you invoke the oauth token endpoint with a JWT that is signed using a private key and a client_assertion_type
set to urn:ietf:params:oauth:client-assertion-type:jwt-bearer
. They identity provider than validates the token using the public key and issues an access token.
In the setup at the identity provider you have to create an OAuth client, set it up to use private_key_jwt
as the authentication method and supply a URL to the JWKS (JSON Web Key Set) that contain the public key(s). This makes this flow very easy to implement with a Google service account since Google publicly hosts the JWKS for each service account at https://www.googleapis.com/service_accounts/v1/jwk/SERVICE_ACCOUNT_EMAIL
. Having the identity provider fetch the JWKS from a public endpoint adds security as it allows for frequent service account key rotation at the side of Google without the need to reconfiger the i
/** | |
* Damm algorithm is a check digit algorithm that detects all single-digit errors and all adjacent transposition errors | |
* https://en.wikipedia.org/wiki/Damm_algorithm | |
* | |
* Live typescript playground at: https://www.typescriptlang.org/play?ssl=33&ssc=1&pln=1&pc=1#code/PQKhCgAIUgRBDAtoy8A2BzA9gJwJYAuAFingM6qQDGRAplQNaQAmeGhqmuhJkx8BFrQL0CFdGkhk8AOwxpaAWlbtBtHDlziZzTpPjMAVvCq0ZggjngyyAByzSCeLDMjrNOMlBhECBW2QAXMDAZgB0AO54DHi2tKzwYbgYwFExwAjIAPro2PjEiN7A4FQuZIJYcVZOLgAq8ABGCpAAvJAA2lCQ3e0ADAA0kADMgwCMgwDsgwCsgwCcgwAcgwBsgwAsgwBMALr9XT1TkAOQC5BbYzMbS6uDQ3sHHZvngydrkMuQR+PDV6cP3R6PyOs2O8xuv0gzwukBWAMB7XePxhIzBUL+ZyOi3hPVR7yO0Ne4MgoM+oxxHVJt1Ok22RMgP1R6wp7U+Z2eoLxdLRwJZ7LuEKRtJeaOmLJhVIZ10h+OJvQeOwA3OBwKAINBIAA1dB4ZgCWiUdgANzMkBkAFdEA11JBzdI5JBCAByCiwACCAFkPdQ6IwWGxCGFvJAAAI4YTmnA2Pg4c0GvAAMzNlutOEdFCNOuYgwT6DIBqwxHUUXzQegxQT5pkVBqrhN+ATAE9MogAMK+hiwAMEAAUsls5oIgSkllkGAAlJAAN6PcMESOuHuPQGQYAAPQAOswp0MAL4bsJbnf7w-b0a7gAkwDCInKfZkA4Ik4AZM-l4D+4P3yvumFw7Y0BMWge2AA9gAwQYnSdcdvx-MI7DQQgeygmCfzQyA-3ic1TB7HtNAiQYVEIS |
In a multi-cloud environment it is wise to use federated identities between different cloud environments. This removes the need to issue, manage, and rotate secrets. With federated identities a party running on (for example) Google Cloud can use the identity they already have within Google Cloud (attached to their VM or Cloud Function) to assume a federated AWS identity and then use that AWS identity to invoke API's from the other party. This could not only be custom API's (like API gateway), but since you fully impersonate an AWS identity (aka AWS Role) they could also invoke AWS own API's like S3.
Over time I've collected numerous samples of federation between different cloud providers. This is list of all of them:
Configure OIDC based Workload Identity Federation at Google Cloud (see https://cloud.google.com/iam/docs/configuring-workload-identity-federation). When configuring the identity provider use the following information:
- Set the
issuerURI
tohttps://[TENANT].eu.auth0.com/
, so google can retrieve thehttps://my-tenant.eu.auth0.com/.well-known/openid-configuration
configuration file with the public key information - Set the
attributeCondition
toassertion.gty=='client-credentials' && assertion.azp=='[CLIENT-ID]'
However, at this stage
inspired by https://github.com/shrikant0013/gcp-aws-webidentityfederation
- create an AWS Role configured for Web Identity federation using Cognito or any OpenID provider
- select Google as the Identity provider in the wizard
- set the audience to a dummy value and do not add any additional conditions in the setup wizard. We will edit the trust policy after completing the wizard.
- assign any permissions needed to the role
- read up on "Available keys for AWS web identity federation" at
Important: When using customer-supplied encryption keys, it is up to you to generate and manage your encryption keys. You must provide Compute Engine a key that is a 256-bit string encoded in RFC 4648 standard base64. For this lab, you will just generate a key with a random number.
- On the Google Cloud Platform menu, click Activate Cloud Shell to open Cloud Shell. If prompted, click Continue.
- Enter the following single command in Cloud Shell to create a 256 bit (32 byte) random number to use as a key:
openssl rand 32 > mykey.txt
- View the mykey.txt to verify the key was created:
// This example is part of a [larger serie of posts](https://gist.github.com/wvanderdeijl/734cc05dd2438a9946c396d714d5e83e) with | |
// examples of federation between different cloud environments. | |
import { Sha256 } from '@aws-crypto/sha256-universal'; // or @aws-crypto/sha256-js | |
import { AssumeRoleCommand, STSClient } from '@aws-sdk/client-sts'; | |
import { SignatureV4 } from '@aws-sdk/signature-v4'; | |
import axios from 'axios'; | |
const AWS_REGION = 'eu-west-1'; | |
const AWS_ROLE_ARN = 'arn:aws:iam::999999999999:role/my-federated-role'; |