Skip to content

Commit bd898c6

Browse files
aeitzmanlsirac
andauthored
docs: adds docs for supplier based external account credentials (#1362)
* docs: adds readme for supplier based external account credentials * Update README.md Co-authored-by: Leo <[email protected]> * Update README.md Co-authored-by: Leo <[email protected]> * Update README.md Co-authored-by: Leo <[email protected]> * Update README.md Co-authored-by: Leo <[email protected]> * Update README.md Co-authored-by: Leo <[email protected]> * Update README.md Co-authored-by: Leo <[email protected]> * addressing review * Addressing comments * Apply suggestions from code review Co-authored-by: Leo <[email protected]> * clean up workforce docs * Addressing comments * Apply suggestions from code review Co-authored-by: Leo <[email protected]> * Adding audience documentation for workload --------- Co-authored-by: Leo <[email protected]>
1 parent b97fa20 commit bd898c6

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed

README.md

+180
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,128 @@ credentials unless they do not meet your specific requirements.
470470
You can now [use the Auth library](#using-external-identities) to call Google Cloud
471471
resources from an OIDC or SAML provider.
472472

473+
#### Using a custom supplier with OIDC and SAML
474+
A custom implementation of IdentityPoolSubjectTokenSupplier can be used while building IdentityPoolCredentials
475+
to supply a subject token which can be exchanged for a GCP access token. The supplier must return a valid,
476+
unexpired subject token when called by the GCP credential.
477+
478+
IdentityPoolCredentials do not cache the returned token, so caching logic should be
479+
implemented in the token supplier to prevent multiple requests for the same subject token.
480+
481+
```java
482+
import java.io.IOException;
483+
484+
public class CustomTokenSupplier implements IdentityPoolSubjectTokenSupplier {
485+
486+
@Override
487+
public String getSubjectToken(ExternalAccountSupplierContext context) throws IOException {
488+
// Any call to the supplier will pass a context object with the requested
489+
// audience and subject token type.
490+
string audience = context.getAudience();
491+
string tokenType = context.getSubjectTokenType();
492+
493+
try {
494+
// Return a valid, unexpired token for the requested audience and token type.
495+
// Note that IdentityPoolCredentials do not cache the subject token so
496+
// any caching logic needs to be implemented in the token supplier.
497+
return retrieveToken(audience, tokenType);
498+
} catch (Exception e) {
499+
// If token is unavailable, throw IOException.
500+
throw new IOException(e);
501+
}
502+
}
503+
504+
private String retrieveToken(string tokenType, string audience) {
505+
// Retrieve a subject token of the requested type for the requested audience.
506+
}
507+
}
508+
```
509+
```java
510+
CustomTokenSupplier tokenSupplier = new CustomTokenSupplier();
511+
IdentityPoolCredentials identityPoolCredentials =
512+
IdentityPoolCredentials.newBuilder()
513+
.setSubjectTokenSupplier(tokenSupplier) // Sets the token supplier.
514+
.setAudience(...) // Sets the GCP audience.
515+
.setSubjectTokenType(SubjectTokenTypes.JWT) // Sets the subject token type.
516+
.build();
517+
```
518+
Where the [audience](https://cloud.google.com/iam/docs/best-practices-for-using-workload-identity-federation#provider-audience) is:
519+
```//iam.googleapis.com/locations/global/workforcePools/$WORKLOAD_POOL_ID/providers/$PROVIDER_ID```
520+
521+
Where the following variables need to be substituted:
522+
- `$WORKLOAD_POOL_ID`: The workload pool ID.
523+
- `$PROVIDER_ID`: The provider ID.
524+
525+
The values for audience, service account impersonation URL, and any other builder field can also be found by
526+
generating a [credential configuration file with the gcloud CLI](https://cloud.google.com/sdk/gcloud/reference/iam/workload-identity-pools/create-cred-config).
527+
528+
#### Using a custom supplier with AWS
529+
A custom implementation of AwsSecurityCredentialsSupplier can be provided when initializing AwsCredentials. If provided, the AwsCredentials instance will defer to the supplier to retrieve AWS security credentials to exchange for a GCP access token.
530+
The supplier must return valid, unexpired AWS security credentials when called by the GCP credential.
531+
532+
AwsCredentials do not cache the returned AWS security credentials or region, so caching logic should be
533+
implemented in the supplier to prevent multiple requests for the same resources.
534+
535+
```java
536+
class CustomAwsSupplier implements AwsSecurityCredentialsSupplier {
537+
@Override
538+
AwsSecurityCredentials getAwsSecurityCredentials(ExternalAccountSupplierContext context) throws IOException {
539+
// Any call to the supplier will pass a context object with the requested
540+
// audience.
541+
string audience = context.getAudience();
542+
543+
try {
544+
// Return valid, unexpired AWS security credentials for the requested audience.
545+
// Note that AwsCredentials do not cache the AWS security credentials so
546+
// any caching logic needs to be implemented in the credentials' supplier.
547+
return retrieveAwsSecurityCredentials(audience);
548+
} catch (Exception e) {
549+
// If credentials are unavailable, throw IOException.
550+
throw new IOException(e);
551+
}
552+
}
553+
554+
@Override
555+
String getRegion(ExternalAccountSupplierContext context) throws IOException {
556+
try {
557+
// Return a valid AWS region. i.e. "us-east-2".
558+
// Note that AwsCredentials do not cache the region so
559+
// any caching logic needs to be implemented in the credentials' supplier.
560+
return retrieveAwsRegion();
561+
} catch (Exception e) {
562+
// If region is unavailable, throw IOException.
563+
throw new IOException(e);
564+
}
565+
}
566+
567+
private AwsSecurityCredentials retrieveAwsSecurityCredentials(string audience) {
568+
// Retrieve Aws security credentials for the requested audience.
569+
}
570+
571+
private String retrieveAwsRegion() {
572+
// Retrieve current AWS region.
573+
}
574+
}
575+
```
576+
```java
577+
CustomAwsSupplier awsSupplier = new CustomAwsSupplier();
578+
AwsCredentials credentials = AwsCredentials.newBuilder()
579+
.setSubjectTokenType(SubjectTokenTypes.AWS4) // Sets the subject token type.
580+
.setAudience(...) // Sets the GCP audience.
581+
.setAwsSecurityCredentialsSupplier(supplier) // Sets the supplier.
582+
.build();
583+
```
584+
585+
Where the [audience](https://cloud.google.com/iam/docs/best-practices-for-using-workload-identity-federation#provider-audience) is:
586+
```//iam.googleapis.com/locations/global/workforcePools/$WORKLOAD_POOL_ID/providers/$PROVIDER_ID```
587+
588+
Where the following variables need to be substituted:
589+
- `$WORKLOAD_POOL_ID`: The workload pool ID.
590+
- `$PROVIDER_ID`: The provider ID.
591+
592+
The values for audience, service account impersonation URL, and any other builder field can also be found by
593+
generating a [credential configuration file with the gcloud CLI](https://cloud.google.com/sdk/gcloud/reference/iam/workload-identity-pools/create-cred-config).
594+
473595
#### Configurable Token Lifetime
474596
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.
475597

@@ -704,6 +826,64 @@ specified below. It must output the response to stdout.
704826
Refer to the [using executable-sourced credentials with Workload Identity Federation](#using-executable-sourced-credentials-with-oidc-and-saml)
705827
above for the executable response specification.
706828

829+
#### Using a custom supplier with OIDC and SAML
830+
A custom implementation of IdentityPoolSubjectTokenSupplier can be used while building IdentityPoolCredentials
831+
to supply a subject token which can be exchanged for a GCP access token. The supplier must return a valid,
832+
unexpired subject token when called by the GCP credential.
833+
834+
IdentityPoolCredentials do not cache the returned token, so caching logic should be
835+
implemented in the token supplier to prevent multiple requests for the same subject token.
836+
837+
```java
838+
import java.io.IOException;
839+
840+
public class CustomTokenSupplier implements IdentityPoolSubjectTokenSupplier {
841+
842+
@Override
843+
public String getSubjectToken(ExternalAccountSupplierContext context) throws IOException {
844+
// Any call to supplier will pass a context object with the requested
845+
// audience and subject token type.
846+
string audience = context.getAudience();
847+
string tokenType = context.getSubjectTokenType();
848+
849+
try {
850+
// Return a valid, unexpired token for the requested audience and token type.
851+
// Note that the IdentityPoolCredential does not cache the subject token so
852+
// any caching logic needs to be implemented in the token supplier.
853+
return retrieveToken(audience, tokenType);
854+
} catch (Exception e) {
855+
// If token is unavailable, throw IOException.
856+
throw new IOException(e);
857+
}
858+
}
859+
860+
private String retrieveToken(string tokenType, string audience) {
861+
// Retrieve a subject token of the requested type for the requested audience.
862+
}
863+
}
864+
```
865+
```java
866+
CustomTokenSupplier tokenSupplier = new CustomTokenSupplier();
867+
IdentityPoolCredentials identityPoolCredentials =
868+
IdentityPoolCredentials.newBuilder()
869+
.setSubjectTokenSupplier(tokenSupplier) // Sets the token supplier.
870+
.setAudience(...) // Sets the GCP audience.
871+
.setSubjectTokenType(SubjectTokenTypes.JWT) // Sets the subject token type.
872+
.setWorkforcePoolUserProject(...) // Sets the workforce pool user project.
873+
.build();
874+
```
875+
Where the audience is:
876+
```//iam.googleapis.com/locations/global/workforcePools/$WORKFORCE_POOL_ID/providers/$PROVIDER_ID```
877+
878+
Where the following variables need to be substituted:
879+
- `$WORKFORCE_POOL_ID`: The workforce pool ID.
880+
- `$PROVIDER_ID`: The provider ID.
881+
882+
and the workforce pool user project is the project number associated with the [workforce pools user project](https://cloud.google.com/iam/docs/workforce-identity-federation#workforce-pools-user-project).
883+
884+
The values for audience, service account impersonation URL, and any other builder field can also be found by
885+
generating a [credential configuration file with the gcloud CLI](https://cloud.google.com/iam/docs/workforce-obtaining-short-lived-credentials#use_configuration_files_for_sign-in).
886+
707887
##### Security considerations
708888
The following security practices are highly recommended:
709889
* Access to the script should be restricted as it will be displaying credentials to stdout. This ensures that rogue processes do not gain access to the script.

0 commit comments

Comments
 (0)