From d69a511cc1988bcdc5a06120a9069794c1199229 Mon Sep 17 00:00:00 2001 From: aeitzman Date: Fri, 19 Aug 2022 13:44:15 -0700 Subject: [PATCH 1/6] feat: adding support for configurable token lifespan --- samples/test/externalclient.test.js | 38 +++++++++++++++++++- src/auth/baseexternalclient.ts | 9 +++++ test/externalclienthelper.ts | 4 +++ test/test.baseexternalclient.ts | 54 +++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) diff --git a/samples/test/externalclient.test.js b/samples/test/externalclient.test.js index a9f9023a..6efdc3f3 100644 --- a/samples/test/externalclient.test.js +++ b/samples/test/externalclient.test.js @@ -72,7 +72,11 @@ const {assert} = require('chai'); const {describe, it, before, afterEach} = require('mocha'); const fs = require('fs'); const {promisify} = require('util'); -const {GoogleAuth, DefaultTransporter} = require('google-auth-library'); +const { + GoogleAuth, + DefaultTransporter, + IdentityPoolClient, +} = require('google-auth-library'); const os = require('os'); const path = require('path'); const http = require('http'); @@ -472,4 +476,36 @@ describe('samples for external-account', () => { // Confirm expected script output. assert.match(output, /DNS Info:/); }); + + it('should acquire access token with service account impersonation options', async () => { + // Create file-sourced configuration JSON file. + // The created OIDC token will be used as the subject token and will be + // retrieved from a file location. + const config = { + type: 'external_account', + audience: AUDIENCE_OIDC, + subject_token_type: 'urn:ietf:params:oauth:token-type:jwt', + token_url: 'https://sts.googleapis.com/v1/token', + service_account_impersonation_url: + 'https://iamcredentials.googleapis.com/v1/projects/' + + `-/serviceAccounts/${clientEmail}:generateAccessToken`, + service_account_impersonation: { + token_lifetime_seconds: 2800, + }, + credential_source: { + file: oidcTokenFilePath, + }, + }; + await writeFile(oidcTokenFilePath, oidcToken); + const client = new IdentityPoolClient(config); + + const minExpireTime = new Date().getTime() + (2800 * 1000 - 5 * 1000); + const maxExpireTime = new Date().getTime() + (2800 * 1000 + 5 * 1000); + const token = await client.getAccessToken(); + const actualExpireTime = new Date(token.res.data.expireTime).getTime(); + + assert.isTrue( + minExpireTime <= actualExpireTime && actualExpireTime <= maxExpireTime + ); + }); }); diff --git a/src/auth/baseexternalclient.ts b/src/auth/baseexternalclient.ts index 87442634..920f6065 100644 --- a/src/auth/baseexternalclient.ts +++ b/src/auth/baseexternalclient.ts @@ -41,6 +41,8 @@ const DEFAULT_OAUTH_SCOPE = 'https://www.googleapis.com/auth/cloud-platform'; const GOOGLE_APIS_DOMAIN_PATTERN = '\\.googleapis\\.com$'; /** The variable portion pattern in a Google APIs domain. */ const VARIABLE_PORTION_PATTERN = '[^\\.\\s\\/\\\\]+'; +/** Default impersonated token lifespan in seconds.*/ +const DEFAULT_TOKEN_LIFESPAN = 3600; /** * Offset to take into account network delays and server clock skews. @@ -69,6 +71,9 @@ export interface BaseExternalAccountClientOptions { audience: string; subject_token_type: string; service_account_impersonation_url?: string; + service_account_impersonation?: { + token_lifetime_seconds?: number; + }; token_url: string; token_info_url?: string; client_id?: string; @@ -130,6 +135,7 @@ export abstract class BaseExternalAccountClient extends AuthClient { protected readonly audience: string; protected readonly subjectTokenType: string; private readonly serviceAccountImpersonationUrl?: string; + private readonly serviceAccountImpersonationLifetime?: number; private readonly stsCredential: sts.StsCredentials; private readonly clientAuth?: ClientAuthentication; private readonly workforcePoolUserProject?: string; @@ -203,6 +209,8 @@ export abstract class BaseExternalAccountClient extends AuthClient { } this.serviceAccountImpersonationUrl = options.service_account_impersonation_url; + this.serviceAccountImpersonationLifetime = + options.service_account_impersonation?.token_lifetime_seconds ?? DEFAULT_TOKEN_LIFESPAN; // As threshold could be zero, // eagerRefreshThresholdMillis || EXPIRATION_TIME_OFFSET will override the // zero value. @@ -510,6 +518,7 @@ export abstract class BaseExternalAccountClient extends AuthClient { }, data: { scope: this.getScopesArray(), + lifetime: this.serviceAccountImpersonationLifetime + 's', }, responseType: 'json', }; diff --git a/test/externalclienthelper.ts b/test/externalclienthelper.ts index 9ab9d4d1..0206aefa 100644 --- a/test/externalclienthelper.ts +++ b/test/externalclienthelper.ts @@ -44,8 +44,10 @@ interface NockMockGenerateAccessToken { token: string; response: IamGenerateAccessTokenResponse | CloudRequestError; scopes: string[]; + lifetime?: number; } +const defaultLifetime = 3600; const defaultProjectNumber = '123456'; const poolId = 'POOL_ID'; const providerId = 'PROVIDER_ID'; @@ -86,6 +88,8 @@ export function mockGenerateAccessToken( saPath, { scope: nockMockGenerateAccessToken.scopes, + lifetime: + (nockMockGenerateAccessToken.lifetime ?? defaultLifetime) + 's', }, { reqheaders: { diff --git a/test/test.baseexternalclient.ts b/test/test.baseexternalclient.ts index 72acd595..5d323003 100644 --- a/test/test.baseexternalclient.ts +++ b/test/test.baseexternalclient.ts @@ -1623,6 +1623,60 @@ describe('BaseExternalAccountClient', () => { }); scopes.forEach(scope => scope.done()); }); + + it('should use provided token lifespan', async () => { + const scopes: nock.Scope[] = []; + scopes.push( + mockStsTokenExchange([ + { + statusCode: 200, + response: stsSuccessfulResponse, + request: { + grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange', + audience, + scope: 'https://www.googleapis.com/auth/cloud-platform', + requested_token_type: + 'urn:ietf:params:oauth:token-type:access_token', + subject_token: 'subject_token_0', + subject_token_type: 'urn:ietf:params:oauth:token-type:jwt', + }, + }, + ]) + ); + scopes.push( + mockGenerateAccessToken([ + { + statusCode: 200, + response: saSuccessResponse, + token: stsSuccessfulResponse.access_token, + lifetime: 2800, + scopes: ['https://www.googleapis.com/auth/cloud-platform'], + }, + ]) + ); + + const externalAccountOptionsWithSATokenLifespan = Object.assign( + { + service_account_impersonation: { + token_lifetime_seconds: 2800, + }, + }, + externalAccountOptionsWithSA + ); + + const client = new TestExternalAccountClient( + externalAccountOptionsWithSATokenLifespan + ); + const actualResponse = await client.getAccessToken(); + + // Confirm raw GaxiosResponse appended to response. + assertGaxiosResponsePresent(actualResponse); + delete actualResponse.res; + assert.deepStrictEqual(actualResponse, { + token: saSuccessResponse.accessToken, + }); + scopes.forEach(scope => scope.done()); + }); }); }); From 86a922e0c81ce7770b1d28b77e762617f42f226b Mon Sep 17 00:00:00 2001 From: aeitzman Date: Mon, 22 Aug 2022 11:39:00 -0700 Subject: [PATCH 2/6] fix: fixing lint error and adding documentation --- .readme-partials.yaml | 31 ++++++++++++++++++++++++++++--- src/auth/baseexternalclient.ts | 3 ++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/.readme-partials.yaml b/.readme-partials.yaml index 5c995155..f86f8cc4 100644 --- a/.readme-partials.yaml +++ b/.readme-partials.yaml @@ -351,6 +351,8 @@ body: |- projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AWS_PROVIDER_ID \ --service-account $SERVICE_ACCOUNT_EMAIL \ --aws \ + # Optional argument for specifying the duration of the service account access token. + # --service-account-token-lifetime-seconds $TOKEN_LIFETIME \ --output-file /path/to/generated/config.json ``` @@ -359,9 +361,12 @@ body: |- - `$POOL_ID`: The workload identity pool ID. - `$AWS_PROVIDER_ID`: The AWS provider ID. - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - + - `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. + This will generate the configuration file in the specified output file. + The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. + If you want to use the AWS IMDSv2 flow, you can add the field below to the credential_source in your AWS ADC configuration file: "imdsv2_session_token_url": "http://169.254.169.254/latest/api/token" The gcloud create-cred-config command will be updated to support this soon. @@ -390,6 +395,8 @@ body: |- projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AZURE_PROVIDER_ID \ --service-account $SERVICE_ACCOUNT_EMAIL \ --azure \ + # Optional argument for specifying the duration of the service account access token. + # --service-account-token-lifetime-seconds $TOKEN_LIFETIME \ --output-file /path/to/generated/config.json ``` @@ -398,9 +405,12 @@ body: |- - `$POOL_ID`: The workload identity pool ID. - `$AZURE_PROVIDER_ID`: The Azure provider ID. - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - + - `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. + This will generate the configuration file in the specified output file. + The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. + You can now [start using the Auth library](#using-external-identities) to call Google Cloud resources from Azure. ### Accessing resources from an OIDC identity provider @@ -435,6 +445,8 @@ body: |- # Optional argument for the field that contains the OIDC credential. # This is required for json. # --credential-source-field-name "id_token" \ + # Optional argument for specifying the duration of the service account access token. + # --service-account-token-lifetime-seconds $TOKEN_LIFETIME \ --output-file /path/to/generated/config.json ``` @@ -444,9 +456,12 @@ body: |- - `$OIDC_PROVIDER_ID`: The OIDC provider ID. - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - `$PATH_TO_OIDC_ID_TOKEN`: The file path where the OIDC token will be retrieved from. - + - `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. + This will generate the configuration file in the specified output file. + The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. + **URL-sourced credentials** For URL-sourced credentials, a local server needs to host a GET endpoint to return the OIDC token. The response can be in plain text or JSON. Additional required request headers can also be specified. @@ -465,6 +480,8 @@ body: |- # Optional argument for the field that contains the OIDC credential. # This is required for json. # --credential-source-field-name "id_token" \ + # Optional argument for specifying the duration of the service account access token. + # --service-account-token-lifetime-seconds $TOKEN_LIFETIME \ --output-file /path/to/generated/config.json ``` @@ -475,6 +492,9 @@ body: |- - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - `$URL_TO_GET_OIDC_TOKEN`: The URL of the local server endpoint to call to retrieve the OIDC token. - `$HEADER_KEY` and `$HEADER_VALUE`: The additional header key/value pairs to pass along the GET request to `$URL_TO_GET_OIDC_TOKEN`, e.g. `Metadata-Flavor=Google`. + - `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. + + The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. #### Using Executable-sourced credentials with OIDC and SAML @@ -502,6 +522,8 @@ body: |- # Optional argument for the absolute path to the executable output file. # See below on how this argument impacts the library behaviour. # --executable-output-file=$EXECUTABLE_OUTPUT_FILE \ + # Optional argument for specifying the duration of the service account access token. + # --service-account-token-lifetime-seconds $TOKEN_LIFETIME \ --output-file /path/to/generated/config.json ``` Where the following variables need to be substituted: @@ -511,6 +533,7 @@ body: |- - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - `$SUBJECT_TOKEN_TYPE`: The subject token type. - `$EXECUTABLE_COMMAND`: The full command to run, including arguments. Must be an absolute path to the program. + - `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. The `--executable-timeout-millis` flag is optional. This is the duration for which the auth library will wait for the executable to finish, in milliseconds. @@ -527,6 +550,8 @@ body: |- this location. The format of contents in the file should match the JSON format expected by the executable shown below. + The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. + To retrieve the 3rd party token, the library will call the executable using the command specified. The executable's output must adhere to the response format specified below. It must output the response to stdout. diff --git a/src/auth/baseexternalclient.ts b/src/auth/baseexternalclient.ts index 920f6065..db108566 100644 --- a/src/auth/baseexternalclient.ts +++ b/src/auth/baseexternalclient.ts @@ -210,7 +210,8 @@ export abstract class BaseExternalAccountClient extends AuthClient { this.serviceAccountImpersonationUrl = options.service_account_impersonation_url; this.serviceAccountImpersonationLifetime = - options.service_account_impersonation?.token_lifetime_seconds ?? DEFAULT_TOKEN_LIFESPAN; + options.service_account_impersonation?.token_lifetime_seconds ?? + DEFAULT_TOKEN_LIFESPAN; // As threshold could be zero, // eagerRefreshThresholdMillis || EXPIRATION_TIME_OFFSET will override the // zero value. From 81bb6f5cb46370d59fb3ebc9d3b39c90ab9f925c Mon Sep 17 00:00:00 2001 From: aeitzman Date: Mon, 22 Aug 2022 16:26:53 -0700 Subject: [PATCH 3/6] fix: changing readme --- .readme-partials.yaml | 55 +++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/.readme-partials.yaml b/.readme-partials.yaml index f86f8cc4..89f7c0ac 100644 --- a/.readme-partials.yaml +++ b/.readme-partials.yaml @@ -351,8 +351,6 @@ body: |- projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AWS_PROVIDER_ID \ --service-account $SERVICE_ACCOUNT_EMAIL \ --aws \ - # Optional argument for specifying the duration of the service account access token. - # --service-account-token-lifetime-seconds $TOKEN_LIFETIME \ --output-file /path/to/generated/config.json ``` @@ -361,12 +359,9 @@ body: |- - `$POOL_ID`: The workload identity pool ID. - `$AWS_PROVIDER_ID`: The AWS provider ID. - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - - `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. This will generate the configuration file in the specified output file. - The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. - If you want to use the AWS IMDSv2 flow, you can add the field below to the credential_source in your AWS ADC configuration file: "imdsv2_session_token_url": "http://169.254.169.254/latest/api/token" The gcloud create-cred-config command will be updated to support this soon. @@ -395,8 +390,6 @@ body: |- projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AZURE_PROVIDER_ID \ --service-account $SERVICE_ACCOUNT_EMAIL \ --azure \ - # Optional argument for specifying the duration of the service account access token. - # --service-account-token-lifetime-seconds $TOKEN_LIFETIME \ --output-file /path/to/generated/config.json ``` @@ -405,12 +398,9 @@ body: |- - `$POOL_ID`: The workload identity pool ID. - `$AZURE_PROVIDER_ID`: The Azure provider ID. - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - - `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. This will generate the configuration file in the specified output file. - The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. - You can now [start using the Auth library](#using-external-identities) to call Google Cloud resources from Azure. ### Accessing resources from an OIDC identity provider @@ -445,8 +435,6 @@ body: |- # Optional argument for the field that contains the OIDC credential. # This is required for json. # --credential-source-field-name "id_token" \ - # Optional argument for specifying the duration of the service account access token. - # --service-account-token-lifetime-seconds $TOKEN_LIFETIME \ --output-file /path/to/generated/config.json ``` @@ -456,12 +444,9 @@ body: |- - `$OIDC_PROVIDER_ID`: The OIDC provider ID. - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - `$PATH_TO_OIDC_ID_TOKEN`: The file path where the OIDC token will be retrieved from. - - `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. This will generate the configuration file in the specified output file. - The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. - **URL-sourced credentials** For URL-sourced credentials, a local server needs to host a GET endpoint to return the OIDC token. The response can be in plain text or JSON. Additional required request headers can also be specified. @@ -480,8 +465,6 @@ body: |- # Optional argument for the field that contains the OIDC credential. # This is required for json. # --credential-source-field-name "id_token" \ - # Optional argument for specifying the duration of the service account access token. - # --service-account-token-lifetime-seconds $TOKEN_LIFETIME \ --output-file /path/to/generated/config.json ``` @@ -492,10 +475,7 @@ body: |- - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - `$URL_TO_GET_OIDC_TOKEN`: The URL of the local server endpoint to call to retrieve the OIDC token. - `$HEADER_KEY` and `$HEADER_VALUE`: The additional header key/value pairs to pass along the GET request to `$URL_TO_GET_OIDC_TOKEN`, e.g. `Metadata-Flavor=Google`. - - `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. - - The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. - + #### Using Executable-sourced credentials with OIDC and SAML **Executable-sourced credentials** @@ -522,8 +502,6 @@ body: |- # Optional argument for the absolute path to the executable output file. # See below on how this argument impacts the library behaviour. # --executable-output-file=$EXECUTABLE_OUTPUT_FILE \ - # Optional argument for specifying the duration of the service account access token. - # --service-account-token-lifetime-seconds $TOKEN_LIFETIME \ --output-file /path/to/generated/config.json ``` Where the following variables need to be substituted: @@ -533,7 +511,6 @@ body: |- - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - `$SUBJECT_TOKEN_TYPE`: The subject token type. - `$EXECUTABLE_COMMAND`: The full command to run, including arguments. Must be an absolute path to the program. - - `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. The `--executable-timeout-millis` flag is optional. This is the duration for which the auth library will wait for the executable to finish, in milliseconds. @@ -550,8 +527,6 @@ body: |- this location. The format of contents in the file should match the JSON format expected by the executable shown below. - The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. - To retrieve the 3rd party token, the library will call the executable using the command specified. The executable's output must adhere to the response format specified below. It must output the response to stdout. @@ -632,6 +607,34 @@ body: |- You can now [use the Auth library](#using-external-identities) to call Google Cloud resources from an OIDC or SAML provider. + #### Configurable Token Lifetime + When creating a credential configuration with workload identity federation using service account impersonation, you can provide an optional argument to configure the access token lifetime. + + To generate the configuration with configurable token lifetime, run the following command (This example uses an AWS configuration, but the token lifetime can be configured for all workload identity federation providers): + + ```bash + # Generate an AWS configuration file with configurable token lifetime. + gcloud iam workload-identity-pools create-cred-config \ + projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AWS_PROVIDER_ID \ + --service-account $SERVICE_ACCOUNT_EMAIL \ + --aws \ + --output-file /path/to/generated/config.json \ + --service-account-token-lifetime-seconds $TOKEN_LIFETIME + ``` + + Where the following variables need to be substituted: + - `$PROJECT_NUMBER`: The Google Cloud project number. + - `$POOL_ID`: The workload identity pool ID. + - `$AWS_PROVIDER_ID`: The AWS provider ID. + - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. + - `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. + + The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. + The minimum allowed value is 600 (10 minutes) and the maximum allowed value is 43200 (12 hours). + If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. + Note that configuring a short lifetime (e.g. 10 minutes) will result in the library initiating the entire token exchange flow every 10 minutes, which will call the 3rd party token provider even if the 3rd party token is not expired. + + ### Using External Identities External identities (AWS, Azure and OIDC-based providers) can be used with `Application Default Credentials`. From 0ca99aa2962c49faee09853c56ec00c336b7930e Mon Sep 17 00:00:00 2001 From: aeitzman Date: Mon, 22 Aug 2022 16:28:51 -0700 Subject: [PATCH 4/6] fix: removing unintentional whitespace --- .readme-partials.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.readme-partials.yaml b/.readme-partials.yaml index 89f7c0ac..66b7633f 100644 --- a/.readme-partials.yaml +++ b/.readme-partials.yaml @@ -359,7 +359,7 @@ body: |- - `$POOL_ID`: The workload identity pool ID. - `$AWS_PROVIDER_ID`: The AWS provider ID. - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - + This will generate the configuration file in the specified output file. If you want to use the AWS IMDSv2 flow, you can add the field below to the credential_source in your AWS ADC configuration file: @@ -398,7 +398,7 @@ body: |- - `$POOL_ID`: The workload identity pool ID. - `$AZURE_PROVIDER_ID`: The Azure provider ID. - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - + This will generate the configuration file in the specified output file. You can now [start using the Auth library](#using-external-identities) to call Google Cloud resources from Azure. @@ -444,7 +444,7 @@ body: |- - `$OIDC_PROVIDER_ID`: The OIDC provider ID. - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - `$PATH_TO_OIDC_ID_TOKEN`: The file path where the OIDC token will be retrieved from. - + This will generate the configuration file in the specified output file. **URL-sourced credentials** @@ -475,7 +475,7 @@ body: |- - `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. - `$URL_TO_GET_OIDC_TOKEN`: The URL of the local server endpoint to call to retrieve the OIDC token. - `$HEADER_KEY` and `$HEADER_VALUE`: The additional header key/value pairs to pass along the GET request to `$URL_TO_GET_OIDC_TOKEN`, e.g. `Metadata-Flavor=Google`. - + #### Using Executable-sourced credentials with OIDC and SAML **Executable-sourced credentials** From 335219f2e91734757644046555a1645eba94b690 Mon Sep 17 00:00:00 2001 From: aeitzman Date: Tue, 23 Aug 2022 11:57:14 -0700 Subject: [PATCH 5/6] fix: minor readme edits --- .readme-partials.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.readme-partials.yaml b/.readme-partials.yaml index 66b7633f..1ca51c7d 100644 --- a/.readme-partials.yaml +++ b/.readme-partials.yaml @@ -608,9 +608,9 @@ body: |- resources from an OIDC or SAML provider. #### Configurable Token Lifetime - When creating a credential configuration with workload identity federation using service account impersonation, you can provide an optional argument to configure the access token lifetime. + When creating a credential configuration with workload identity federation using service account impersonation, you can provide an optional argument to configure the service account access token lifetime. - To generate the configuration with configurable token lifetime, run the following command (This example uses an AWS configuration, but the token lifetime can be configured for all workload identity federation providers): + To generate the configuration with configurable token lifetime, run the following command (this example uses an AWS configuration, but the token lifetime can be configured for all workload identity federation providers): ```bash # Generate an AWS configuration file with configurable token lifetime. @@ -632,9 +632,9 @@ body: |- The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. The minimum allowed value is 600 (10 minutes) and the maximum allowed value is 43200 (12 hours). If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. + Note that configuring a short lifetime (e.g. 10 minutes) will result in the library initiating the entire token exchange flow every 10 minutes, which will call the 3rd party token provider even if the 3rd party token is not expired. - - + ### Using External Identities External identities (AWS, Azure and OIDC-based providers) can be used with `Application Default Credentials`. From da8d59ab088ad615018fe7f6ecfc5659e8ce20db Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Tue, 23 Aug 2022 18:59:32 +0000 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 059bd944..99dc4788 100644 --- a/README.md +++ b/README.md @@ -651,6 +651,34 @@ credentials unless they do not meet your specific requirements. You can now [use the Auth library](#using-external-identities) to call Google Cloud resources from an OIDC or SAML provider. +#### Configurable Token Lifetime +When creating a credential configuration with workload identity federation using service account impersonation, you can provide an optional argument to configure the service account access token lifetime. + +To generate the configuration with configurable token lifetime, run the following command (this example uses an AWS configuration, but the token lifetime can be configured for all workload identity federation providers): + +```bash +# Generate an AWS configuration file with configurable token lifetime. +gcloud iam workload-identity-pools create-cred-config \ + projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AWS_PROVIDER_ID \ + --service-account $SERVICE_ACCOUNT_EMAIL \ + --aws \ + --output-file /path/to/generated/config.json \ + --service-account-token-lifetime-seconds $TOKEN_LIFETIME +``` + + Where the following variables need to be substituted: +- `$PROJECT_NUMBER`: The Google Cloud project number. +- `$POOL_ID`: The workload identity pool ID. +- `$AWS_PROVIDER_ID`: The AWS provider ID. +- `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate. +- `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds. + +The `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour. +The minimum allowed value is 600 (10 minutes) and the maximum allowed value is 43200 (12 hours). +If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint. + +Note that configuring a short lifetime (e.g. 10 minutes) will result in the library initiating the entire token exchange flow every 10 minutes, which will call the 3rd party token provider even if the 3rd party token is not expired. + ### Using External Identities External identities (AWS, Azure and OIDC-based providers) can be used with `Application Default Credentials`.