Skip to content

Commit 363aa43

Browse files
authored
Add AIPs describing workload credentials and mTLS token binding flows (#945)
1 parent 8dfa9e0 commit 363aa43

3 files changed

Lines changed: 322 additions & 7 deletions

File tree

aip/auth/4110.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ For example, the `GOOGLE_APPLICATION_CREDENTIALS` environment variable can provi
8888
the default credential JSON as the input here, or the well-known path that
8989
gCloud uses to store the default user credential JSON. The output is the access
9090
token that application can use to access the Google APIs. This access token
91-
__may__ be a bearer token or a certificate bound token depending on the
92-
chosen authentication flow.
91+
__may__ be a bearer token, a certificate-bound token, or an identity-bound token
92+
depending on the chosen authentication flow.
9393

9494
## Expected Behavior
9595

@@ -104,7 +104,7 @@ digraph d_front_back {
104104
105105
check_env_var [ label="1. Check Environment Variables" ];
106106
load_credentials [ label="2. Load Credentials" ];
107-
check_metadata [ label="3. Check Virtual Machine Credentials" ];
107+
check_metadata [ label="3. Check workload credentials" ];
108108
auth_flows [ label="4. Determine Auth Flows" ];
109109
execute [ label="5. Execute Auth Flows" ];
110110
@@ -127,10 +127,17 @@ digraph d_front_back {
127127
1. If the credential is [an external account][8] JSON, go to step (4)
128128
1. If the credential is unknown type, return an error saying that _[END]_
129129
1. Credentials not found _[END]_
130-
1. **Check Google Virtual Machine Credentials**
131-
1. If true, use the [virtual machine flow][3] to fetch an auth token associated with the current environment
132-
1. If target audience is provided by the developer, get an [identity token][7] _[END]_
133-
1. Otherwise, get an access token _[END]_
130+
1. **Check workload credentials (on GCE, GKE, GAE and Serverless)**
131+
1. If true,
132+
1. If identity binding is enabled, by meeting the requirements in
133+
[mTLS Token Binding][9], use the mTLS Token Binding flow to fetch an
134+
identity-bound access token _[END]_
135+
1. If there is an issue when obtaining bound access tokens, return an error
136+
indicating that _[END]_
137+
1. If identity binding is not enabled, use the [virtual machine flow][3] to
138+
fetch an auth token associated with the current environment
139+
1. If target audience is provided by the developer, get an [identity token][7] _[END]_
140+
1. Otherwise, get an access token _[END]_
134141
1. If false, go to step (2.3)
135142
1. **Determine auth flows**
136143
1. If the credential is gcloud credential go to step (5.3)
@@ -166,4 +173,5 @@ digraph d_front_back {
166173
[6]: ./4112
167174
[7]: ./4116
168175
[8]: ./4117
176+
[9]: ./4119
169177
<!-- prettier-ignore-end -->

aip/auth/4118.md

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
---
2+
id: 4118
3+
scope: auth
4+
state: draft
5+
created: 2022-09-09
6+
---
7+
8+
# Mutual Authentication Using Workload Credentials
9+
10+
Mutual TLS (a.k.a mTLS) authentication enables authentication of both client and
11+
server identities in a TLS handshake. With workload credentials, applications
12+
running in Google Cloud can authenticate to Google APIs using [X.509 SPIFFE
13+
Verifiable Identity Documents][0] (SVIDs). These SVIDs are X.509 certificates
14+
that contain [SPIFFE IDs][1] specifying the identity of the certificate owners.
15+
mTLS authentication using X.509 SVIDs occurs when the client uses an X.509 SVID
16+
when performing the TLS handshake.
17+
18+
**Note:** Because this AIP describes guidance and requirements in a
19+
language-neutral way, it uses generic terminology which may be imprecise or
20+
inappropriate in certain languages or environments.
21+
22+
## Guidance
23+
24+
If users enable token binding, they **should** do so via [ADC][2]. This section
25+
describes the general guidance of supporting such authentication.
26+
27+
### Provisioning Workload Credentials in Google Cloud
28+
29+
On Google Cloud, workload credentials should be provisioned using one of the
30+
following methods:
31+
32+
- [Set up service security with Envoy][3].
33+
- [Set up service security with proxyless gRPC][4].
34+
35+
In order for workload credentials to be properly used, the auth libraries
36+
**must** support the automatic switching of the service endpoint to its mTLS
37+
counterpart.
38+
39+
### Using Workload Credentials
40+
41+
Users **should** configure [ADC][2] to use workload credentials via the
42+
certificate configuration gcloud metadata file. Workload credentials can be
43+
added as a **"cert_configs"** type as follows:
44+
45+
```json
46+
{
47+
“version”: 1
48+
"cert_configs": {
49+
"workload": {
50+
"cert_path": "path/to/cert/file"
51+
"key_path": "path/to/key/file"
52+
“workload_identity_provider”: “...”
53+
"authenticate_as_identity_type": "gsa/native"
54+
“service_account_email”: “...”
55+
},
56+
"keychain": {
57+
...
58+
},
59+
"pkcs11": {
60+
...
61+
},
62+
"windows": {
63+
...
64+
},
65+
},
66+
"libs": {
67+
...
68+
}
69+
}
70+
```
71+
72+
For Linux and macOS platforms, the above metadata file is located in the
73+
well-known gcloud config directory at
74+
**"~/.config/gcloud/certificate_config.json"**. Note that the default location
75+
of this file can be changed using the `GOOGLE_API_CERTIFICATE_CONFIG`
76+
environment variable.
77+
78+
The following lists the fields of the **"workload"** certificate info type that
79+
are relevant to workload credentials:
80+
81+
- **"cert_path"**: The specified value will be used as the full path to locate
82+
the workload certificate file. This file **must** contain a PEM-encoded
83+
X.509 certificate chain (ordered from leaf to root) where the leaf
84+
certificate is a valid X.509 SVID. The chain __may__ consist of only the
85+
leaf certificate.
86+
- **"key_path"**: The specified value will be used as the full path to locate
87+
the workload private key file. This file must contain a PEM-formatted
88+
private key associated with the X.509 certificate specified by
89+
**“cert_path”**.
90+
91+
The description of the **"workload_identity_provider"**,
92+
**"authenticate_as_identity_type"** and **"service_account_email"** fields can
93+
be found in [mTLS Token Binding][5].
94+
95+
To enable mutual authentication to Google APIs using workload credentials, the
96+
**"workload"** section and its **"cert_path"** and **"key_path"** values must be
97+
present in the **"~/.config/gcloud/certificate_config.json"** configuration
98+
file.
99+
100+
### Expected Behavior
101+
102+
Support for mTLS authentication to Google APIs using workload credentials
103+
**must** give priority to user mTLS endpoint override via client options. The
104+
auth libraries **must** follow the steps below:
105+
106+
- Locate the workload certificate and private key files using the above
107+
config file. If one of these files is not present, mTLS using workload
108+
credentials may be disabled. The auth libraries **must** check that the
109+
public and private keys in the certificate and key files match before
110+
passing them to the TLS library.
111+
- Occasional mismatches may happen, since during certificate rotation the
112+
client library may read the two files while another process is replacing
113+
them. In that case, the library **must** retry reading the certificate
114+
and private key files and checking their match status, up to a maximum
115+
of four attempts. The library **should** wait for 5 seconds between
116+
attempts.
117+
- If the certificate and private key files are loaded in memory (as
118+
opposed to being read from disk for every mTLS connection), the auth
119+
libraries **must** periodically reload them (at least every 10 minutes
120+
or when the certificate expires) to refresh their copies in memory after
121+
the infrastructure rotates them. Refreshing the credentials **must** be
122+
done in a background thread and not upon usage.
123+
- Configure the TLS library to use the found, and matched, certificate and
124+
key for client authentication during the TLS handshake.
125+
- If the user specifies the endpoint override via client options, use it as is
126+
and connect to the specified endpoint using mTLS.
127+
- If the user does not specify the endpoint override, use the default mTLS
128+
endpoint if the certificate and key files exist and the default regular
129+
endpoint otherwise.
130+
131+
Note that mTLS 1.3 **must** be the only supported version to preserve client
132+
identity and certificate confidentiality.
133+
134+
One implication of the above logic is that if the user enables mTLS
135+
authentication using workload credentials, provides valid certificate and key
136+
files, and specifies a non-mTLS endpoint override, the client libraries
137+
**should** use the certificate and key anyway and let the server decide what to
138+
do. This avoids introducing client-side logic that parses whether the endpoint
139+
override is an mTLS URL, since the URL pattern may change at any time.
140+
141+
### Obtaining the Default mTLS Endpoint
142+
143+
The default mTLS endpoint for a service **should** be read from the Discovery
144+
Document field **"mtlsRootUrl"** instead of generated via regex patterns.
145+
146+
<!-- prettier-ignore-start -->
147+
[0]: https://github.com/spiffe/spiffe/blob/main/standards/X509-SVID.md
148+
[1]: https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#2-spiffe-identity
149+
[2]: https://google.aip.dev/auth/4110
150+
[3]: https://cloud.google.com/traffic-director/docs/security-envoy-setup
151+
[4]: https://cloud.google.com/traffic-director/docs/security-proxyless-setup
152+
[5]: https://google.aip.dev/auth/4119
153+
<!-- prettier-ignore-end -->

aip/auth/4119.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
---
2+
id: 4119
3+
scope: auth
4+
state: draft
5+
created: 2022-09-09
6+
---
7+
8+
# mTLS Token Binding
9+
10+
Token binding allows issuing Google access tokens that are bound to mTLS
11+
credentials. The advantage of such mTLS bound tokens is that they are meant to
12+
only be used over secure channels established via mTLS credentials they are
13+
bound to. Therefore, using bound tokens is more secure than bearer tokens which
14+
can be stolen and adversarially replayed.
15+
16+
This AIP describes the flow of (1) obtaining access tokens bound to X.509
17+
certificate identities, called identity-bound tokens and (2) how to use them to
18+
access Google APIs using the Google auth libraries.
19+
20+
**Note:** Because this AIP describes guidance and requirements in a
21+
language-neutral way, it uses generic terminology which may be imprecise or
22+
inappropriate in certain languages or environments.
23+
24+
## Guidance
25+
26+
If users enable token binding, they **should** do so via [ADC][0]. This section
27+
describes the general guidance of supporting such tokens.
28+
29+
### Prerequisites
30+
31+
Identity-bound access tokens require that the clients have
32+
[X.509 SPIFFE Verifiable Identity Documents][1] (SVIDs). [Mutual Authentication
33+
Using Workload Credentials][2] describes how such SVIDs are provisioned in
34+
Google Cloud.
35+
36+
Additionally, identity-bound access tokens tokens require configuring a workload
37+
identity pool and identity provider with Google Cloud's IAM. The instructions on
38+
how to do this are out of scope of this AIP.
39+
40+
### Using mTLS Token Binding
41+
42+
The auth libraries **must** support the following values in the
43+
**"~/.config/gcloud/certificate_config.json"** configuration file. Note that the
44+
default location of this file can be changed using the
45+
`GOOGLE_API_CERTIFICATE_CONFIG` environment variable.
46+
47+
```json
48+
{
49+
“version”: 1
50+
"cert_configs": {
51+
"workload": {
52+
"cert_path": "path/to/cert/file"
53+
"key_path": "path/to/key/file"
54+
“workload_identity_provider”: “...”
55+
"authenticate_as_identity_type": "gsa/native"
56+
“service_account_email”: “...”
57+
},
58+
"keychain": {
59+
...
60+
},
61+
"pkcs11": {
62+
...
63+
},
64+
"windows": {
65+
...
66+
},
67+
},
68+
"libs": {
69+
...
70+
}
71+
}
72+
```
73+
74+
The following lists the fields relevant to mTLS token binding configuration:
75+
76+
- **"workload_identity_provider"**: The specified value will be used to
77+
populate the request to Security Token Service (STS) to request
78+
identity-bound access tokens. This value refers to the fully qualified name
79+
of the workload identity pool and identity provider configured in IAM. The
80+
specified value **must** be of the following format.
81+
82+
```
83+
"workload_identity_provider":"//iam.googleapis.com/projects/<project_number>/locations/global/workloadIdentityPools/<pool_identifier>/providers/<provider_identifier>"
84+
```
85+
86+
- **"authenticate_as_identity_type"**: This field specifies what identity is
87+
used to authenticate to Google APIs. The value can be set to `gsa` or
88+
`native`, where `gsa` is the GCP service account of the workload, e.g., the
89+
GCP service account of a GCE VM, and `native` is the native workload
90+
identity, e.g., the GKE pod kubernetes service account. If not specified,
91+
the default value is `gsa`.
92+
93+
- **"service_account_email"**: If set, the specified value will be used to
94+
populate the request to the IAM Credentials service to request
95+
identity-bound access tokens. This value refers to the service account email
96+
to be used for resource access. If not set, the service account email will
97+
be determined automatically by querying the following Metadata Service
98+
endpoint:
99+
`http://metadata/computeMetadata/v1/instance/service-accounts/default/email`.
100+
The value of this field is only relevant if
101+
**"authenticate_as_identity_type"** is set to `gsa`.
102+
103+
The description of the **"cert_path"** and **"key_path"** fields can be found in
104+
[Mutual Authentication Using Workload Credentials][2].
105+
106+
To enable using token binding when communicating with Google APIs the following
107+
conditions are required:
108+
109+
- [Mutual Authentication Using Workload Credentials][2] **must** be enabled.
110+
- The **"workload_identity_provider"** **must** be present,
111+
**"authenticate_as_identity_type"** __may__ be set and
112+
**"service_account_email"** __may__ be set in the **"workload"**
113+
section of the **"~/.config/gcloud/certificate_config.json"** configuration
114+
file.
115+
116+
### Expected Behavior
117+
118+
To support the usage of identity-bound access tokens, the auth libraries
119+
**must** follow the steps below when sending requests to Google APIs:
120+
121+
1. Connect to the mTLS endpoint of the [STS API][3] using the workload
122+
credentials provisioned as described in [Mutual Authentication Using
123+
Workload Credentials][2]. This endpoint **must** be
124+
`sts.mtls.googleapis.com`.
125+
1. Send an HTTP request to STS’s [ExchangeToken][5] method requesting an
126+
identity-bound token using the information in the
127+
**"workload_identity_provider"** field in the
128+
**"~/.config/gcloud/certificate_config.json"** configuration file. The
129+
scope of the requested token **must** be
130+
`https://www.googleapis.com/auth/iam`.
131+
1. Connect to the mTLS endpoint of the [IAM Credentials Service API][4] using
132+
the workload credentials provisioned as described in [Mutual Authentication
133+
Using Workload Credentials][2]. This endpoint **must** be
134+
`iamcredentials.mtls.googleapis.com`.
135+
1. If **"authenticate_as_identity_type"** is set to `gsa`, send an HTTP
136+
request to the IAM Credentials Service’s [GenerateAccessToken][6] method
137+
requesting an identity bound token asserting the service account email in
138+
the **"service_account_email"** field in the
139+
**"~/.config/gcloud/certificate_config.json"** configuration file. The
140+
scope of this token **must** be the same scope defined by the user for
141+
accessing the requested Google API.
142+
1. Attach the returned token in Step 4 to the request. Note that this request
143+
**must** be sent over an mTLS channel using the same workload credentials
144+
in Step 1.
145+
146+
<!-- prettier-ignore-start -->
147+
[0]: https://google.aip.dev/auth/4110
148+
[1]: https://github.com/spiffe/spiffe/blob/main/standards/X509-SVID.md
149+
[2]: https://google.aip.dev/auth/4118
150+
[3]: https://cloud.google.com/iam/docs/reference/sts/rest
151+
[4]: https://cloud.google.com/iam/docs/reference/credentials/rest
152+
[5]: https://cloud.google.com/iam/docs/reference/sts/rest/v1/TopLevel/token
153+
[6]: https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/generateAccessToken
154+
<!-- prettier-ignore-end -->

0 commit comments

Comments
 (0)