Authentication Guide
Satori uses JWT (JSON Web Tokens) for secure API authentication. This guide covers how to create, manage, and use authentication tokens.
Overview
Authentication in Satori follows this flow:
- Get your API token from your Satori administrator
- Use token in the
Authorizationheader for all API requests - Token validation happens automatically on each request
Getting Your API Token
Your API token is provided by your Satori administrator. If you need additional tokens, you can create them using your existing token.
Creating Additional Tokens
If you already have a token, you can create additional tokens:
curl -X POST "https://api.satorivault.com/api/tenants/{tenant_id}/tokens/" \
-H "Authorization: Bearer <EXISTING_JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"name": "Secondary Token",
"expires_at": "2025-06-30T00:00:00Z"
}'
Response:
{
"id": "650e8400-e29b-41d4-a716-446655440000",
"name": "Secondary Token",
"key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"is_active": true,
"expires_at": "2025-06-30T00:00:00Z",
"created_at": "2025-01-15T10:00:00Z"
}
Important: The key field contains your JWT token. Save it immediately - you cannot retrieve it again later.
Using Tokens
Authorization Header
Include the token in every API request:
curl -X GET "https://api.satorivault.com/api/tenants/{tenant_id}/" \
-H "Authorization: Bearer <YOUR_JWT_TOKEN>"
Note: Replace {tenant_id} with your tenant ID and https://api.satorivault.com with your actual API URL.
Python Example
import requests
JWT_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
headers = {
"Authorization": f"Bearer {JWT_TOKEN}",
"Content-Type": "application/json"
}
response = requests.get(
"{api_host}/api/tenants/{tenant_id}/",
headers=headers
)
JavaScript/TypeScript Example
const JWT_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";
const response = await fetch("{api_host}/api/tenants/{tenant_id}/", {
headers: {
Authorization: `Bearer ${JWT_TOKEN}`,
"Content-Type": "application/json",
},
});
Token Management
Listing Tokens
List all tokens for your tenant:
curl -X GET "https://api.satorivault.com/api/tenants/{tenant_id}/tokens/" \
-H "Authorization: Bearer <YOUR_JWT_TOKEN>"
Response:
[
{
"id": "650e8400-e29b-41d4-a716-446655440000",
"name": "Production API Token",
"is_active": true,
"expires_at": "2025-12-31T23:59:59Z",
"last_used": "2025-01-15T14:30:00Z",
"created_at": "2025-01-15T10:00:00Z"
}
]
Note: The actual token key is not returned for security reasons.
Deactivating Tokens
Deactivate a token (instead of deleting):
curl -X PUT "https://api.satorivault.com/api/tenants/{tenant_id}/tokens/{token_id}" \
-H "Authorization: Bearer <YOUR_JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"is_active": false
}'
Token Expiration
Tokens can have optional expiration dates:
{
"name": "Temporary Token",
"expires_at": "2025-06-30T00:00:00Z"
}
- If
expires_atis not provided, the token never expires - Expired tokens cannot be used for authentication
- Check token expiration before making requests
Security Best Practices
✅ DO:
- Store tokens securely: Use environment variables or secret management
- Use different tokens: Separate tokens for different applications or environments
- Set expiration dates: Especially for temporary or test tokens
- Rotate tokens regularly: Create new tokens and deactivate old ones
- Use descriptive names: Make it easy to identify token purpose
- Monitor token usage: Check
last_usedto identify unused tokens
❌ DON'T:
- Commit tokens to version control: Never commit
.envfiles with tokens - Share tokens between team members: Each person should have their own token
- Reuse tokens across applications: Use separate tokens for different apps
- Ignore expiration dates: Check and renew tokens before they expire
Environment Variables
# .env file (never commit this!)
SATORI_JWT_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
SATORI_MASTER_KEY=your-master-key-here
SATORI_BASE_URL={api_host}
import os
from dotenv import load_dotenv
load_dotenv()
JWT_TOKEN = os.getenv("SATORI_JWT_TOKEN")
MASTER_KEY = os.getenv("SATORI_MASTER_KEY")
BASE_URL = os.getenv("SATORI_BASE_URL", "{api_host}")
Error Handling
401 Unauthorized
Token is missing, invalid, or expired:
if response.status_code == 401:
# Token is invalid or expired
# Create a new token or check expiration
raise AuthenticationError("Invalid or expired token")
403 Forbidden
Token is valid but doesn't have access to the requested resource:
if response.status_code == 403:
# Token doesn't have access to this enclave
raise PermissionError("Access denied")
Token Scoping
Tokens are scoped to your tenant:
- All operations using a token are limited to your tenant's data
- Enclaves within your tenant are accessible with your token
- You can create multiple tokens for different purposes (e.g., different applications or environments)
Token Management
Your tokens are managed through the tenant API endpoints. You can:
- Create new tokens for different applications or environments
- List all your tokens
- Deactivate tokens that are no longer needed
- Set expiration dates for temporary tokens
All token management operations require authentication with an existing token.
Token Refresh Strategy
While Satori doesn't provide automatic token refresh, you can implement your own:
class TokenManager:
def __init__(self, base_url, tenant_id, existing_token):
self.base_url = base_url
self.tenant_id = tenant_id
self.existing_token = existing_token
self.token = None
self.token_expires = None
def get_token(self):
if self.token and self.is_token_valid():
return self.token
# Create new token using existing token
response = requests.post(
f"{self.base_url}/api/tenants/{self.tenant_id}/tokens/",
headers={"Authorization": f"Bearer {self.existing_token}"},
json={"name": "Auto-refreshed token"}
)
token_data = response.json()
self.token = token_data["key"]
self.token_expires = token_data.get("expires_at")
return self.token
def is_token_valid(self):
if not self.token_expires:
return True # Never expires
return datetime.now() < datetime.fromisoformat(self.token_expires)
Next Steps
- Best Practices - General usage best practices
- Quick Start - Get started with Satori
- API Reference - Full API documentation