Skip to content

Authentication

Login

POST /api/auth/login
Content-Type: application/json

{
  "username": "admin",
  "password": "secret"
}

Response:

{
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "user": {
      "id": 1,
      "username": "admin",
      "is_superuser": true
    },
    "requires_2fa": false
  }
}

If requires_2fa: true, submit the TOTP code:

POST /api/auth/login
{
  "username": "admin",
  "password": "secret",
  "totp_code": "123456"
}

Bearer Token

All protected endpoints require the Authorization header:

curl -H "Authorization: Bearer <token>" \
     https://<server>:2087/api/webapps

Token Lifetime

JWT tokens have a configurable lifetime (default: 24 hours). The token is signed with the JWT_SECRET from starkone.env.

Verify Token

GET /api/auth/verify
Authorization: Bearer <token>

Returns { "data": { "valid": true } } or 401.

Current User

GET /api/auth/me
Authorization: Bearer <token>

Returns the authenticated user's profile and permissions.

API Keys

API keys provide long-lived programmatic access:

# Create an API key
POST /api/users/:uid/api-keys
{ "name": "deploy-script" }

# Response
{
  "data": {
    "id": 1,
    "name": "deploy-script",
    "key": "sk_live_abcdef...",
    "created_at": "2024-01-15T10:00:00Z"
  }
}

Use the API key as a Bearer token:

curl -H "Authorization: Bearer sk_live_abcdef..." \
     https://<server>:2087/api/webapps

API keys do not expire and are not affected by JWT secret rotation.

401 Behaviour

When authentication fails, the API returns:

{
  "error": {
    "code": "unauthorized",
    "message": "token is expired"
  }
}

HTTP status: 401 Unauthorized.