SOC 2 — readiness work in progress, not yet attested
Engineering practices are built and documented against the SOC 2 Trust Services Criteria for security, availability, and confidentiality, and we maintain a control-by-control readiness tracker against them. To be precise about where that stands: no auditor has been engaged yet, no observation window has opened, and blankit holds no SOC 2 attestation — Type I or Type II. Engaging an independent CPA firm is the next step. If procurement needs evidence before an audit exists, ask for the current readiness summary and we will share it, including what is still open.
Encryption in transit and at rest
HTTPS-only at the application load balancer (TLS 1.2 or higher). RDS storage is encrypted with KMS-managed keys. S3 buckets enforce server-side encryption (AES-256) and block all public access at the account-resource level. Secrets stored in AWS Secrets Manager — never in source.
Authenticated session model
Two distinct session systems — one for advisors and firm admins (JWT cookie with short TTL), one for plan-member portal users (hashed bearer tokens). Cross-session access is impossible by design — portal users cannot read advisor data, and vice versa.
Each firm has its own database, its own bucket, and its own encryption key
Firm-owned data is not rows in a shared table separated by a filter. Every advisor firm is provisioned its own PostgreSQL database, its own S3 bucket, and its own KMS key; a firm’s connection cannot address another firm’s database at all, so a cross-firm read is not something the application declines to do — it is something it has no route to attempt. Control-plane records (billing, the firm directory) live in a separate catalog database that holds no client data. This is a fixed property of the platform rather than a tier: there is no plan on which firms share a database.
Query-layer tenant scoping, as the second line
Inside a firm’s own database every model holding firm-owned data is still firmId-scoped, with the data-access layer injecting the tenant filter at the query layer — so a coding mistake in a route handler cannot cross a boundary even within one tenant. A short, explicit allow-list covers the pre-authentication lookups where the credential itself resolves the firm (sign-in, API tokens); a schema-consistency test fails the build if any other model carrying a firmId escapes scoping. Scripts are audited the same way, by walking the import graph rather than grepping for a helper name.
Two-factor and passkey authentication
Mandatory for every administrator account — an admin without a second factor cannot reach the product until they enrol one, and cannot later remove their last one. Any firm can additionally require it of every member. Advisors can use TOTP, email OTP, or a WebAuthn passkey — and a verified passkey also enables passwordless, phishing-resistant sign-in on its own. TOTP secrets are encrypted at rest with an AES-GCM key held separately from the database; passkey public keys are not secret and are stored unencrypted.
Tamper-evident audit log on every privileged action
Every advisor action that touches personal information or runs a privileged operation is recorded — who, what, when, from where. Logs are retained for seven years and are immutable from the application surface. Entries are also chained: each one stores a SHA-256 over its own fields plus the hash of the entry before it, per firm, so altering a recorded field, deleting an entry, or reordering history breaks the chain arithmetically and is detectable on verification. Entries written before the chain existed carry no hash and are reported as uncovered rather than counted as protected.