What the code enforces
Each statement below describes behavior that exists in the product today.
Workspaces are isolated by row-level rules
Every table carries an explicit row-level access rule, and signed-in queries and mutations run through it. A table added without a rule fails the build.
Test traffic is fenced from your data
Rows written by a conformance key carry a fence tag. Console sessions never see them, and verdicts on them are answered only through the conformance key's own API door.
API keys are stored as a hash
A key looks like blr_<org>_<id>.<secret>. Only a SHA-256 hash of the secret is stored, it is compared in constant time, and key listings never return it.
Keys carry only what their tier allows
Service keys and person keys draw from a capability table. A person key is further limited to what its owner's role allows, and only a person key can commit a judgment.
One guard for every verdict
A verdict can arrive from the API, the console or Slack. All three pass the same check: the answerer must be a verified person who holds the capability that decision needs.
Outgoing webhooks are signed
Each delivery carries an HMAC-SHA256 signature over the timestamp and the raw body, so a receiver can verify who sent it and that it was not altered.
Incoming webhooks are verified
GitHub, Slack and Linear webhooks are checked against their signature with a constant-time comparison before anything is read from them.
Webhook targets cannot reach your network
A webhook URL that resolves to a private, loopback or link-local address is refused, and the connection is pinned to the address that was checked, so a second DNS answer cannot redirect it.
Webhook deliveries keep no bodies
A delivery record holds its status, attempt count, status code and a short error. It does not store the request or the response body.
Events expire after 90 days
Events and their webhook delivery records are deleted 90 days after they are written, by a scheduled sweep.
Text from outside is data, not instructions
Captured signals and pull request comments are handed to agents as data to classify, with a standing rule not to follow instructions inside them. Procedure text an agent writes is shown to reviewers as untrusted.
Every key is rate limited
The API admits each request through a per-key token bucket sized by tier, and answers an exhausted bucket with a retry time.
Conversation transcripts are pruned
Seven days after a session ends, its messages and working context are deleted daily. The session record and its outcome are kept.