BugBoardDocs

Authentication

Every request to POST /api/v1/tasks must be authenticated with a project API key. BugBoard supports two schemes — bearer (publishable keys) and HMAC signatures (secret keys) — chosen by your key type. For help deciding, see Choosing a key type.

Authentication proves who is reporting. To also keep the report body unreadable in transit — in the browser network tab, at proxies, and in logs — see Encrypted Transport, which uses a separate project encryption key.

Publishable keys (bearer)

Send the key as a bearer token:

Authorization: Bearer bb_pub_<48 hex chars>

Publishable keys are write-only and scoped to a single project. They're meant to be embedded in client code, so secrecy is not what protects them — the origin allow-list and your monthly quota are.

Secret keys (HMAC signature)

The secret is never sent. Instead, each request carries three headers computed from the signing secret:

X-Bb-Key-Id: bbk_<id>
X-Bb-Timestamp: <unix seconds>
X-Bb-Signature: <hex HMAC-SHA256>

Signing algorithm

sign(method, path, body, signingSecret, keyId):
    timestamp = current unix time in SECONDS, as a string
    payload   = timestamp + "." + UPPERCASE(method) + "." + path + "." + sha256_hex(body)
    signature = hmac_sha256_hex(key = signingSecret, message = payload)
    return headers:
        X-Bb-Key-Id    = keyId
        X-Bb-Timestamp = timestamp
        X-Bb-Signature = signature
  • path is the request path with its leading slash and no query string — for ingestion always /api/v1/tasks.
  • body is the exact raw bytes you transmit. Re-serialising the JSON (different key order or whitespace) breaks the signature — sign the same bytes you send.
  • timestamp is integer Unix seconds sent as digits only — a millisecond value (JavaScript's Date.now()) is rejected, so divide by 1000 first.
  • Both sha256_hex(body) and the final signature are lowercase hex. The server compares them exactly, so uppercase hex or base64 will not match.
  • The server rejects any timestamp more than ±300 seconds from its clock (replay protection). A bad signature is a hard 401 with no Retry-After.

The server SDKs implement this for you; the full reference is in the API Reference.

Origin allow-list (publishable keys only)

A publishable key may carry a list of allowed origins. When the list is non-empty, the server only accepts requests whose Origin (falling back to Referer) matches an entry; an empty list accepts any origin. Entries may be a full origin (https://app.example.com) or a bare host (app.example.com), and a mobile identifier in the X-Bb-App-Id header is matched too.

This is a junk filter, not a security wall. A real browser can't forge Origin, so it blocks other sites from using your key — but a script can send any Origin. The real cap on a leaked key is the quota.

Getting and rotating keys

  1. Open your project → Settings → API Keys (requires the manageApiKey ability).
  2. Create key, choose Publishable or Secret, name it, and for publishable keys optionally add allowed origins.
  3. Copy the shown value(s) immediately — BugBoard stores only a hash.
  4. Revoke any key at will (password-confirmed). Revocation is immediate and per-key, so you can rotate a leaked key without breaking other integrations.

Errors

Authentication failures return JSON:

Status Meaning
401 Missing/invalid key, bad signature, or expired timestamp
403 Publishable key used from a disallowed origin

See Error Codes for the full list.