Authentication Guide
Authentication Guide
Single Bearer Token for All API Access
Overview
HeliosDB-Lite uses JWT Bearer tokens for authentication. One token grants access to all API endpoints based on your permissions.
┌─────────────────────────────────────────────────────────┐│ Your Application ││ │ ││ Authorization: ││ Bearer <token> ││ │ ││ ▼ ││ ┌───────────┐ ┌───────────┐ ┌───────────────────┐ ││ │ REST API │ │ SQL Query │ │ Schema Generation │ ││ │ /rest │ │ /query │ │ /schema │ ││ └───────────┘ └───────────┘ └───────────────────┘ │└─────────────────────────────────────────────────────────┘Quick Start: Get Your Token
1. Sign Up / Sign In
# Create account (if auth enabled)curl -X POST http://localhost:6543/auth/v1/signup \ -H "Content-Type: application/json" \ -d '{ "email": "developer@example.com", "password": "secure-password-123" }'
# Sign in to get tokencurl -X POST http://localhost:6543/auth/v1/token \ -H "Content-Type: application/json" \ -d '{ "email": "developer@example.com", "password": "secure-password-123" }'2. Response
{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTEyMyIsImV4cCI6MTcwMjY0MDAwMH0.abc123", "token_type": "bearer", "expires_in": 3600, "refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."}3. Use Token in All Requests
# Set token as environment variableexport HELIOS_TOKEN="eyJhbGciOiJIUzI1NiIs..."
# Use in any API callcurl -X POST http://localhost:6543/api/v1/query \ -H "Authorization: Bearer $HELIOS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"sql": "SELECT * FROM users"}'Token Lifecycle
Token Structure
Header.Payload.Signature │ │ │ │ │ └─── HMAC-SHA256 signature │ └──────────── User ID, expiry, scopes └──────────────────── Algorithm (HS256)Decoded Payload:
{ "sub": "user-abc-123", "email": "developer@example.com", "role": "authenticated", "tenant_id": "tenant-xyz", "exp": 1702640000, "iat": 1702636400, "scopes": ["read", "write", "admin"]}Token Expiry
| Token Type | Default Expiry | Configurable |
|---|---|---|
| Access Token | 1 hour | Yes |
| Refresh Token | 7 days | Yes |
Refresh Token
# Refresh before expirycurl -X POST http://localhost:6543/auth/v1/token?grant_type=refresh_token \ -H "Content-Type: application/json" \ -d '{ "refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..." }'Response:
{ "access_token": "eyJhbGciOiJIUzI1NiIs...<new-token>", "token_type": "bearer", "expires_in": 3600}Authentication Methods
Method 1: Bearer Token (Recommended)
curl -X GET http://localhost:6543/api/v1/query \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."Method 2: API Key Header
curl -X GET http://localhost:6543/api/v1/query \ -H "X-API-Key: your-api-key-here"Method 3: Query Parameter (Not Recommended)
# Only for testing - tokens visible in logscurl "http://localhost:6543/api/v1/query?apikey=your-api-key"SDK Examples
Python
import requests
class HeliosDBClient: def __init__(self, base_url: str, email: str, password: str): self.base_url = base_url self.token = None self.refresh_token = None self._login(email, password)
def _login(self, email: str, password: str): response = requests.post( f"{self.base_url}/auth/v1/token", json={"email": email, "password": password} ) data = response.json() self.token = data["access_token"] self.refresh_token = data["refresh_token"]
def _headers(self): return { "Authorization": f"Bearer {self.token}", "Content-Type": "application/json" }
def query(self, sql: str): response = requests.post( f"{self.base_url}/api/v1/query", headers=self._headers(), json={"sql": sql} ) return response.json()
def refresh(self): response = requests.post( f"{self.base_url}/auth/v1/token?grant_type=refresh_token", json={"refresh_token": self.refresh_token} ) data = response.json() self.token = data["access_token"]
# Usageclient = HeliosDBClient( "http://localhost:6543", "dev@example.com", "password123")
users = client.query("SELECT * FROM users")print(users)JavaScript/TypeScript
class HeliosDBClient { private baseUrl: string; private token: string | null = null; private refreshToken: string | null = null;
constructor(baseUrl: string) { this.baseUrl = baseUrl; }
async login(email: string, password: string): Promise<void> { const response = await fetch(`${this.baseUrl}/auth/v1/token`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }) }); const data = await response.json(); this.token = data.access_token; this.refreshToken = data.refresh_token; }
async query(sql: string): Promise<any> { const response = await fetch(`${this.baseUrl}/api/v1/query`, { method: "POST", headers: { "Authorization": `Bearer ${this.token}`, "Content-Type": "application/json" }, body: JSON.stringify({ sql }) }); return response.json(); }
async refresh(): Promise<void> { const response = await fetch( `${this.baseUrl}/auth/v1/token?grant_type=refresh_token`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ refresh_token: this.refreshToken }) } ); const data = await response.json(); this.token = data.access_token; }}
// Usageconst client = new HeliosDBClient("http://localhost:6543");await client.login("dev@example.com", "password123");const users = await client.query("SELECT * FROM users");cURL Script
#!/bin/bash
BASE_URL="http://localhost:6543"EMAIL="dev@example.com"PASSWORD="password123"
# Login and extract tokenlogin() { TOKEN=$(curl -s -X POST "$BASE_URL/auth/v1/token" \ -H "Content-Type: application/json" \ -d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\"}" \ | jq -r '.access_token') echo "Token: ${TOKEN:0:20}..."}
# Query with tokenquery() { curl -s -X POST "$BASE_URL/api/v1/query" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "{\"sql\":\"$1\"}"}
# Usageloginquery "SELECT * FROM users LIMIT 5"Multi-Tenant Authentication
When using multi-tenancy, tokens include tenant context:
Token with Tenant ID
{ "sub": "user-123", "tenant_id": "acme-corp", "role": "authenticated", "exp": 1702640000}Automatic RLS Enforcement
All queries are automatically filtered by tenant:
-- User querySELECT * FROM orders;
-- Internally rewritten to:SELECT * FROM orders WHERE tenant_id = 'acme-corp';Cross-Tenant Access (Admin Only)
# Admin token with cross-tenant scopecurl -X POST http://localhost:6543/api/v1/query \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "X-Tenant-ID: acme-corp" \ -d '{"sql": "SELECT * FROM orders"}'Security Best Practices
1. Store Tokens Securely
// DO: Use secure storagelocalStorage.setItem("helios_token", token); // Browser onlyprocess.env.HELIOS_TOKEN = token; // Server only
// DON'T: Log tokensconsole.log(token); // Never!2. Set Short Expiry
# Server config./heliosdb-lite --token-expiry 900 # 15 minutes3. Use HTTPS in Production
# Always use TLS./heliosdb-lite --mode server \ --tls-cert /path/to/cert.pem \ --tls-key /path/to/key.pem4. Implement Token Refresh
// Auto-refresh before expirysetInterval(async () => { const decoded = jwt_decode(token); const expiresIn = decoded.exp * 1000 - Date.now();
if (expiresIn < 300000) { // 5 minutes await client.refresh(); }}, 60000); // Check every minute5. Revoke on Sign Out
# Invalidate token on logoutcurl -X POST http://localhost:6543/auth/v1/logout \ -H "Authorization: Bearer $TOKEN"Troubleshooting
”Token Expired"
# Error{"error": "token_expired", "message": "Token has expired"}
# Solution: Refresh tokencurl -X POST http://localhost:6543/auth/v1/token?grant_type=refresh_token \ -d '{"refresh_token": "..."}'"Invalid Token"
# Error{"error": "invalid_token", "message": "Token is invalid"}
# Solution: Re-authenticatecurl -X POST http://localhost:6543/auth/v1/token \ -d '{"email": "...", "password": "..."}'"Unauthorized”
# Error{"error": "unauthorized", "message": "Missing authorization header"}
# Solution: Include Bearer tokencurl -H "Authorization: Bearer $TOKEN" ...API Reference
| Endpoint | Method | Description |
|---|---|---|
/auth/v1/signup | POST | Create new account |
/auth/v1/token | POST | Get access token |
/auth/v1/token?grant_type=refresh_token | POST | Refresh token |
/auth/v1/logout | POST | Invalidate token |
/auth/v1/user | GET | Get current user info |
Next: Schema Generation | API Reference