The Shared Flow reads its configuration from an encrypted KVM. Create the KVM and set the Aforo credentials:
terminal
# Create the KVM (encrypted, environment-scoped)
curl -X POST "https://apigee.googleapis.com/v1/organizations/{ORG}/environments/{ENV}/keyvaluemaps" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"name": "aforo-config",
"encrypted": true
}'
# Set the API key
curl -X POST "https://apigee.googleapis.com/v1/organizations/{ORG}/environments/{ENV}/keyvaluemaps/aforo-config/entries" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"name": "aforo_api_key",
"value": "sk_live_your_key_here"
}'
# Set the ingest endpoint
curl -X POST "https://apigee.googleapis.com/v1/organizations/{ORG}/environments/{ENV}/keyvaluemaps/aforo-config/entries" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"name": "aforo_ingest_url",
"value": "https://ingest.aforo.ai/v1/ingest"
}'
WARNING
Always use encrypted KVMs for API keys. Apigee encrypts the values at rest and in transit. Never store credentials in proxy-level variables or environment properties.
Attach the Shared Flow to a Pre-Proxy Flow Hook for global enforcement. This ensures every API proxy in the environment runs the Aforo entitlement and metering logic automatically — no individual proxy edits.
terminal
# Attach to Pre-Proxy Flow Hook (entitlement check BEFORE backend)
curl -X PUT "https://apigee.googleapis.com/v1/organizations/{ORG}/environments/{ENV}/flowhooks/PreProxyFlowHook" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"sharedFlow": "aforo-metering",
"continueOnError": false
}'
# Optional: Also attach to Post-Proxy for async metering
curl -X PUT "https://apigee.googleapis.com/v1/organizations/{ORG}/environments/{ENV}/flowhooks/PostProxyFlowHook" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"sharedFlow": "aforo-metering",
"continueOnError": true
}'
PreProxyFlowHook
Entitlement check + Margin Guard enforcement
Before backend
PostProxyFlowHook
Async usage metering + event enrichment
After response
PRO TIP
Set continueOnError: false on PreProxy to hard-block requests that fail entitlement checks. Set continueOnError: true on PostProxy so metering failures never break the API response.
L3 enforcement uses Apigee's RaiseFault policy. The request is rejected at the gateway — your backend never sees it. This protects compute costs from unprofitable traffic.
Verify the deployment by checking the Flow Hook attachment and sending a test request:
terminal
# Verify Flow Hook is attached
curl -s "https://apigee.googleapis.com/v1/organizations/{ORG}/environments/{ENV}/flowhooks/PreProxyFlowHook" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" | jq .
# Expected: { "sharedFlow": "aforo-metering", "continueOnError": false }
# PaperPlaneTilt a test request through any proxy in the environment
curl -v https://{ORG}-{ENV}.apigee.net/your-api/endpoint \
-H "X-Tenant-Id: test_tenant_123" \
-H "Authorization: Bearer sk_live_customer_key"
# Check for Aforo headers in response:
# X-Aforo-Remaining: 8420
# X-Aforo-Plan: enterprise
# Verify event in Aforo
curl -s "https://api.aforo.ai/v1/events?tenant_id=test_tenant_123&limit=1" \
-H "Authorization: Bearer sk_live_your_admin_key" | jq .
PRO TIP
If events are not appearing, check the Apigee Debug (Trace) tool. Look for the aforo-metering Shared Flow execution in the PreProxy phase. Common issues: KVM not found (wrong environment), expired Aforo API key, or network policy blocking outbound HTTPS to ingest.aforo.ai.