---
title: "JWT Authentication Quick Reference"
---

# JWT Authentication Quick Reference

Every route under `/v1` (and `/api/v1`) of the HeliosDB-Lite REST API requires a JSON
Web Token. The server verifies tokens with the shared secret in `HELIOSDB_JWT_SECRET`;
your application or identity service signs them with the same secret.

## Quick Start

### 1. Start the Server with a Secret

```bash
export HELIOSDB_JWT_SECRET="$(openssl rand -hex 32)"
heliosdb-lite start --data-dir ./mydb
```

The server refuses to start when `HELIOSDB_JWT_SECRET` is unset or empty.

### 2. Sign a Token

Tokens use HS256 and must carry the issuer `heliosdb-api` and the audience
`heliosdb-client`. Example with Python and PyJWT:

```python
import os, time, uuid
import jwt  # pip install PyJWT

now = int(time.time())
token = jwt.encode(
    {
        "sub": "app_rw",                 # user (SQL role) the request runs as
        "tenant_id": "default",
        "client_id": str(uuid.uuid4()),
        "iat": now,
        "nbf": now,
        "exp": now + 3600,               # 1 hour
        "jti": str(uuid.uuid4()),
        "iss": "heliosdb-api",
        "aud": "heliosdb-client",
        "scopes": [],
    },
    os.environ["HELIOSDB_JWT_SECRET"],
    algorithm="HS256",
)
```

### 3. Call the API

```bash
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8080/v1/branches
```

## Token Claims

| Claim | Type | Meaning |
|-------|------|---------|
| `sub` | string | User the request is executed as |
| `tenant_id` | string | Tenant identifier |
| `client_id` | UUID | Client identifier |
| `exp` | Unix time | Expiry; expired tokens are rejected |
| `nbf` | Unix time | Not valid before |
| `iat` | Unix time | Issued at |
| `jti` | string | Unique token ID |
| `iss` | string | Must be `heliosdb-api` |
| `aud` | string | Must be `heliosdb-client` |
| `scopes` | string list | Permissions; `admin` lets a caller cancel other users' queries |

Requests run as the `sub` user, so `GRANT` and row-level security apply to REST calls.

## Security Checklist

- [ ] Use a strong random secret (32 bytes or more)
- [ ] Keep the secret in a secret manager or an environment file readable only by the service
- [ ] Serve the API over TLS (for example behind a reverse proxy)
- [ ] Keep token lifetimes short (1 hour is a good default)
- [ ] Never log tokens
- [ ] Monitor authentication failures

## Troubleshooting

| Error | Cause | Solution |
|-------|-------|----------|
| 401 on every request | Token signed with a different secret | Sign with the server's `HELIOSDB_JWT_SECRET` |
| 401 after a while | Token expired | Issue a new token |
| 401 with a fresh token | Wrong `iss`, `aud` or algorithm | Use HS256, `heliosdb-api`, `heliosdb-client` |
| Server does not start | `HELIOSDB_JWT_SECRET` unset | Export the secret before `heliosdb-lite start` |

API-key authentication and a token-issuing endpoint are planned.

## Next Steps

- [REST API Tutorial](/docs/lite/guides/tutorials/rest_api_tutorial/)
- [Security Hardening](/docs/lite/guides/security_hardening/)
