Last active
January 1, 2021 19:03
-
-
Save mikesparr/6ff77e7bd22412904ce1442fd542374b to your computer and use it in GitHub Desktop.
VPC Service Control (Setup)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
export ORG_ID="CHANGEME" | |
export PROJECT_ID=$(gcloud config get-value project) | |
export PROJECT_USER=$(gcloud config get-value core/account) # set current user | |
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)") | |
export IDNS=${PROJECT_ID}.svc.id.goog # workflow identity domain | |
export DATA_SA_NAME="data-viewer" | |
export DATA_SA_ID="${DATA_SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" | |
export API_SA_NAME="aws-api" | |
export API_SA_ID="${API_SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" | |
export BUCKET_NAME="mike-vpc-sa-test1" | |
export STORAGE_CLASS="STANDARD" # NEARLINE | COLDLINE | ARCHIVE | |
export STORAGE_LOCATION="us-central1" # US | EU | ASIA | US-CENTRAL1 | ... | |
export POLICY_TITLE="default policy" | |
export PERIMETER_NAME="StoragePerimeter" | |
export LEVEL_NAME="AWSApiAccess" | |
# confirm they are installing in right project | |
while true; do | |
read -p "Create VPC Service Control on ${PROJECT_ID} as user ${PROJECT_USER}? " -n 1 -r yn | |
echo | |
case $yn in | |
[Yy]* ) break;; | |
[Nn]* ) exit;; | |
* ) echo "Please answer yes or no.";; | |
esac | |
done | |
# enable apis | |
gcloud services enable accesscontextmanager.googleapis.com \ | |
iam.googleapis.com \ | |
storage.googleapis.com | |
########################################################## | |
# SERVICE ACCOUNT(S) | |
########################################################## | |
# create service account to access data | |
gcloud iam service-accounts create $DATA_SA_NAME | |
gcloud organizations add-iam-policy-binding $ORG_ID \ | |
--member="serviceAccount:${DATA_SA_ID}" \ | |
--role="roles/storage.objectViewer" | |
# create service account to impersonate sa | |
gcloud iam service-accounts create $API_SA_NAME | |
gcloud organizations add-iam-policy-binding $ORG_ID \ | |
--member="serviceAccount:${API_SA_ID}" \ | |
--role="roles/iam.serviceAccountTokenCreator" | |
# download key for use on AWS | |
gcloud iam service-accounts keys create aws-sa-key.json \ | |
--iam-account=$API_SA_ID | |
########################################################## | |
# STORAGE BUCKET(S) | |
########################################################## | |
# create storage bucket | |
gsutil mb -b on -c $STORAGE_CLASS -l $STORAGE_LOCATION gs://${BUCKET_NAME} | |
# copy top-secret file to bucket | |
gsutil cp $(PWD)/top-secret.jpg gs://${BUCKET_NAME} | |
########################################################## | |
# VPC SERVICE CONTROLS | |
########################################################## | |
# create access policy (only one per org so may already exist) | |
# gcloud access-context-manager policies create \ | |
# --organization $ORG_ID \ | |
# --title $POLICY_TITLE | |
export POLICY_NAME=$(gcloud access-context-manager policies list --organization $ORG_ID --format="value(name)") | |
# create perimeter (restricted to a single Org) | |
gcloud access-context-manager perimeters \ | |
create $PERIMETER_NAME --title=$PERIMETER_NAME \ | |
--resources=projects/${PROJECT_NUMBER} \ | |
--restricted-services=storage.googleapis.com,bigquery.googleapis.com \ | |
--policy=$POLICY_NAME | |
# verify | |
gcloud access-context-manager perimeters list \ | |
--policy=$POLICY_NAME | |
# inspect | |
gcloud access-context-manager perimeters describe $PERIMETER_NAME \ | |
--policy=$POLICY_NAME | |
# create access level config | |
cat > access-level.yaml << EOF | |
- members: | |
- user:${PROJECT_USER} | |
- serviceAccount:${DATA_SA_ID} | |
EOF | |
# create access level | |
# optional: https://cloud.google.com/access-context-manager/docs/create-custom-access-level | |
gcloud access-context-manager levels create $LEVEL_NAME \ | |
--title $LEVEL_NAME \ | |
--basic-level-spec access-level.yaml \ | |
--policy=$POLICY_NAME | |
# add level to perimeter | |
gcloud access-context-manager perimeters update $PERIMETER_NAME \ | |
--add-access-levels=$LEVEL_NAME \ | |
--policy=$POLICY_NAME | |
########################################################## | |
# VERIFY ONLY DATA SA CAN ACCESS BUCKET | |
########################################################## | |
gcloud config set auth/impersonate_service_account $DATA_SA_ID | |
gsutil ls gs://${BUCKET_NAME} # OK | |
gcloud config set auth/impersonate_service_account $API_SA_ID | |
gsutil ls gs://${BUCKET_NAME} # DENIED | |
########################################################## | |
# NEXT STEPS | |
# 1. copy the aws-sa-key.json to your external env (i.e. AWS) | |
# 2. install the gcloud or gsutil in external env | |
# 3. leverage the key to authenticate gsutil (for test) | |
# `gcloud auth activate-service-account --key-file=aws-sa-key.json` | |
# 4. confirm cannot access bucket | |
# `gsutil ls gs://${BUCKET_NAME}` # DENIED | |
# 5. impersonate data SA | |
# `gcloud config set auth/impersonate_service_account ${DATA_SA_ID}` | |
# `gsutil ls gs://${BUCKET_NAME}` # OK | |
########################################################## | |
########################################################## | |
# REFERENCES | |
########################################################## | |
# https://cloud.google.com/iam/docs/creating-short-lived-service-account-credentials | |
# https://cloud.google.com/vpc-service-controls/docs/access-control | |
# https://cloud.google.com/vpc-service-controls/docs/create-service-perimeters | |
# https://cloud.google.com/vpc-service-controls/docs/create-perimeter-bridges | |
# https://cloud.google.com/vpc-service-controls/docs/set-up-private-connectivity | |
# https://cloud.google.com/vpc-service-controls/docs/use-access-levels | |
# https://cloud.google.com/vpc-service-controls/docs/troubleshooter |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment