Skip to content

Commit 4720338

Browse files
authored
[AIP-4117] Document executable-sourced credentials. (#896)
1 parent 7070fc3 commit 4720338

1 file changed

Lines changed: 123 additions & 7 deletions

File tree

aip/auth/4117.md

Lines changed: 123 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ The JSON file for AWS configuration files should have the following form:
192192
"environment_id": "aws1",
193193
"region_url": "http://169.254.169.254/latest/meta-data/placement/availability-zone",
194194
"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials",
195-
"regional_cred_verification_url": "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
195+
"regional_cred_verification_url": "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15"
196196
}
197197
}
198198
```
@@ -331,7 +331,7 @@ The auth libraries and applications **must** follow the steps below:
331331
- Parse the file as JSON and then retrieve the external credential from
332332
the field name based on the value of **subject_token_field_name**.
333333

334-
#### Determining the subject token file-sourced credentials
334+
#### Determining the subject token in file-sourced credentials
335335

336336
External account configuration JSON files contain the following information
337337
in the `credential_source` object to facilitate retrieval of file-sourced
@@ -362,11 +362,10 @@ the following form:
362362

363363
The auth libraries and applications **must** follow the steps below:
364364

365-
- Check **credential_source** for the environment ID. If no environment ID,
366-
this should be a file-sourced credential.
365+
- Check **credential_source** has a **file** field and no **environment_id**. If not,
366+
this is not a file-sourced credential and the proceeding steps do not apply.
367367
- Get the external credential from the file location specified by the
368-
`credential_source.file` field. If not available, this should be a
369-
url-sourced credential.
368+
`credential_source.file` field.
370369
- Before parsing the token, check the **format** field.
371370
- If the **format** is not available, assume the external credential is
372371
provided in plain text format.
@@ -375,10 +374,127 @@ The auth libraries and applications **must** follow the steps below:
375374
- Parse the file as JSON and then retrieve the external credential from
376375
the field name based on the value of **subject_token_field_name**.
377376

377+
378+
#### Determining the subject token in executable-sourced credentials
379+
380+
External account configuration JSON files contain the following information
381+
in the `credential_source` object to facilitate retrieval of executable-sourced
382+
credentials to be passed as subject tokens to the GCP STS token exchange
383+
endpoint.
384+
385+
| Field Name | Required | Description |
386+
|---------------------------|----------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
387+
| executable | Yes | Holds the information necessary to run the executable. |
388+
| executable.command | Yes | Specifies the full command to run to retrieve the subject token. This can include arguments. Must be an absolute path for the program. |
389+
| executable.timeout_millis | No | Specifies the timeout duration, in milliseconds. Defaults to 30 seconds when not provided. |
390+
| executable.output_file | No | Specifies the absolute path to the output file where the executable will cache the response. By specifying this path, the auth libraries will first check this location before running the executable. The format of the file should match the JSON format expected by the auth libraries defined below. |
391+
392+
The JSON file for executable-sourced configuration files (OIDC / SAML) should have
393+
the following form:
394+
395+
```json
396+
{
397+
"type": "external_account",
398+
"audience": "//iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID",
399+
"subject_token_type": "urn:ietf:params:oauth:token-type:saml2",
400+
"token_url": "https://sts.googleapis.com/v1/token",
401+
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$EMAIL@project.iam.gserviceaccount.com:generateAccessToken",
402+
"credential_source": {
403+
"executable": {
404+
"command": "/path/to/executable --arg1=value1 --arg2=value2",
405+
"timeout_millis": 5000,
406+
"output_file": "/path/to/cached/credentials"
407+
}
408+
}
409+
}
410+
```
411+
412+
To use executable-sourced credentials, the `GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES` environment variable must be set to `1`.
413+
414+
Additionally, the executable **must** adhere to the following response format:
415+
416+
Successful responses:
417+
418+
| Field Name | Type | Description |
419+
|---------------------------|---------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
420+
| version | number | The version of the JSON output. Currently only version 1 is supported. |
421+
| success | boolean | The status of the response. True in this case. |
422+
| token_type | string | The 3rd party subject token type. Must be *urn:ietf:params:oauth:token-type:jwt*, *urn:ietf:params:oauth:token-type:id_token*, or *urn:ietf:params:oauth:token-type:saml2*. |
423+
| id_token OR saml_response | string | The 3rd party OIDC token or SAML response. |
424+
| expiration_time | number | The 3rd party subject token expiration time in seconds (unix epoch time). |
425+
426+
A sample successful executable OIDC response:
427+
```json
428+
{
429+
"version": 1,
430+
"success": true,
431+
"token_type": "urn:ietf:params:oauth:token-type:id_token",
432+
"id_token": "...",
433+
"expiration_time": 1620499962
434+
}
435+
```
436+
437+
A sample successful executable SAML response:
438+
```json
439+
{
440+
"version": 1,
441+
"success": true,
442+
"token_type": "urn:ietf:params:oauth:token-type:saml2",
443+
"saml_response": "...",
444+
"expiration_time": 1620499962
445+
}
446+
```
447+
448+
Error responses:
449+
450+
| Field Name | Type | Description |
451+
|------------|---------|:-----------------------------------------------------------------------|
452+
| version | number | The version of the JSON output. Currently only version 1 is supported. |
453+
| success | boolean | The status of the response. False in this case. | |
454+
| code | string | The error code. |
455+
| message | string | The error message. |
456+
457+
A sample executable error response:
458+
```json
459+
{
460+
"version": 1,
461+
"success": false,
462+
"code": "401",
463+
"message": "Caller not authorized."
464+
}
465+
```
466+
467+
The auth libraries and applications **must** follow the steps below:
468+
469+
- Check **credential_source** has an **executable** field and no **environment_id**. If not,
470+
this is not a executable-sourced credential and the proceeding steps do not apply.
471+
- Retrieve the external credential's executable information from the
472+
**credential_source.executable** field.
473+
- Check that the `GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES` environment variable is set to **1**. If not, error out.
474+
- Before the next step, check if **credential_source.executable.output_file** was specified in the credential configuration.
475+
- If present, check if there is an executable response at that location.
476+
- If the response is valid and unexpired, or there is no response at that location, continue execution.
477+
- If the response is malformed or invalid, error out.
478+
- Ensure the following environment variables will be available to the executable:
479+
- `GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE`: The audience field from the credential configuration. Must always be present.
480+
- `GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL`: The service account email. Only present when service account impersonation is used.
481+
- `GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE`: The output file location from the credential configuration. Only present when specified in the credential configuration.
482+
- Run the command specified at **credential_source.executable.command**.
483+
- Fail in the following scenarios:
484+
- The executable failed to complete in the timeout duration specified.
485+
- The executable's response is invalid, was unsuccessful or expired.
486+
- The executable finished with a non-zero exit code.
487+
- Parse the executable response as JSON and then retrieve the external credential from
488+
the field name based on the value of **token_type**.
489+
- The token_type value must be **urn:ietf:params:oauth:token-type:jwt**,
490+
**urn:ietf:params:oauth:token-type:id_token**, or **urn:ietf:params:oauth:token-type:saml2**.
491+
- If the **token_type** is **urn:ietf:params:oauth:token-type:saml2**, the subject token will be parsed from the **saml_response** field.
492+
- Otherwise it will be parsed from the **id_token** field.
493+
378494
## Changelog
379495

380496
- **2021-12-10**: Add AIP for External Account Credentials (AIP 4117).
381-
497+
- **2022-05-18**: Document executable-sourced credentials (AIP 4117).
382498

383499
<!-- prettier-ignore-start -->
384500
[0]: https://cloud.google.com/iam/docs/configuring-workload-identity-federation#aws

0 commit comments

Comments
 (0)