Security
The Portal is built for a domain (property risk and insurance) where data sensitivity, audit, and grounding correctness are table-stakes. This page describes the controls in production today. The full architecture lives in our internal docs; this is the user-facing summary.
The perimeter
The Portal runs entirely inside a single Google Cloud project
(us-west1 region). No data crosses to other regions
or to public AI services. Every component — the FastAPI service,
Vertex AI Gemini, Vertex AI RAG Engine, Cloud Storage, Cloud
Firestore, Cloud KMS, Cloud Logging — is a Google Cloud managed
service governed by Google's Data Processing Addendum.
Outbound network traffic from the application is restricted to the GCP service endpoints we depend on. There is no path for the application to send your documents to a public LLM API.
Authentication + access
- Sign-in is via Google. Identity-Aware Proxy (IAP) verifies the OIDC token on every request. The application only ever sees authenticated requests.
- Per-corpus access control is enforced server-side on every read and write. Membership lists are stored in Firestore; the application checks the caller's identity against the corpus's members before returning any chunk.
- Admin actions (creating corpora, editing rule plans, adding users) require role-based access (RBAC). Roles are stored in Firestore, gated server-side, and propagated through every route via FastAPI dependencies.
- Cross-user reads return 404, not 403. We deliberately don't leak the existence of resources you can't access.
Encryption
- At rest: source documents in Cloud Storage are encrypted with our customer-managed encryption key (CMEK), software-protection level, 90-day rotation. The KEK is held by Cloud KMS and never leaves it.
- OAuth tokens: refresh tokens for Google Drive, HubSpot, and the CriticalAsset API are envelope-encrypted before Firestore. A per-write AES-256-GCM data-encryption key is generated, used to wrap the secret, then itself wrapped by the KMS-held KEK. Plaintext tokens never persist.
- In transit: TLS 1.2+ on every external connection (the load balancer terminates TLS in front of Cloud Run; intra-GCP traffic is encrypted by Google's network).
- Logs: redactor processor in the structlog chain strips known sensitive field names (password, token, refresh, access_token, secret) before any log entry reaches Cloud Logging.
Data isolation
- Each corpus is namespaced by a stable ID and assigned to one of four Vertex AI RAG Engine shards (hash-based mapping). Retrieval calls assert the shard target server-side; cross-corpus leakage is structurally prevented.
-
Domain-scoped tenancy: corpora carry a
domain_residencyfield tied to the owner's email domain. List queries filter on that field server-side. - Per-user thread storage in Firestore. Cross-user thread reads return 404.
Prompt injection defense
The Portal's grounding contract — answer using only the retrieved
chunks, return UNSUPPORTED if nothing matches — is
the first defense against prompt injection. Documents in your
corpus can't override the system instruction to "ignore prior
instructions" because the model is structurally told to treat
retrieved content as DATA, not INSTRUCTIONS.
Specifically:
-
Source documents are wrapped in
<untrusted_source>tags in the prompt context. - The system instruction declares that content within those tags is data and must not modify behavior.
- Output is schema-constrained to a JSON verdict structure for Report QA flows; freeform outputs (chat) carry a citation list that's validated server-side.
- A post-hoc substring validator rejects any citation whose text doesn't actually appear in the retrieved chunks. If the model tries to hallucinate a citation, the validator catches it before the response ships.
Audit + logging
- Every sign-in, prompt, retrieval, generation, and document action is logged with the user's email, a trace ID, and a structured event name.
- Cloud Logging retention is 30 days for operational logs; a dedicated Cloud Storage logging sink with a Bucket Lock policy provides 7-year retention for audit-relevant events.
- Every connected integration writes its own audit trail (sign-in, token rotation, sync, disconnect) so we can reconstruct the full lifecycle of any credential.
Vulnerability disclosure
Found a security issue? Email security@criticalasset.com with reproduction steps. We'll acknowledge within 2 business days and remediate critical issues within 7. We don't run a paid bug bounty, but we credit responsible disclosures in our internal security log and will work with you on coordinated disclosure timing.
Please don't probe the live Portal beyond what's needed to reproduce. Do not exfiltrate other users' data; do not run automated scanners against production. We will action good-faith research without legal action; we will pursue malicious activity.