EdgeQuake Python SDK - Authentication Guide
February 12, 2026 · View on GitHub
Complete guide to authentication methods supported by the EdgeQuake Python SDK.
Table of Contents
- Authentication Methods
- API Key Authentication
- JWT Token Authentication
- Multi-Tenant Authentication
- Security Best Practices
Authentication Methods
EdgeQuake supports three primary authentication methods:
- API Key — Simple key-based authentication (recommended for server-to-server)
- JWT Tokens — Login with email/password, receive tokens (recommended for user-facing apps)
- Multi-Tenant — Workspace/tenant scoped authentication
API Key Authentication
API key authentication is the simplest method, ideal for server-to-server communication and automation.
Basic Usage
from edgequake import EdgequakeClient
# Method 1: Environment variable (recommended)
import os
client = EdgequakeClient(
api_key=os.environ.get("EDGEQUAKE_API_KEY")
)
# Method 2: Explicit parameter (not recommended for production)
client = EdgequakeClient(
api_key="your-api-key-here"
)
Environment Variable
Set the API key in your environment:
export EDGEQUAKE_API_KEY="sk-your-api-key-here"
python your_script.py
Or use a .env file:
# .env
EDGEQUAKE_API_KEY=sk-your-api-key-here
Then load it:
from dotenv import load_dotenv
load_dotenv()
from edgequake import EdgequakeClient
client = EdgequakeClient() # Reads from environment
How It Works
The SDK adds the API key to the Authorization header:
GET /health HTTP/1.1
Host: localhost:8080
Authorization: Bearer sk-your-api-key-here
Obtaining an API Key
API keys are typically issued by the EdgeQuake server administrator:
# Example: Generate API key via CLI
edgequake-cli api-keys create --name "Production Server"
# Output: sk-proj-abc123def456...
Or via the admin API:
# Admin client
admin = EdgequakeClient(api_key="admin-key")
# Create new API key
key = admin.api_keys.create(name="Production", scopes=["read", "write"])
print(key["key"]) # sk-proj-...
JWT Token Authentication
JWT (JSON Web Token) authentication is ideal for user-facing applications where users log in with credentials.
Login Flow
from edgequake import EdgequakeClient
# Step 1: Create client without authentication
client = EdgequakeClient()
# Step 2: Login with email/password
auth_response = client.auth.login(
email="user@example.com",
password="SecurePassword123!"
)
print(auth_response)
# {
# "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
# "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
# "token_type": "Bearer",
# "expires_in": 3600
# }
# Step 3: Create authenticated client
authenticated_client = EdgequakeClient(
api_key=auth_response["access_token"]
)
# Now use the authenticated client
docs = authenticated_client.documents.list()
Token Refresh
JWTs expire after a set period (typically 1 hour). Use the refresh token to get a new access token:
# Before access token expires
new_auth = client.auth.refresh(
refresh_token=auth_response["refresh_token"]
)
# Update client with new token
authenticated_client = EdgequakeClient(
api_key=new_auth["access_token"]
)
Automatic Token Refresh (Advanced)
import time
from edgequake import EdgequakeClient
from edgequake.exceptions import UnauthorizedError
class AutoRefreshClient:
def __init__(self, email, password):
self.email = email
self.password = password
self._login()
def _login(self):
temp_client = EdgequakeClient()
auth = temp_client.auth.login(self.email, self.password)
self.access_token = auth["access_token"]
self.refresh_token = auth["refresh_token"]
self.expires_at = time.time() + auth["expires_in"]
self.client = EdgequakeClient(api_key=self.access_token)
def _ensure_fresh_token(self):
# Refresh 5 minutes before expiry
if time.time() > self.expires_at - 300:
temp_client = EdgequakeClient()
auth = temp_client.auth.refresh(self.refresh_token)
self.access_token = auth["access_token"]
self.refresh_token = auth.get("refresh_token", self.refresh_token)
self.expires_at = time.time() + auth["expires_in"]
self.client = EdgequakeClient(api_key=self.access_token)
def __getattr__(self, name):
self._ensure_fresh_token()
return getattr(self.client, name)
# Use auto-refreshing client
client = AutoRefreshClient("user@example.com", "password")
docs = client.documents.list() # Auto-refreshes if needed
Multi-Tenant Authentication
Multi-tenant authentication adds workspace and tenant context to every request.
Workspace Context
from edgequake import EdgequakeClient
# Client scoped to a workspace
client = EdgequakeClient(
api_key="your-api-key",
workspace_id="workspace-123"
)
# All operations are scoped to this workspace
docs = client.documents.list() # Only returns docs in workspace-123
Tenant + Workspace Context
# Full multi-tenant setup
client = EdgequakeClient(
api_key="your-api-key",
tenant_id="tenant-456",
workspace_id="workspace-123"
)
# All operations scoped to tenant-456, workspace-123
doc = client.documents.upload(
content="Tenant-specific document",
title="Scoped Doc"
)
How It Works
The SDK adds headers to every request:
POST /documents HTTP/1.1
Host: localhost:8080
Authorization: Bearer your-api-key
X-Tenant-Id: tenant-456
X-Workspace-Id: workspace-123
Content-Type: application/json
{"content": "...", "title": "..."}
Switching Workspaces
# Production workspace
prod_client = EdgequakeClient(
api_key="api-key",
workspace_id="prod-workspace"
)
prod_docs = prod_client.documents.list()
# Development workspace
dev_client = EdgequakeClient(
api_key="api-key",
workspace_id="dev-workspace"
)
dev_docs = dev_client.documents.list()
Security Best Practices
1. Never Hardcode Credentials
❌ Bad:
client = EdgequakeClient(api_key="sk-proj-abc123...")
✅ Good:
import os
client = EdgequakeClient(api_key=os.environ.get("EDGEQUAKE_API_KEY"))
2. Use Environment Variables
Store secrets in environment variables, not source code:
# .bashrc or .zshrc
export EDGEQUAKE_API_KEY="sk-..."
# Or use .env file (never commit it!)
# .gitignore should include:
.env
3. Rotate API Keys Regularly
# Rotate keys every 90 days
admin = EdgequakeClient(api_key="admin-key")
# Revoke old key
admin.api_keys.revoke("old-key-id")
# Create new key
new_key = admin.api_keys.create(name="Q1-2025")
print(new_key["key"]) # Update your .env
4. Limit Key Scopes
Create API keys with minimal required permissions:
# Read-only key for analytics
analytics_key = admin.api_keys.create(
name="Analytics",
scopes=["read"]
)
# Full access for automation
automation_key = admin.api_keys.create(
name="Automation",
scopes=["read", "write", "admin"]
)
5. Use HTTPS in Production
❌ Bad (development only):
client = EdgequakeClient(base_url="http://api.example.com")
✅ Good (production):
client = EdgequakeClient(base_url="https://api.example.com")
6. Handle Expired Tokens Gracefully
from edgequake.exceptions import UnauthorizedError
try:
docs = client.documents.list()
except UnauthorizedError:
# Token expired or invalid
# Option 1: Refresh token
new_auth = client.auth.refresh(refresh_token)
client = EdgequakeClient(api_key=new_auth["access_token"])
# Option 2: Re-login
auth = client.auth.login(email, password)
client = EdgequakeClient(api_key=auth["access_token"])
7. Secure Token Storage
For client-side apps (not recommended for sensitive data):
import keyring
# Store token in OS keyring (macOS Keychain, Windows Credential Manager, etc.)
keyring.set_password("edgequake", "access_token", auth["access_token"])
# Retrieve later
access_token = keyring.get_password("edgequake", "access_token")
client = EdgequakeClient(api_key=access_token)
8. Audit API Key Usage
# Monitor API key usage
admin = EdgequakeClient(api_key="admin-key")
# List all keys
keys = admin.api_keys.list()
for key in keys.get("items", []):
print(f"{key['name']}: Last used {key['last_used_at']}")
# Revoke unused keys
if key["last_used_at"] is None:
admin.api_keys.revoke(key["id"])
Troubleshooting
Unauthorized Errors (401)
Problem: HTTP 401: Unauthorized
Solutions:
- Check API key is set:
echo $EDGEQUAKE_API_KEY - Verify key hasn't been revoked
- Ensure key has required scopes
- Check JWT token hasn't expired
Forbidden Errors (403)
Problem: HTTP 403: Forbidden
Solutions:
- Verify API key has required permissions
- Check workspace/tenant context is correct
- Ensure user has access to resource
Token Expiration
Problem: Token expires during long-running operations
Solution: Use refresh token proactively:
import time
def query_with_refresh(client, auth_response):
start_time = time.time()
# Refresh 5 minutes before expiry
if time.time() - start_time > auth_response["expires_in"] - 300:
new_auth = client.auth.refresh(auth_response["refresh_token"])
client = EdgequakeClient(api_key=new_auth["access_token"])
auth_response = new_auth
return client.query.execute(query="...")
See Also
- API Reference:
API.md - Streaming Guide:
STREAMING.md - Examples:
examples/multi_tenant.py