Reference → API Keys — Reference

API Keys — Reference

The API Keys surface is the platform's token-management plane. It owns the lifecycle of every credential that an external system uses to call into SGEN — creation, scope assignment, last-used tracking, rotation, and revocation. Any integration that authenticates against SGEN's programmatic surface traces back to a record managed here.

This page is a reference for platform engineers and integrators who need to understand the surface before extending it, scripting against it, or scoping a credential model. Customer-facing how-tos live in the customer docs set; this page describes the shape of the surface, not the steps to drive it.


Overview

API Keys live under the Settings → Developer module in SG-Admin. The module renders three primary views — the key list, the key create form, and the key detail view — and exposes a small set of write operations for create, scope edit, rotate, revoke, and permanent delete.

The module is paired by convention: one half renders the views and prepares the data, the other half handles writes and returns AJAX responses. Engineers reading the source will see this split across two controller files; the reference below describes the combined surface as it appears to a calling integration.

A second surface — scope catalog — lives adjacent to the API Keys module under Settings → Roles. Scopes are defined there; the API Keys module references them by slug. A new scope shows up automatically in the create form once it has been added to the catalog.

Where it lives in SG-Admin:

  • Sidebar: SG-Admin → Settings → Developer → API Keys
  • URL prefix: /sg-admin/api-keys/
  • View templates: application/views/Admin/ApiKeys/
The module surface is intentionally small. Heavier authorization concerns (per-endpoint rate limits, per-IP allowlists, OAuth client registration) live in adjacent surfaces (Integrations, Permissions) — this page covers only the bearer-token CRUD plane.
┌────────────────────────────────────────────────────────────────────────────┐│ SG-Admin → Settings → Developer → API Keys [+ New key] │├────────────────────────────────────────────────────────────────────────────┤│ Label Scope Last used Status ││ ────────────────── ─────────────── ─────────────── ────────────────────││ Zapier integration read:content 2 min ago active ││ CI publish bot write:posts 14 min ago active ││ Legacy mobile app read:content 32 days ago active ││ Old import script admin:full never revoked ││ Vendor sync read:orders yesterday rotating ││ ││ [⋯ Detail] [⋯ Rotate] [⋯ Revoke] │└────────────────────────────────────────────────────────────────────────────┘

Actions

The API Keys surface exposes the following operations. Each is described by what it does to the data, not by its internal method name.

List and filter

Returns the keys visible to the current operator, paginated, with label / scope / last-used / status columns. Supports column sort, free-text filter across label, and scope-based filter. The list view never exposes the secret value of a key — only its label, prefix, and metadata.

Create key

Opens an empty create form. Required fields: label, scope set, expiry preference (never / 30 / 90 / 365 days). Optional fields cover description, IP allowlist, and per-environment tag (production / staging / sandbox). On submit, the surface generates a fresh secret, persists the hashed form of it, and returns the plaintext secret exactly once — in the success response. The plaintext is never re-shown.

Engineering note — the one-shot reveal is a hard property of the surface. A second GET on the same key returns metadata only, with the secret field omitted. Integrations that lose the plaintext must rotate, not re-fetch.

View key detail

Loads the metadata for a single key: label, scope set, expiry, IP allowlist, environment tag, created-by operator, last-used timestamp, last-used IP, and the action vocabulary the key has invoked (derived from Activity Log). The plaintext secret is not part of the response.

Edit scope

A focused write path. Accepts a new scope set for an existing key, validates that every requested scope exists in the catalog, and rewrites the binding. The secret value is unchanged; only the bound scope set updates. Takes effect on the next authenticated call — there is no cache to flush.

Rotate

Generates a fresh secret for an existing key while keeping the label, scope, and IP allowlist intact. The new plaintext is returned exactly once in the rotate response. The old secret transitions to a grace state where it continues to authenticate for a configurable overlap window (default 24 hours), then hard-revokes. Used when a secret leaks or when periodic rotation policy fires.

Revoke

Marks a key inactive. The secret stops authenticating immediately — no grace window. The record stays in the database for audit purposes; subsequent calls return a structured rejection naming the revoked state. Revoke is reversible up to permanent delete via the Restore entry on the key detail view.

Permanent delete

Hard-removes a revoked key. Available only after a revoke. This path is irreversible and is intentionally separated from revoke so that the audit trail survives operator panic.

Inspect last-used

A read-only diagnostic. Returns the last-used timestamp, the last-used IP, the last-used action slug, and a recent-activity tail (last 25 calls). Used during incident review when the question is "is this key in use?" before a planned revoke.


Data model

An API key record carries the following fields. Field names below are the conceptual shape — the on-disk column names match closely but are not contractually stable across releases.

