Docs/API & Webhooks/Authentication & Scopes

Authentication & Scopes

Every public API request must carry a long-lived API key as a bearer token. Scopes constrain what each key is allowed to do — grant only what your integration actually needs.

Bearer token format

API keys look like this:

scs_live_t9JQ10cDjddmslzv9mRKYqaDS5ZU1KuDH

The prefix scs_live_ identifies the key as a production credential for SecureCodingHub. Tokens are 41 characters total (9-character prefix + 32-character random body). They are returned exactly once when the key is created.

Send the token on every request as a standard Bearer authentication header:

Authorization: Bearer scs_live_t9JQ10cDjddmslzv9mRKYqaDS5ZU1KuDH

Creating an API key

API keys are created in the admin console — not through the API.

1

Sign in to app.securecodinghub.com as an organization admin.

2

Open Organization → API Keys from the sidebar.

3

Click + Create new key. Give the key a descriptive name (e.g. GitHub Actions — CI or Looker BI sync).

4

Tick only the scopes the integration needs. Read-only scopes are highlighted in blue, write scopes in amber.

5

(Optional) Set an expiry date. Keys without an expiry stay valid until you revoke them.

6

Click Create key. The full token is shown in a modal. Copy it to your secrets manager now. You will not be able to retrieve it again — only the prefix and the last four characters are stored.

Scope reference

SecureCodingHub uses 16 fine-grained scopes split into read and write tiers. A request that hits an endpoint without the matching scope returns 403 Forbidden with the response body {"error":"insufficient_scope","required":"…","present":[…]}.

ScopeResourceTierGrants
org:readOrganizationReadRead organization metadata (name, plan, seats).
users:readUsersReadList users; get user detail.
users:writeUsersWriteCreate, update, deactivate users.
teams:readTeamsReadList teams and members.
teams:writeTeamsWriteCreate, update, delete teams.
assignments:readAssignmentsReadList assignments; get detail with completion.
assignments:writeAssignmentsWriteCreate, update, deactivate assignments.
custom-courses:readCustom CoursesReadList custom courses with items.
custom-courses:writeCustom CoursesWriteCreate, update, delete custom courses.
progress:readProgressReadPractice and learn progress per user.
certificates:readCertificatesReadList and download certificates.
audit-log:readAudit LogReadList audit log entries.
compliance:readComplianceReadCompliance dashboard data.
content:readContentReadTopics, scenarios, CWE-to-topic mapping.
sarif:ingestSARIFWriteIngest SARIF runs and auto-assign training.
webhook:manageWebhooksWriteManage outbound webhook endpoints.

Recommended scope sets

Use caseMinimum scopes
CI/CD SARIF ingestionsarif:ingest
HR-driven user provisioningusers:write, teams:write
BI / reporting exportusers:read, progress:read, assignments:read, audit-log:read
Ticketing & SOAR (event subscribers)webhook:manage, assignments:read
Auditor read-only exportorg:read, audit-log:read, compliance:read, certificates:read

Rotation & revocation

To rotate a key, create a replacement first, deploy the new token, then revoke the old one in Organization → API Keys. Revocation takes effect immediately — in-flight requests using the old token will start returning 401 Unauthorized within seconds.

If a key is leaked, revoke it. There is no "pause" state; revocation is permanent. The token cannot be re-enabled.

Storage best practice

  • Treat the token like a database password. Never commit it to source control.
  • Prefer your platform's native secret store (AWS Secrets Manager, GCP Secret Manager, GitHub Actions secrets, Vault, 1Password Connect).
  • In CI, inject the token only at the step that needs it; avoid echoing it.
  • Issue one key per integration so you can revoke independently. Don't share a single key across CI, BI, and SOAR.
  • Set an expiry on tokens created for short-lived integrations (proofs of concept, vendor evaluations).

Common errors

StatusResponseMeaning
401{"error":"unauthorized"}Missing, malformed, revoked, or expired token.
403{"error":"insufficient_scope",…}Token is valid but lacks the required scope for this endpoint.
429{"error":"rate_limited"}Per-minute or per-hour cap reached. See Rate Limits.