This interceptor streamlines work with Google Cloud DLP—handling PII detection, de‑identification, and re‑identification—while supporting asynchronous workflows. Blocking RPC calls are delegated to the event loop’s default executor, making the design well‑suited for modern async Python applications.
- PII Detection: Identifies sensitive information within text and images.
- De-identification: Transforms sensitive data (e.g., masking, redacting, tokenizing) to protect privacy.
- Re-identification (for tokenized data): Reverses the de-identification process for specific tokenized data, allowing controlled access to original PII when necessary
- Asynchronous Operations: Integrates seamlessly into asyncio applications.
A step‑by‑step guide to spinning up Google Cloud Model Armor — complete with Compute Engine dependencies, KMS encryption, and four ready‑to‑use templates (basic filter · inspect · de‑identify · re‑identify) — using nothing but the gcloud CLI.
Model Armor relies on Google Cloud APIs that require billing and authentication. The service account is necessary to automate deployment and API calls.
| Tool / Resource | Version / Role | Notes |
|---|---|---|
| gcloud CLI | ≥ 460 | gcloud version |
| openssl | any | Generate AES key |
| Service‑account JSON key | Project Owner | Activate via gcloud auth |
| Billing Account | Billing Admin | Needed for new project |
Add following variables to main:
| Variable | Description |
|---|---|
| GOOGLE_PROJECT | GCP project name |
| GOOGLE_REGION | GCP region |
| GOOGLE_INSPECT_TEMPLATE | inspect template |
| GOOGLE_DEIDENTIFY_TEMPLATE | PII deidentify template name |
| GOOGLE_KMS_KEY_NAME | PATH to DLP key |
| GOOGLE_KMS_WRAPPED_KEY | KMS wrapped key base64 |
| GOOGLE_SURROGATE_INFO_TYPE | Surrogate token name in re-identify template |
| GOOGLE_APPLICATION_CREDENTIALS | Local path to credentials file |
| DIAL_URL | URL where DIAL Core is running |
Activate the service account and set it as the active one
gcloud auth activate-service-account --key-file=./secret/xxx-key.json
gcloud config set account "$(jq -r .client_email < ./secret/xxx-key.json)"A project is the security + billing boundary for Model Armor. Without billing, the Model Armor API refuses to enable.
# Create the project
gcloud projects create "$PROJECT_ID" \
--name="Model Armor Demo"
# Link to a billing account
gcloud billing projects link "$PROJECT_ID" \
--billing-account "$BILLING_ACCOUNT_ID"# Point gcloud at the regional Model Armor endpoint
gcloud config set api_endpoint_overrides/modelarmor \
"https://modelarmor.${LOCATION_ID}.rep.googleapis.com/"
# Enable the required services
gcloud services enable compute.googleapis.com --project "$PROJECT_ID"
gcloud services enable modelarmor.googleapis.com --project "$PROJECT_ID"
gcloud services enable cloudkms.googleapis.com --project "$PROJECT_ID"Model Armor controls are template‑driven – each template is an immutable set of rules that the interceptor references by name.
gcloud model-armor templates create "$BASIC_TEMPLATE_ID" \
--location "$REGION" \
--basic-config-filter-enforcement=enabledAdds structured findings so downstream logic can decide to redact, log, or allow.
cat > inspect-config.json <<'EOF'
{
"inspectConfig": {
"infoTypes": [
{ "name": "EMAIL_ADDRESS" },
{ "name": "PHONE_NUMBER" },
{ "name": "CREDIT_CARD_NUMBER" }
],
"includeQuote": true
}
}
EOF
# Create template for Model Armor
gcloud model-armor templates create "$INSPECT_TEMPLATE_ID" \
--location "$REGION" \
[email protected]De-identification templates specify the rules and methods for transforming sensitive data (e.g., PII, financial details) to protect privacy while still allowing for data analysis or model training.
cat > deidentify-config.json <<'EOF'
{
"transformationConfigs": [
{
"primitiveTransform": {
"removeFindings": true
}
}
]
}
EOF
gcloud model-armor templates create "$DEID_TEMPLATE_ID" \
--location="$REGION" \
[email protected]Turns PII_TOKEN placeholders back into real data after the LLM responds.
cat > reidentify-config.json <<'EOF'
{
"reidentifyConfig": {
"surrogateInfoType": {
"name": "PII-TOKEN"
}
}
}
EOF
gcloud model-armor templates create "$REID_TEMPLATE_ID" \
--location "$REGION" \
[email protected]gcloud model-armor templates list --location "$LOCATION_ID"
# Should list: basic‑guard, inspect‑guard, deid‑guard, reid‑guard# Create a key ring
gcloud kms keyrings create "dlp-keyring" \
--location global \
--project "$PROJECT_ID"
# Create a key inside the key ring
gcloud kms keys create "dlp-key" \
--location global \
--keyring dlp-keyring \
--purpose encryption \
--project "$PROJECT_ID"# Generate 256‑bit AES key
openssl rand -out ./aes_key.bin 32
# Base‑64 encode
PLAINTEXT_KEY=$(base64 -i ./aes_key.bin)
# Wrap using Cloud KMS
gcloud kms encrypt \
--location=global \
--keyring=dlp-keyring \
--key=dlp-key \
--plaintext-file=<(echo "$PLAINTEXT_KEY") \
--ciphertext-file=wrapped_key.b64 \
--project="$PROJECT_ID"
export WRAPPED_KEY=$(cat wrapped_key.b64)
# Persist to env
printf "\nWRAPPED_KEY=%s\n" "$WRAPPED_KEY" >> .env# List templates
gcloud model-armor templates list --location "$REGION"
# Dry‑run an inspect call
gcloud model-armor templates inspect-user-prompt \
--location "$REGION" \
--template "$INSPECT_TEMPLATE_ID" \
--user-prompt-data-text "Hi, my SSN is 123‑45‑6789"Edit the config.json file located at:
$DIAL-CORE-SDK/dial-docker-compose/application/core/config.jsonAdd the Model Armor interceptor to the DIAL Core configuration and attach it to a model or an application:
{
"interceptors": {
"google-model-armor-interceptor": {
"endpoint": "MODEL_ARMOR_INTERCEPTOR_ORIGIN/openai/deployments/google-ma-anonymizer/chat/completions"
}
},
"models": {
"my-dial-model": {
"type": "chat",
"endpoint": "...",
"interceptors": [
"google-model-armor-interceptor"
]
}
},
"applications": {
"my-dial-application": {
"endpoint": "...",
"interceptors": [
"google-model-armor-interceptor"
]
}
}
}This ensures that all requests pass through the interceptor before reaching the model.