Secret values are wrapped in a type whose serializers refuse to print them. Converting one to a string, to JSON, or logging it to a console yields [redacted], so redaction survives the paths where a developer forgets. Reading the value is an explicit call, and it is the only way through.
Traffic is TLS in transit and envelope-encrypted at rest, with least-privilege roles between the app and the control planes. SOC 2 is in progress, and compliance commitments are negotiated per contract on Enterprise.
A report is evidence that somebody independent checked. Until ours exists, here is what you can check yourself — each of these is a property of how the product is built, not a policy document, and several are enforced by the database or the test suite rather than by us remembering:
- Logical access
- Row-level security is FORCED on tenant tables and bound per transaction, so a query with no org context returns nothing.
- Integrity of the log
- Only SELECT and INSERT policies exist on the audit table. UPDATE and DELETE are denied to us as well as to you.
- Key management
- One data key per value, wrapped by KMS, with the key id recorded per version — so a rotation is provable rather than asserted.
- Boundary protection
- Outbound requests are range-checked inside the socket's own DNS lookup and never follow a redirect.
- Vendor management
- The subprocessor register is public and names which one holds plaintext in memory.
- Secret handling
- Values are wrapped in a type whose serializers print [redacted]; revealing one is an explicit call.
None of that is a substitute for an audit, and we are not going to present it as one. It is what an evaluation can stand on while the report is outstanding — and if your procurement gate is the report itself, the honest answer is that we do not have it yet.
The subprocessor register lists every third party in the path and exactly what each one can access, including the one that holds plaintext in memory because it runs the decrypt path.