Belora
Security

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.