Authentication
The Cloud API uses two authentication methods depending on who is making the request.
JWT — User Authentication
Operators, dashboards, and scripts authenticate with a short-lived JWT access token. Tokens are signed with HS256 (symmetric shared secret) or RS256 (RSA public/private key pair) depending on the deployment configuration.
Obtaining a token
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "your-password"
}
Response:
{
"accessToken": "eyJhbGci...",
"refreshToken": "eyJhbGci...",
"expiresIn": 3600
}
Using the token
Include it as a Bearer token on every request:
GET /api/v1/agents
Authorization: Bearer eyJhbGci...
Refreshing
Access tokens expire after expiresIn seconds. Use the refresh token to get a new pair without re-entering credentials:
POST /api/v1/auth/refresh
Content-Type: application/json
{
"refreshToken": "eyJhbGci..."
}
Device API Keys — Agent Authentication
Each provisioned agent authenticates with a long-lived API key. Keys are generated during provisioning and stored in the database. They do not expire but can be revoked.
The API key is used in two places:
- MQTT connection — the agent uses the API key as the MQTT username when connecting to the broker. The Mosquitto broker validates it via the Cloud API's
mosquitto-authplugin before accepting the connection. - HTTP requests — passed in the
X-Device-API-Keyheader for control-plane calls such as polling target state.
Using an API key (HTTP)
GET /api/v1/device/:uuid/state
X-Device-API-Key: iotsk_live_abc123...
Using an API key (MQTT)
The agent connects to the MQTT broker with:
host: <broker host>
port: 1883 (or 8883 for TLS)
username: iotsk_live_abc123... ← API key as MQTT username
password: <provisioned password> ← separate MQTT password from provisioning
clientId: agent-{uuid}
On connect, the broker calls back to the Cloud API to validate credentials before allowing the session.
Generating a key manually
POST /api/v1/auth/api-keys
Authorization: Bearer <admin-jwt>
Content-Type: application/json
{
"name": "factory-gateway-01",
"agentUuid": "550e8400-e29b-41d4-a716-446655440000"
}
Provisioning Flow
New devices receive their API key through a one-time provisioning key:
1. Operator creates a provisioning key
POST /api/v1/provision/keys
→ { "key": "prov_abc123", "expiresAt": "..." }
2. Key is passed to the device (env var, install script, QR code)
3. Agent calls self-registration with the key
POST /api/v1/provision/agent
{ "key": "prov_abc123", "agentName": "gateway-01" }
→ { "apiKey": "iotsk_live_xyz...", "agentUuid": "..." }
4. Agent stores the API key and uses it for all future requests
The provisioning key is single-use and deleted after registration.
License Validation
The API validates a signed license JWT on startup. The license controls:
| Feature | Controlled by license |
|---|---|
| Device limit | Max number of registered agents |
| Advanced anomaly | Multi-metric correlation rules |
| Data export | CSV / Parquet export endpoints |
| AI features | Chat and dashboard suggestions |
A missing or expired license puts the API in restricted mode — existing devices continue to report, but new registrations and premium features are blocked.
Environment Variables
# JWT signing (choose one)
JWT_SECRET=your-hs256-secret
# or
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n..."
JWT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n..."
# License
LICENSE_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n..."
LICENSE_KEY=eyJhbGci... # signed by Iotistica