Skip to content

Instantly share code, notes, and snippets.

@mikesparr
Last active January 1, 2021 19:03
Show Gist options
  • Save mikesparr/6ff77e7bd22412904ce1442fd542374b to your computer and use it in GitHub Desktop.
Save mikesparr/6ff77e7bd22412904ce1442fd542374b to your computer and use it in GitHub Desktop.
VPC Service Control (Setup)
#!/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