Security
Written to be forwarded to a security reviewer.
Summary
| Question | Answer |
|---|---|
| Where does data live? | Your database and your bucket, in your account |
| Does the vendor see it? | No. There is no vendor-side component |
| Is analysis performed locally? | Yes. Scoring and simulation run in your cluster |
| Does anything leave the network? | Only optional narrative rendering, to OpenAI, under your key |
| Can that be turned off? | Yes. Unset OPENAI_API_KEY |
| Who holds the encryption keys? | You |
| Authentication? | Your OIDC provider, or Google via IAP |
| Is there telemetry? | No |
The one claim worth reading carefully is the third and fourth. See Data flow for exactly what is computed where.
Encryption
Sensitive columns are encrypted before they are written, using envelope encryption. The key-encryption key lives wherever KMS_BACKEND points: in the application secret as APP_KEK, or in AWS KMS, Google Cloud KMS, or Vault.
Searchable sensitive columns carry blind indexes HMACed with INDEX_PEPPER, so equality lookups work without decrypting.
Login tokens are hashed at rest with AUTH_TOKEN_PEPPER.
Details and trade-offs in Encryption.
Licensing has no runtime dependency
The license is an Ed25519-signed token verified locally against a public key in the image. LICENSE_VALIDATION_URL adds optional revocation checks and is blank by default.
With it blank, an outage at the vendor cannot affect your deployment, because there is no call to fail.
Authentication
Four paths, and one of them needs a condition attached. Header-trust authentication through an identity-aware proxy is only safe when the app is reachable only through that proxy. See IAP.
ACCESS_TOKENS is a break-glass mechanism that bypasses your identity provider, your MFA, and your offboarding. Remove it after bootstrap.
Container posture
The chart runs the workload as non-root with a read-only root filesystem, allowPrivilegeEscalation: false, and all capabilities dropped.
podSecurityContext:
runAsNonRoot: true
runAsUser: 10001
fsGroup: 10001
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
Credentials
On GKE, the deployment can run with no static credentials at all: Workload Identity for storage, IAM database auth through the Cloud SQL Auth Proxy for Postgres, and IAP for sign-in.
On EKS, IRSA covers storage. The database still uses a password in DATABASE_URL.
What to check in a review
- Is
APP_KEKbacked up outside the cluster? Its loss is unrecoverable - Is
KMS_BACKENDstillk8s? A real KMS is better - Is
ACCESS_TOKENSstill in the secret after SSO went live? - Is the app reachable by any path that bypasses the proxy, if using IAP?
- Is
LICENSE_ENFORCEMENTstillenforce? - Is
OPENAI_API_KEYset, and does your DPA with OpenAI cover it?
Reporting a vulnerability
Open an issue for anything non-sensitive. For a vulnerability, contact your support channel directly rather than filing publicly.