Separated at the database, not by a query
The controls a security review asks about, described precisely enough that you can check them — and honest about what is not in place yet.
- Schema-per-tenant
- OIDC SSO
- Full audit trail
- Signed webhooks
How workspaces are separated
A schema per workspace
Every organization gets its own PostgreSQL schema. Separation is enforced by the database, not by a WHERE clause somebody has to remember to add to every query.
Encrypted in transit and at rest
TLS on every connection. Stored credentials — webhook signing secrets, the SSO client secret — are encrypted with a key held outside the database.
SSO via OIDC
Configurable per workspace, so account lifecycle stays with your identity provider and offboarding someone there offboards them here.
Guest isolation by construction
A guest sees exactly the projects they were added to. There is no fallback path, so their isolation never depends on an admin having remembered to mark something private.
How secrets are handled
Two different jobs, two different treatments — and the distinction is deliberate.
API tokens are hashed, not stored
Only a SHA-256 hash and an 8-character prefix are kept. A database leak does not leak working tokens, because the original value never exists on our side after creation.
Leaked tokens are revoked automatically
Tokens carry a fixed krm_live_ marker registered with GitHub secret scanning. A token pushed to a public repository is reported to us and revoked.
Tokens are not people
A token authenticates a service account with its own role and its own scopes — so it cannot inherit a promotion, and offboarding a human cannot break production.
Default deny on the API
The public surface is an allowlist. A path that is not on it refuses every token regardless of scopes, and token management itself is absent from it entirely.
A webhook signing secret is a credential we present on every delivery, so it has to be reversible and is encrypted. An API token is a credential we verify, so it is hashed and never recoverable. Treating both the same way would weaken one of them.
Outgoing requests are guarded
An outgoing webhook is, by design, a way for a customer to make our servers issue an HTTP request — so every endpoint URL is validated when it is saved and again on every delivery attempt, against every address the hostname resolves to rather than only the first.
Non-HTTPS URLs, loopback, private (RFC1918) and link-local addresses — including the cloud metadata address — are refused. Checking twice is what closes DNS rebinding, where a name is safe at save time and hostile at send time.
Auditing
Every write records who made it, when, from which IP, with which user agent and under which request id. Writes made through the API are attributed to the service account that made them rather than to whichever person created the token — so the audit log never claims a human did something a script did.
Rate limiting and abuse
API traffic is limited per token and per organization, and both limits are reported back on every response so a client can back off on the one that is actually binding. Refused requests are metered too, which stops rapid-fire rejections being used to probe what exists.
Reporting a vulnerability
Write to security@krrim.com with enough detail to reproduce the issue. We acknowledge within two business days, and we will not pursue legal action against researchers acting in good faith. Please give us a reasonable window to fix an issue before disclosing it publicly.
What we do not claim
Krrim does not currently hold SOC 2 or ISO 27001 certification, and we do not publish penetration test reports or run a bug bounty programme. We would rather say so here than let you find out during procurement. If a certification is a requirement for you, tell us — it helps us prioritise.
Working through a security review?
Send us the questionnaire. We answer them ourselves rather than routing them to a form.