API authentication
Workspace API keys and JWT login for the public HTTP API.
Lunnoa Automate exposes its REST API (Swagger at /docs) to two kinds of callers:
- Machines: server-side applications authenticating with a workspace-scoped API key (
lna_…). - Humans: end users authenticating with a JWT from password login (
POST /api/auth/login), token exchange (POST /api/auth/login-with-token), or SSO under/api/auth/sso/….
Both converge on the same authorisation model: RBAC permissions evaluated per workspace. There are no separate partner API endpoints.
For a typed SDK surface (login, 2FA, refresh, SSO discovery, token stores), see Client authentication.
API keys are service accounts
An API key is a credential for a machine service account: a user of type SERVICE_ACCOUNT that
- has no password and can never log in interactively,
- is a member of exactly one workspace, chosen when the key is created,
- holds a normal RBAC role (system or custom),
- is excluded from SCIM and from people-facing user lists,
- can never hold the
SUPER_ADMINplatform role;/api/admin/*endpoints remain JWT-only.
Every action performed with the key is attributed to the service account in audit trails.
Creating a key (SuperAdmin)
Open Admin Space
Go to Admin Space → API Keys (
/adminspace/api-keys).Create the key
Choose a name, the target workspace, an RBAC role with the minimum permission set, and an optional expiry.
Copy the secret once
Copy the
lna_…secret from the confirmation screen. It is shown exactly once; only its sha256 hash is stored.
Using a key
Send the secret as a bearer token:
/api/workflowsExample authenticated list call
Requires a bearer token (API key or JWT). Outside the role's permissions returns 403; revoked or unknown keys return 401.
Two supported patterns
| Pattern | Who authenticates | When to use |
|---|---|---|
| A. Backend holds the key | The custom app's server, as the service account | Background jobs, data sync, server-rendered pages |
| B. End users are Lunnoa users | Each end user via JWT / SSO | Per-user shares, permissions, and task history |
Auth is Bearer JWT (JSON bodies for login/refresh). There is no session-cookie login for the public API, and no server logout route: clients clear stored tokens locally.
Primary routes for Pattern B:
| Method | Path | Purpose |
|---|---|---|
POST | /api/auth/login | Email + password (may require 2FA) |
POST | /api/auth/2fa/verify-login | Complete 2FA |
POST | /api/auth/login-with-token | Exchange SSO / email hidden JWT |
POST | /api/auth/refresh-token | New access token from refresh token |
GET | /api/auth/sso/providers | Public SSO discovery |
GET | /api/auth/sso/:providerId/login | Start OIDC redirect |
GET | /api/users/me | Current user (Bearer required) |
SSO callbacks redirect to {CLIENT_URL}/verify-token?token=…, then the client calls login-with-token.
Security notes
- Only the sha256 hash of a key is stored; treat the plaintext like any other production secret.
- A leaked key exposes at most one workspace, bounded by the service account's role.
- Rotate by creating a new key, switching the application, then revoking the old one.
- Set
API_KEYS_ENABLED=falseto reject alllna_tokens (fail closed) without affecting human JWT logins.
# .env — enabled by default
API_KEYS_ENABLED=trueFull reference
Browse every public operation on the API reference, or open Swagger at /docs on your deployment to try calls interactively.