1*af546375SCole Faust#!/bin/bash 2*af546375SCole Faust 3*af546375SCole Faust# Copyright 2021 Google LLC 4*af546375SCole Faust# 5*af546375SCole Faust# Redistribution and use in source and binary forms, with or without 6*af546375SCole Faust# modification, are permitted provided that the following conditions are 7*af546375SCole Faust# met: 8*af546375SCole Faust# 9*af546375SCole Faust# * Redistributions of source code must retain the above copyright 10*af546375SCole Faust# notice, this list of conditions and the following disclaimer. 11*af546375SCole Faust# * Redistributions in binary form must reproduce the above 12*af546375SCole Faust# copyright notice, this list of conditions and the following disclaimer 13*af546375SCole Faust# in the documentation and/or other materials provided with the 14*af546375SCole Faust# distribution. 15*af546375SCole Faust# * Neither the name of Google LLC nor the names of its 16*af546375SCole Faust# contributors may be used to endorse or promote products derived from 17*af546375SCole Faust# this software without specific prior written permission. 18*af546375SCole Faust# 19*af546375SCole Faust# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20*af546375SCole Faust# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21*af546375SCole Faust# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22*af546375SCole Faust# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23*af546375SCole Faust# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24*af546375SCole Faust# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25*af546375SCole Faust# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*af546375SCole Faust# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*af546375SCole Faust# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*af546375SCole Faust# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29*af546375SCole Faust# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*af546375SCole Faust 31*af546375SCole Faust# This script is used to generate the project configurations needed to 32*af546375SCole Faust# end-to-end test workload identity pools in the Auth library, specifically 33*af546375SCole Faust# OIDC-based credentials and AWS credentials. This script only needs to be ran once. 34*af546375SCole Faust# 35*af546375SCole Faust# In order to run this script, the GOOGLE_APPLICATION_CREDENTIALS environment 36*af546375SCole Faust# variable needs to be set to point to a service account key file. 37*af546375SCole Faust# Additional fields must be provided in this file. 38*af546375SCole Faust# Detailed instructions are documented below. 39*af546375SCole Faust# 40*af546375SCole Faust# GCP project changes: 41*af546375SCole Faust# -------------------- 42*af546375SCole Faust# The following IAM roles need to be set on the service account: 43*af546375SCole Faust# 1. IAM Workload Identity Pool Admin (needed to create resources for workload 44*af546375SCole Faust# identity pools). 45*af546375SCole Faust# 2. Security Admin (needed to get and set IAM policies). 46*af546375SCole Faust# 3. Service Account Token Creator (needed to generate Google ID tokens and 47*af546375SCole Faust# access tokens). 48*af546375SCole Faust# 49*af546375SCole Faust# The following APIs need to be enabled on the project: 50*af546375SCole Faust# 1. Identity and Access Management (IAM) API. 51*af546375SCole Faust# 2. IAM Service Account Credentials API. 52*af546375SCole Faust# 3. Cloud Resource Manager API. 53*af546375SCole Faust# 4. The API being accessed in the test, eg. DNS. 54*af546375SCole Faust# 55*af546375SCole Faust# AWS developer account changes: 56*af546375SCole Faust# ------------------------------ 57*af546375SCole Faust# For testing AWS credentials, the following are needed: 58*af546375SCole Faust# 1. An AWS developer account is needed. The account ID will need to 59*af546375SCole Faust# be provided in the configuration object below. 60*af546375SCole Faust# 2. A role for web identity federation. This will also need to be provided 61*af546375SCole Faust# in the configuration object below. 62*af546375SCole Faust# - An OIDC Google identity provider needs to be created with the following: 63*af546375SCole Faust# issuer: accounts.google.com 64*af546375SCole Faust# audience: Use the client_id of the service account. 65*af546375SCole Faust# - A role for OIDC web identity federation is needed with the created 66*af546375SCole Faust# Google provider as a trusted entity: 67*af546375SCole Faust# "accounts.google.com:aud": "$CLIENT_ID" 68*af546375SCole Faust# The role creation steps are documented at: 69*af546375SCole Faust# https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html 70*af546375SCole Faust# 71*af546375SCole Faust# This script needs to be run once. It will do the following: 72*af546375SCole Faust# 1. Create a random workload identity pool. 73*af546375SCole Faust# 2. Create a random OIDC provider in that pool which uses the 74*af546375SCole Faust# 3. Enable OIDC tokens generated by the current service account to impersonate 75*af546375SCole Faust# the service account. (Identified by the OIDC token sub field which is the 76*af546375SCole Faust# service account client ID). 77*af546375SCole Faust# 4. Create a random AWS provider in that pool which uses the provided AWS 78*af546375SCole Faust# account ID. 79*af546375SCole Faust# 5. Enable AWS provider to impersonate the service account. (Principal is 80*af546375SCole Faust# identified by the AWS role name). 81*af546375SCole Faust# 6. Print out the STS audience fields associated with the created providers 82*af546375SCole Faust# and AWS role name/arn after the setup completes successfully so that 83*af546375SCole Faust# they can be used in the tests. 84*af546375SCole Faust# 85*af546375SCole Faust# The same service account used for this setup script should be used for 86*af546375SCole Faust# the test script. 87*af546375SCole Faust# 88*af546375SCole Faust# It is safe to run the setup script again. A new pool is created and new 89*af546375SCole Faust# audiences are printed. If run multiple times, it is advisable to delete 90*af546375SCole Faust# unused pools. Note that deleted pools are soft deleted and may remain for 91*af546375SCole Faust# a while before they are completely deleted. The old pool ID cannot be used 92*af546375SCole Faust# in the meantime. 93*af546375SCole Faust 94*af546375SCole Faustsuffix="" 95*af546375SCole Faust 96*af546375SCole Faustfunction generate_random_string () { 97*af546375SCole Faust local valid_chars=abcdefghijklmnopqrstuvwxyz0123456789 98*af546375SCole Faust for i in {1..8} ; do 99*af546375SCole Faust suffix+="${valid_chars:RANDOM%${#valid_chars}:1}" 100*af546375SCole Faust done 101*af546375SCole Faust} 102*af546375SCole Faust 103*af546375SCole Faustgenerate_random_string 104*af546375SCole Faust 105*af546375SCole Faustpool_id="pool-"${suffix} 106*af546375SCole Faustoidc_provider_id="oidc-"${suffix} 107*af546375SCole Faustaws_provider_id="aws-"${suffix} 108*af546375SCole Faust 109*af546375SCole Faust# Fill in. 110*af546375SCole Faustproject_id="" 111*af546375SCole Faustproject_number="" 112*af546375SCole Faustaws_account_id="" 113*af546375SCole Faustaws_role_name="" 114*af546375SCole Faustservice_account_email="" 115*af546375SCole Faustsub=""; # client_id from service account key file 116*af546375SCole Faust 117*af546375SCole Faustoidc_aud="//iam.googleapis.com/projects/${project_number}/locations/global/workloadIdentityPools/${pool_id}/providers/${oidc_provider_id}" 118*af546375SCole Faustaws_aud="//iam.googleapis.com/projects/${project_number}/locations/global/workloadIdentityPools/${pool_id}/providers/${aws_provider_id}" 119*af546375SCole Faust 120*af546375SCole Faustgcloud config set project ${project_id} 121*af546375SCole Faust 122*af546375SCole Faust# Create the Workload Identity Pool. 123*af546375SCole Faustgcloud beta iam workload-identity-pools create ${pool_id} \ 124*af546375SCole Faust --location="global" \ 125*af546375SCole Faust --description="Test pool" \ 126*af546375SCole Faust --display-name="Test pool for Java" 127*af546375SCole Faust 128*af546375SCole Faust# Create the OIDC Provider. 129*af546375SCole Faustgcloud beta iam workload-identity-pools providers create-oidc ${oidc_provider_id} \ 130*af546375SCole Faust --workload-identity-pool=${pool_id} \ 131*af546375SCole Faust --issuer-uri="https://accounts.google.com" \ 132*af546375SCole Faust --location="global" \ 133*af546375SCole Faust --attribute-mapping="google.subject=assertion.sub" 134*af546375SCole Faust 135*af546375SCole Faust# Create the AWS Provider. 136*af546375SCole Faustgcloud beta iam workload-identity-pools providers create-aws ${aws_provider_id} \ 137*af546375SCole Faust --workload-identity-pool=${pool_id} \ 138*af546375SCole Faust --account-id=${aws_account_id} \ 139*af546375SCole Faust --location="global" 140*af546375SCole Faust 141*af546375SCole Faust# Give permission to impersonate the service account. 142*af546375SCole Faustgcloud iam service-accounts add-iam-policy-binding ${service_account_email} \ 143*af546375SCole Faust--role roles/iam.workloadIdentityUser \ 144*af546375SCole Faust--member "principal://iam.googleapis.com/projects/${project_number}/locations/global/workloadIdentityPools/${pool_id}/subject/${sub}" 145*af546375SCole Faust 146*af546375SCole Faustgcloud iam service-accounts add-iam-policy-binding ${service_account_email} \ 147*af546375SCole Faust --role roles/iam.workloadIdentityUser \ 148*af546375SCole Faust --member "principalSet://iam.googleapis.com/projects/${project_number}/locations/global/workloadIdentityPools/${pool_id}/attribute.aws_role/arn:aws:sts::${aws_account_id}:assumed-role/${aws_role_name}" 149*af546375SCole Faust 150*af546375SCole Faustecho "OIDC audience:"${oidc_aud} 151*af546375SCole Faustecho "AWS audience:"${aws_aud} 152*af546375SCole Faustecho "AWS role name:"${aws_role_name} 153*af546375SCole Faustecho "AWS role ARN: arn:aws:iam::${aws_account_id}:role/${aws_role_name}" 154