FieldTypeNotes
idintegerPrimary key. Stable across rotations.
labelstringOperator-set display name. Not unique.
prefixstringFirst 8 characters of the secret. Shown in lists for visual matching against logs.
secret_hashstringSalted hash of the full secret. Never exposed in any read response.
scopearrayList of scope slugs. Validated against the Settings → Roles catalog.
statusenumactive, rotating, revoked, expired.
expires_attimestampNull if "never".
ip_allowlistarrayOptional. CIDR ranges. Empty = no IP restriction.
environmentenumproduction, staging, sandbox. Cosmetic — does not change auth behavior.
created_byintegerUser id of the operator who issued the key.
last_used_attimestampTouched on every successful auth. Null until first use.
last_used_ipstringSource IP of the most recent successful auth.
grace_untiltimestampDuring rotation, the old secret remains valid until this time.
created_attimestampSet on create, immutable.
updated_attimestampTouched on any edit.
One-shot plaintext. The plaintext secret exists in the response of create and rotate and nowhere else. The database stores only the salted hash.

Rotation overlap. During a rotation, both the old and the new secrets authenticate. The old secret carries grace_until; the new secret is unmarked. After the overlap window, the old secret hard-revokes.

Scope expansion. A scope set is additive. A key with read:content and write:posts can do both. Adding a new scope requires Edit scope; removing requires the same.

API KEY RECORD├── id integer primary key├── label string operator-set├── prefix string first 8 chars of secret (lookup aid)├── secret_hash string salted hash, never returned├── scope array e.g. ['read:content', 'write:posts']├── status enum active | rotating | revoked | expired├── expires_at timestamp null = never├── ip_allowlist array CIDR ranges, empty = unrestricted├── environment enum production | staging | sandbox├── created_by integer issuing operator user.id├── last_used_at timestamp touched on auth success├── last_used_ip string source IP of last auth├── grace_until timestamp during rotation only└── timestamps created_at, updated_at↓ on rotateNEW SECRET ISSUED (returned once)OLD SECRET → status=rotating, grace_until=now+overlap↓ after overlap windowOLD SECRET → status=revoked

Permissions

Access to the API Keys surface is gated at two layers.

Layer 1 — admin gate. Every action under SG-Admin passes through the platform's standard admin access check at request entry. An unauthenticated request never reaches the API Keys surface.

Layer 2 — per-action capability. Within SG-Admin, each API Keys action checks a capability associated with the calling operator's role. The default role configuration ships with three roles — Administrator, Editor, Viewer — and the capability map is:

CapabilityAdministratorEditorViewer
List keys
View key detail
Create key
Edit scope
Rotate
Revoke
Permanent delete
Inspect last-used
View own keys (self-issued)
Custom roles defined under Settings → Roles override the default map. The capability slugs are stable; the role slugs are configurable.

Self-protection rules. An operator cannot create a key with a scope they themselves do not hold. The surface returns a structured rejection naming the missing capability. An operator cannot revoke a key in a different environment from the one they are signed into when environment isolation is enabled under Settings → Security.

Audit. Every write — create, edit scope, rotate, revoke, permanent delete — emits an Activity Log entry. The log records the acting operator, the key identifier (label + prefix, never the secret), and the change shape. Reads of the key list and detail are not logged; calls authenticated by the key itself are logged with source = api.

REQUEST│▼┌───────────────────────────┐│ Admin gate │ unauth → reject│ (every /sg-admin/* call) │└─────────────┬─────────────┘│ authed▼┌───────────────────────────┐│ Capability check │ role lacks cap → reject│ (per-action) │ (custom roles override defaults)└─────────────┬─────────────┘│ allowed▼┌───────────────────────────┐│ Scope-floor rule │ requested scope exceeds│ (create / edit scope) │ operator's own → reject└─────────────┬─────────────┘│ passes▼action executes│▼Activity Log entry(label + prefix only, never secret)

Related references

  • Settings — Reference. Owns the scope catalog, the rotation overlap window, the environment isolation flag, and the IP allowlist defaults. Changes there reshape what API Keys can request.
  • Roles — Reference. Defines the scope slugs that this surface binds against. New scopes added under Roles flow automatically into the API Keys create form.
  • Permissions — Reference. Per-endpoint capability mapping. API Keys carry scopes; scopes resolve to capabilities at request time.
  • Integrations — Reference. Pre-built integrations (Zapier, webhooks, OAuth clients) provision their own API keys through this surface but may layer additional metadata.
  • Activity Log — Reference. Source of last-used data, source of the rotation / revoke audit trail. Every key write emits an entry; every authenticated call emits an entry with source = api.
  • Users — Reference. A key's created_by references a user record. Soft-deleting the issuing user does not revoke their keys — a separate cleanup workflow handles that under Settings → Security.
For the corresponding customer-facing walkthrough — issuing a key, scoping it for a vendor, rotating before a launch — see the API Keys section of the customer docs at /docs/api-keys.
On this page