Authentication
Every ScaiGrid request (except /health and /metrics) must authenticate. Two methods are supported.
API keys#
API keys are the right choice for server-to-server integration — your backend calls ScaiGrid.
Format: sgk_ followed by 32+ random characters (e.g., sgk_a8f3e2...).
Lifetime: Never expire by default. Can be revoked individually.
Scope: Belong to a single user within a single tenant. Inherit that user's permissions.
Creating an API key#
From the admin UI: Access → API Keys → Create. You see the full key exactly once — copy it immediately. The database stores only a SHA-256 hash.
Via the API:
1 2 3 4 | |
Using an API key#
Include it in the Authorization header:
1 | |
1 2 | |
1 2 3 4 | |
1 2 | |
Revoking an API key#
1 2 | |
Once revoked, the key is permanently invalid — including any in-flight requests using it.
Rate limits#
API keys have independent rate limits (configurable per tenant). Hitting the limit returns 429 RATE_LIMITED with a Retry-After header. See Rate Limiting.
ScaiKey JWTs#
JWTs are the right choice for human users interacting with ScaiGrid — the admin UI, user-facing dashboards, tools where individual users log in via SSO.
Issuer: ScaiKey (your identity provider).
Format: Standard JWT, signed RS256.
Lifetime: Short (typically 1 hour). Refreshed via /v1/auth/refresh.
Scope: Identifies the user and their tenant. Permissions resolved from the user's roles at request time.
Obtaining a JWT#
ScaiKey issues JWTs through an OAuth 2.0 authorization code flow with PKCE. The admin UI handles this automatically. For your own user-facing app, the flow is:
POST /v1/auth/identifywith the user's email → returns available tenantsPOST /v1/auth/authorizewith tenant + PKCE code challenge → returns an OAuth URL- User completes SSO at ScaiKey → redirected back with authorization code
POST /v1/auth/tokenwith the code → returns access + refresh tokens
See Authentication Reference for the complete flow.
Using a JWT#
Same Authorization header as API keys:
1 | |
Refreshing a JWT#
1 2 3 | |
Response contains a new access token. Your client should refresh proactively before expiration, or reactively on 401 AUTH_TOKEN_EXPIRED.
Which should I use?#
| Situation | Use |
|---|---|
| Backend service calling ScaiGrid | API key |
| CI/CD pipeline, cron job, batch processor | API key |
| Personal scripts, quick experiments | API key |
| Admin UI or user-facing dashboard | JWT (via ScaiKey login) |
| MCP integration for a user's own tools | JWT |
| Shared key across a team | Avoid — create one API key per service, per environment |
Rule of thumb: if a human is in the loop, JWT. If it's automation, API key.
What if I need both?#
Common case: a backend service calls ScaiGrid on behalf of end users, and you want the requests accounted per end user, not per service.
Two patterns work:
- Service-to-service JWT. The backend uses its own JWT (obtained via client credentials through ScaiKey) and passes the user identity in a custom header that your tenant's usage pipeline aggregates.
- Per-user API keys. Each end user gets their own API key, and the backend proxies requests using the user's key. Simpler but requires storing user keys.
Pattern 1 is cleaner for SaaS platforms. Pattern 2 is simpler for internal tooling.
Security notes#
- Never put API keys in client-side code. A JavaScript bundle in a browser leaks the key to anyone who opens DevTools. Always proxy through your backend.
- Rotate keys regularly. At minimum on personnel changes. Consider quarterly rotation for production integrations.
- Use one key per service, per environment. Easier to revoke surgically without disrupting unrelated systems.
- Enable audit logging. See Audit Log. Every authenticated mutation is recorded.
- Monitor for unusual usage. Spikes in a single API key's activity are the earliest signal of a leak.
What's next#
- Your First Integration — complete walk-through including error handling.
- Roles and Permissions — what permissions do, how they're resolved.
- Authentication Reference — full OAuth flow and endpoint details.