Credentials
Provider credentials are bring-your-own-key and are resolved only at the execution boundary — never carried through the planner, never written to a manifest, never logged. Authorization and x-api-key headers are redacted in logs.
Planverity API keys are 256-bit random values. Only a SHA-256 hash and a short display prefix are stored, so a key is visible exactly once, at creation. A slow key-derivation function is deliberately not used: those exist because passwords are low-entropy and guessable, and a work factor here would only add latency to every request.
Tenant isolation
Tenancy is derived from the credential and never from the request body. A request naming an organisation it does not belong to is rejected rather than silently ignored.
Isolation is enforced in the query, not the handler: an execution id alone is never enough to read another tenant's manifest. A key from another organisation receives a 404 rather than a 403, so the response does not confirm the record exists.
Row Level Security is enabled with no permissive policies on every table; the anon surface reads nothing.
Immutability
Settled usage records cannot be updated or deleted — a database trigger rejects both. Corrections are adjustment rows, so an original figure stays visible.
Policies, pools and prices are versioned and never edited in place, so what a past execution was permitted to do cannot be retroactively rewritten.
Not yet implemented
Per-key and per-tenant rate limiting. A public gateway is currently protected by key entropy and spend caps alone.
A backend credential service with encrypted storage, rotation and revocation. Provider keys are configured as environment variables today, which is why the beta is BYOK and invite-only.
SSO, SCIM, an administrative kill switch, and a security-event audit log.
Disclosure
Report vulnerabilities to security@planverity.ai. We will acknowledge within two business days. Please do not test against other tenants' data.