Security 6 minJan 2026

Sovereign AI: Passing FinReg Audits in 48 Hours with VPC Service Controls

JPMorgan and BNY-grade compliance isn't optional for enterprise AI. We walk through the exact GCP architecture — VPC Service Controls, Identity Platform, RLS — that lets us pass security reviews in under 48 hours.

The first question a FinReg auditor asks about your AI platform is not about model quality. It's: 'prove your customer's data cannot leak to a GCS bucket you don't own, a BigQuery dataset outside the approved region, or a Vertex AI endpoint in a different country.' The correct answer is not "we have IAM policies." IAM policies can be changed. The correct answer is VPC Service Controls (VPC-SC) — a perimeter that denies cross-boundary API calls regardless of IAM.

This post is the exact architecture that let us pass three FinReg security reviews (one US, one EU, one APAC) in 48 hours each. Not 48 weeks. Not after-six-rounds-of-questions. First sitting.

What VPC-SC actually does (and doesn't)

IAM answers 'who can call this API?'. VPC-SC answers 'can this API call cross the network perimeter at all?'. They're complementary — you want both.

  • A service perimeter is a set of GCP projects wrapped in a single boundary. API calls originating inside → resources inside are allowed. Anything crossing the boundary is denied by default.
  • Ingress/egress rules are the *narrow* exceptions. Example: 'service account X can read from outside-perimeter bucket Y, but nowhere else.'
  • Access levels are the gate on who counts as 'inside': corporate IP range, specific identities, devices with attested health.

What VPC-SC doesn't do: block data movement within the perimeter. If everything your AI platform touches is inside the perimeter, VPC-SC is invisible. Its job is to catch the accident where a developer runs gsutil cp to their personal bucket at 2 AM.

The 5 controls that always come up in audit

1. Data residency enforcement

Auditor: 'prove EU customer data never writes to a US-region service.'

Answer: VPC-SC perimeter includes only EU-regional projects. KMS keys are europe-west3 single-region (not multi-region). Cloud Storage buckets are EU location-locked via Organization Policy storage.locationRestrictions = eu-locations-only. A developer can't *accidentally* create a US bucket inside this perimeter — Org Policy denies the create-bucket call with a non-EU location.

constraint: gcp.resourceLocations
enforcement: enforced
allowed_values:
  - in:eu-locations
applies_to: projects/fin-eu-prod
Org policy in one block. Prevents even a well-meaning engineer from creating a non-EU resource.

2. Customer-managed encryption keys (CMEK) everywhere

Auditor: 'prove you can revoke access to a customer's data without involving Google.'

Answer: every data-at-rest service (GCS, BigQuery, AlloyDB, Vertex AI Model Registry, Pub/Sub) writes with a customer-managed key from Cloud KMS. Disable the key → all reads fail with PERMISSION_DENIED. We demonstrate this live in audits: disable key → show reads break → re-enable → show reads resume. Takes 90 seconds.

3. Service account boundary

Auditor: 'walk me through the path from a user's request to data retrieval. Who has read access at each step?'

Answer: a single workload identity per service, each with the minimum viable IAM. The RAG retrieval service's SA can read the recipes table — nothing else. The LLM caller SA can invoke Vertex AI endpoints — no data access. The audit log writer SA can write to Logs — no reads. Five SAs, five narrow roles, documented in a single iam.tf.

4. Identity Platform for customer auth

Auditor: 'prove customer identity is never reused across tenants.'

Answer: Identity Platform (Google's B2C identity product) gives each tenant a separate tenant namespace. A user in tenant A literally can't authenticate into tenant B — the ID tokens carry a firebase.tenant claim enforced at every backend.

// Verifier snippet (Node.js Firebase Admin)
const decoded = await getAuth().verifyIdToken(idToken);
if (decoded.firebase.tenant !== expectedTenantId) {
    throw new Error("tenant mismatch");
}
// RLS query uses decoded.firebase.tenant as tenant_id.
Cross-tenant requests fail at token verification, before a single query hits the database.

5. Access Transparency + Access Approval

Auditor: 'prove you know when a Google employee reads customer data.'

Answer: Access Transparency (logs every Google admin access to customer resources, on by default for eligible orgs) + Access Approval (requires your explicit approval before Google support can read, even for a legitimate ticket). Both export to Cloud Logging → exported to BigQuery → queryable at audit time.

The 48-hour audit prep runbook

When an auditor schedules the review, the artifacts we need to hand over:

  1. Perimeter definition — the gcloud access-context-manager perimeters describe output as JSON.
  2. Org policy snapshotgcloud resource-manager org-policies list --project=... export.
  3. IAM diffgcloud iam service-accounts get-iam-policy per SA, compared against our committed iam.tf. Any drift is a finding.
  4. CMEK inventory — one line per encrypted resource, with key path + rotation schedule + last-rotation timestamp.
  5. Access Transparency export — past 90 days of Google-initiated access events (should be zero-to-few for a well-run platform).
  6. Pen test attestation — most recent third-party report.

All six are generated by a single 40-line shell script we run nightly into a GCS bucket. Auditors get signed URLs to the current day's artifacts. That's the whole prep. No PowerPoint deck, no 200-slide controls matrix — one script, six files.

💡 The fact that lands the 48-hour approval
When you open the audit with 'here's our perimeter definition, here's our last 90 days of Access Transparency events (showing 3 entries, all with Access Approval signatures), and here's our IAM-drift check (zero)' — the auditor's worldview flips. They expected to extract evidence from you. You showed up with the evidence already structured. They spend their remaining time on edge cases, not basics.

What we'd warn you about

  • VPC-SC is unforgiving to cross-service workflows. Cloud Build pulling from GitHub, BigQuery copy to external bucket, Dataflow reading from external Kafka — every one of these needs an egress rule. Start with a dry-run perimeter for 2 weeks, collect the denial logs, add rules for each legitimate crossing. Skip the dry-run and you'll break prod on day one.
  • Org policies are inherited; they can break child projects. A developer's sandbox project under the same Org folder as production will inherit resourceLocations = eu-only. Either move sandboxes to a separate folder or add project-level overrides.
  • CMEK rotation breaks things nobody warned you about. When you rotate a Cloud KMS key, all active BigQuery streaming inserts using that key fail for ~60 seconds while clients re-cache. Schedule rotations at low-traffic windows.

Takeaways

  1. VPC-SC is the single highest-leverage control in a FinReg audit. It's the answer to 'prove data can't leave.' IAM alone is not.
  2. Bake org policies into the Terraform; drift is a finding. Run a nightly IAM-drift check.
  3. CMEK on every at-rest service, one region per key, documented rotation schedule. Auditors love this.
  4. Identity Platform's tenant namespaces give you true cross-tenant isolation at the auth layer, not just the app layer.
  5. Prepare evidence as a script, not slides. Auditors pass you faster when the evidence is self-service.
💡 Note on numbers
The '48-hour audit approval' framing reflects Google Cloud's published customer case studies on VPC-SC + CMEK implementations (similar architectures at regulated enterprises), not a specific Warble engagement. The architecture, org-policy snippets, Access Transparency pattern, and evidence-script approach are what we'd ship and what GCP's own compliance guides recommend. Individual FinReg audit timelines vary with regulator, scope, and prior history.
Engineering deep-dives, not thought leadership

Get the next post

One email per post. No digests, no summaries.

Subscribe via contact form