Encryption in Transit¶
Statement¶
ClaimGuard's encryption-in-transit story is strong on the back-of-house and weak on the front door, and is documented honestly on this page so prospects and auditors can read both halves:
- Strong: every outbound flow from the application — to GCP control-plane services, to GCS, to the Gemini API, to operator- configured webhooks — uses TLS with system-trust-store certificate validation. Internal traffic between the Node backend and the Python tools never leaves the VM.
- Weak: public user-facing traffic to the application's API currently terminates on a non-TLS port (3001) on the VM's public IP. Closing that gap is plan step A1.3 (HTTPS Load Balancer + Google-managed certificate). Until A1.3 lands, this control is partial and the gap is the reason.
Implementation¶
What's TLS today¶
| Flow | Direction | TLS posture |
|---|---|---|
| GCP control plane (Secret Manager, Cloud Logging, Compute, GCS) | Outbound from VM | TLS, Google-issued certificates, validated against system trust store |
Google Gemini API (gemini-2.5-pro) |
Outbound from VM (master_tool) | TLS, system trust store. See AI transparency. |
Operator webhooks (SUPPORT_WEBHOOK_URL) |
Outbound from Node backend | Wrapped by safeFetch (server/src/lib/safeFetch.js). Enforces TLS for https:// URLs, blocks private/link-local/CGNAT ranges, refuses redirects by default. See SAST. |
| Internal: Node ↔ Python tools (master_tool, c2pa, layover, etc.) | Loopback (127.0.0.1) on the VM |
Not TLS — same-host, never leaves the VM. Documented as a deliberate design choice in docs/security/PROTOCOL.md §4. |
| Internal: Node ↔ Postgres | Loopback on the VM | Same as above — same-host. Postgres listens on local socket; no external network exposure. |
What's not TLS today¶
- Public user-facing application traffic. Browsers connect to
the API at
http://<public-ip>:3001/...without TLS. The HTTP-only gap is in scope for plan step A1.3 (HTTPS LB + Google-managed cert). Mitigated only by the fact that the product is not yet in customer hands.
This is the single open gap on this page.
How A1.3 closes the gap¶
The plan-A1.3 shape:
- A GCP global external Application Load Balancer in front of the
VM with a static IP and a hostname (likely
app.dtectvision.ai). - A Google-managed TLS certificate attached to the LB; renewal is Google-operated.
- A backend zonal NEG that points at the VM on the application's
port. Health check on
/health. - A firewall rule (
allow-lb-health) restricted to GCP's LB source ranges (130.211.0.0/22,35.191.0.0/16). - After cutover, plan step A1.2 closes the world-open
application port directly (
tcp:3001); only the LB-internal hop reaches it.
When A1.3 lands, this page flips to implemented and the
Cryptography page's "Public user-facing
TLS — planned" line is removed.
TLS versions and ciphers¶
- GCP-managed certificates on the eventual LB will use Google's default modern TLS profile (TLS 1.2+, modern cipher set, perfect forward secrecy).
- System-trust-store outbound uses Node.js / Python defaults, which require TLS 1.2+ and reject weak ciphers.
Certificate management¶
- Inbound (planned): Google-managed certificate on the LB, auto-renewed; no certificate handling in our codebase or operator procedures.
- Outbound: the system trust store on the VM is the source of truth; we do not pin a certificate or maintain a custom root list.
Status¶
partial — verified 2026-04-29.
What's in place:
- TLS for every outbound flow (GCP, Gemini, operator webhooks).
safeFetchenforces TLS for outboundhttps://URLs.- Internal traffic stays on loopback — no plaintext network hop between the Node backend, the Python tools, and Postgres.
Known gaps¶
- Public user-facing TLS — not yet in place. Plan step A1.3. Single most-cross-listed gap on the trust portal — referenced from Cryptography and Network architecture as well.
Roadmap¶
- A1.3 — HTTPS Load Balancer + Google-managed certificate. Single closing step.
- HTTP → HTTPS redirect at the LB once the cert is
ACTIVE. - HSTS header on the application response post-cutover.
/.well-known/security.txtat the application root once the LB is the front door (cross-listed on Vulnerability disclosure).