Authentication Guide
Authentication Guide
Single Bearer Token for All API Access
Overview
HeliosDB Nano 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-nano --token-expiry 900 # 15 minutes3. Use HTTPS in Production
# Always use TLS./heliosdb-nano --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