Authentication
How to authenticate to the SigSentry API — the three-prefix key model, surface-routing rules, and the X-Project-Id header
Every request to the SigSentry API authenticates with an API key
in the Authorization header. SigSentry uses three explicit key
types — one for SDK / browser use, two for server-side use — each
with a distinct prefix and scope.
The Authorization header
Authorization: Bearer ss_secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx| Element | Notes |
|---|---|
| Scheme | Bearer |
| Value | The full key including one of the three prefixes below |
Missing or malformed authorization returns 401 Unauthorized.
The three key types
| Prefix | Type | Scope | Created from |
|---|---|---|---|
ss_pub_* | Public | Project (immutable) | Project → SDK Keys |
ss_secret_* | Secret | Project (immutable) | Project → API Keys |
ss_org_* | Secret | Organization (tenant-wide) | Organization → API Keys |
The prefix is structural — it determines key type, scope, and which endpoints the key is allowed to call. The auth middleware short-circuits on prefix; no DB lookup is needed to decide what's permitted.
ss_pub_* — public, SDK-safe
- Permission set is platform-locked to
analysis:createandanalysis:read. A customer cannot grantconfig:read,config:write, or any other permission to a public key — the dashboard form has no picker, and the API rejects elevation attempts with400 INVALID_PUBLIC_KEY_PERMISSIONS. - Always project-scoped. Project binding is set at creation and cannot be changed.
- Safe to ship in browsers, mobile apps, and
<script>embeds.
ss_secret_* — server, project-scoped
- Any permission combination from the full permission list.
- Always project-scoped —
projectIdrequired at creation. - Cannot escape its project: a request that targets a different
project returns
403 WRONG_PROJECT.
ss_org_* — server, tenant-scoped
- Any permission combination.
- Tenant-scoped — works against any project in the organization, required for tenant-only endpoints (project create/list, org-wide usage rollup).
- For project-scoped endpoints, send the project anchor via
X-Project-Id. Without it, the API returns400 MISSING_PROJECT_ID.
Surface-level routing rules
| Surface | Accepts | Rejects with |
|---|---|---|
| SDK | ss_pub_* only | ss_secret_* / ss_org_* → 403 PUBLIC_KEY_REQUIRED |
| Public REST API — project-scoped endpoints | ss_secret_* (implicit project from binding) or ss_org_* + X-Project-Id | ss_pub_* → 403 SECRET_KEY_REQUIRED |
| Public REST API — tenant-only endpoints | ss_org_* only | ss_pub_* / ss_secret_* → 403 ORG_KEY_REQUIRED |
Project anchoring
Every request needs a scope anchor — a "current project" or "this whole org". The anchor is resolved in this order:
X-Project-Idheader — set this when sending anss_org_*key targeting a specific project.- Key's project binding —
ss_pub_*andss_secret_*always carry one; the binding is immutable. - URL path — endpoints like
GET /v1/projects/{id}carry the anchor in the path itself. - Tenant-only operation — endpoints with no project anchor
require
ss_org_*.
Authorization: Bearer ss_org_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-Project-Id: 6f1c89bb-3b50-4c4a-9c5f-2d0e8f1a3b21Permissions
A key carries a permission list, separate from a user's role. Each endpoint requires one or more permissions:
| Permission | Grants |
|---|---|
analysis:create | Create analyses, ask follow-ups, generate postmortems |
analysis:read | List analyses, fetch by id, view similar incidents |
config:read | Read project, channel, log source, repo, watchdog config |
config:write | Create/update/delete config resources (log sources, repos, channels, watchdog rules, projects) |
To mint or revoke keys, sign in to the dashboard — see API Keys for the three creation flows.
A key without the required permission returns 403 FORBIDDEN.
See API Keys → Permissions for the complete mapping.
Errors specific to authentication
| HTTP | error.code | When |
|---|---|---|
| 401 | UNAUTHORIZED | Missing, malformed, or unknown key |
| 401 | API_KEY_REVOKED | Key was revoked |
| 401 | API_KEY_EXPIRED | Key passed its expiration date |
| 401 | KEY_FORMAT_DEPRECATED | Legacy tb_* / ss_live_* key after sunset window |
| 403 | FORBIDDEN | Key lacks the permission for this endpoint |
| 403 | PUBLIC_KEY_REQUIRED | An ss_secret_* or ss_org_* key was used with the SDK |
| 403 | SECRET_KEY_REQUIRED | An ss_pub_* key was used on a server-only endpoint |
| 403 | ORG_KEY_REQUIRED | A project-scoped key was used on a tenant-only endpoint |
| 403 | WRONG_PROJECT | A project-scoped key targeted a different project |
| 403 | DASHBOARD_ONLY | This action lives in the dashboard — sign in to the web app |
| 400 | MISSING_PROJECT_ID | ss_org_* key without X-Project-Id on a project-scoped endpoint |
Legacy key migration
Customers with existing tb_* (legacy Traceback prefix) or ss_live_*
keys continue to work during a 6-month sunset window. The dashboard
shows a migration banner on each API Keys page when legacy keys are
detected — rotate at your convenience. After the sunset window, legacy
prefixes return 401 KEY_FORMAT_DEPRECATED with rotation instructions.
Best practices
Never ship an ss_secret_* or ss_org_* key in client-side code.
Anything visible in a browser, mobile app, or compiled binary is
exposed. The SigSentry SDK enforces this by throwing at construction
time if you pass a non-ss_pub_* key. Use a public key with the SDK,
and a server proxy with a secret key for anything beyond running
analyses.
- Store keys in environment variables or a secret manager.
- Rotate by creating a new key, switching your app, then revoking the old one.
- Scope keys to the smallest type and permission set that works —
prefer
ss_secret_*overss_org_*when one project is enough. - Use a separate key per environment (production, staging, CI).
- Never commit keys to source control — even private repos can leak.
