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_t9JQ10cDjddmslzv9mRKYqaDS5ZU1KuDHThe 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_t9JQ10cDjddmslzv9mRKYqaDS5ZU1KuDHCreating an API key
API keys are created in the admin console — not through the API.
Sign in to app.securecodinghub.com as an organization admin.
Open Organization → API Keys from the sidebar.
Click + Create new key. Give the key a descriptive name (e.g. GitHub Actions — CI or Looker BI sync).
Tick only the scopes the integration needs. Read-only scopes are highlighted in blue, write scopes in amber.
(Optional) Set an expiry date. Keys without an expiry stay valid until you revoke them.
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":[…]}.
| Scope | Resource | Tier | Grants |
|---|---|---|---|
org:read | Organization | Read | Read organization metadata (name, plan, seats). |
users:read | Users | Read | List users; get user detail. |
users:write | Users | Write | Create, update, deactivate users. |
teams:read | Teams | Read | List teams and members. |
teams:write | Teams | Write | Create, update, delete teams. |
assignments:read | Assignments | Read | List assignments; get detail with completion. |
assignments:write | Assignments | Write | Create, update, deactivate assignments. |
custom-courses:read | Custom Courses | Read | List custom courses with items. |
custom-courses:write | Custom Courses | Write | Create, update, delete custom courses. |
progress:read | Progress | Read | Practice and learn progress per user. |
certificates:read | Certificates | Read | List and download certificates. |
audit-log:read | Audit Log | Read | List audit log entries. |
compliance:read | Compliance | Read | Compliance dashboard data. |
content:read | Content | Read | Topics, scenarios, CWE-to-topic mapping. |
sarif:ingest | SARIF | Write | Ingest SARIF runs and auto-assign training. |
webhook:manage | Webhooks | Write | Manage outbound webhook endpoints. |
Recommended scope sets
| Use case | Minimum scopes |
|---|---|
| CI/CD SARIF ingestion | sarif:ingest |
| HR-driven user provisioning | users:write, teams:write |
| BI / reporting export | users:read, progress:read, assignments:read, audit-log:read |
| Ticketing & SOAR (event subscribers) | webhook:manage, assignments:read |
| Auditor read-only export | org: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
| Status | Response | Meaning |
|---|---|---|
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. |