π Authentication SystemΒΆ
π― OverviewΒΆ
The Authentication System provides secure API access through API Keys, enabling programmatic interaction with Continuum's services. It supports role-based access control, key expiration, and application-specific authentication.
π PurposeΒΆ
The Authentication System enables: - API Key Management: Generate, revoke, and manage API keys - Role-Based Access: API keys inherit permissions from assigned roles - Application Isolation: Keys are specific to each application - Expiration Control: Set expiration times for security - Secure Token Generation: Cryptographically secure key generation
ποΈ ArchitectureΒΆ
graph TB
Request[API Request]
subgraph "Authentication Flow"
AuthHeader{Authorization<br/>Header?}
KeyValidator[API Key Validator]
TokenVerifier[Token Verifier]
RoleResolver[Role Resolver]
end
subgraph "Key Management"
KeyGenerator[Key Generator]
KeyStorage[(Key Storage)]
KeyRotation[Key Rotation]
end
subgraph "Access Control"
PermissionCheck{Has Permission?}
ACL[ACL System]
ResourceAccess[Resource Access]
end
Request --> AuthHeader
AuthHeader -->|Yes| KeyValidator
AuthHeader -->|No| Reject[401 Unauthorized]
KeyValidator --> TokenVerifier
TokenVerifier -->|Valid| RoleResolver
TokenVerifier -->|Invalid| Reject
RoleResolver --> PermissionCheck
PermissionCheck -->|Yes| ResourceAccess
PermissionCheck -->|No| Forbidden[403 Forbidden]
KeyGenerator --> KeyStorage
KeyStorage --> KeyValidator
KeyRotation --> KeyStorage
RoleResolver --> ACL
ACL --> PermissionCheck
classDef auth fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
classDef mgmt fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef acl fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef error fill:#ffebee,stroke:#c62828,stroke-width:2px
class AuthHeader,KeyValidator,TokenVerifier,RoleResolver auth
class KeyGenerator,KeyStorage,KeyRotation mgmt
class PermissionCheck,ACL,ResourceAccess acl
class Reject,Forbidden error π API KeysΒΆ
π What are API Keys?ΒΆ
API Keys are secure tokens that authenticate API requests without requiring user credentials. They: - Are long, cryptographically random strings - Are tied to a specific role (which defines permissions) - Are application-specific - Can have expiration dates - Are stored hashed in the database
π― Key PropertiesΒΆ
| Property | Description | Example |
|---|---|---|
| Token | The actual API key string | eyJhbGc... |
| Role | Associated role name | admin, editor |
| Application | Which app the key belongs to | main, marketing-app |
| Expires In | Expiration duration | 7d, 30d, never |
| Created At | Key creation timestamp | 2025-01-15T10:00:00Z |
| Last Used | Last usage timestamp | 2025-01-20T14:30:00Z |
π οΈ API Key ManagementΒΆ
β Create API KeyΒΆ
Using the UI: 1. Navigate to Settings β Plugins β API Keys 2. Click "Add API Key" 3. Select a role (defines permissions) 4. Set expiration time (optional) 5. Click "Save" 6. Copy the key immediately (shown only once)
Using the API:
POST /api/apiKeys:create
Authorization: Bearer {existing-user-token}
X-App: main
Content-Type: application/json
{
"role": {
"name": "admin"
},
"expiresIn": "30d"
}
Response:
{
"data": {
"id": 5,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
"role": "admin",
"expiresAt": "2025-02-14T10:00:00.000Z",
"createdAt": "2025-01-15T10:00:00.000Z"
}
}
β οΈ Important: Save the token immediately - it cannot be retrieved again for security reasons.
π List API KeysΒΆ
Response:
{
"data": [
{
"id": 1,
"name": "Production API Key",
"role": "admin",
"expiresAt": "2025-12-31T23:59:59.000Z",
"createdAt": "2025-01-01T00:00:00.000Z",
"lastUsedAt": "2025-01-20T14:30:00.000Z"
},
{
"id": 2,
"name": "Development Key",
"role": "developer",
"expiresAt": null,
"createdAt": "2025-01-10T08:00:00.000Z",
"lastUsedAt": "2025-01-20T12:15:00.000Z"
}
]
}
Note: The actual token is never returned in list operations for security.
ποΈ Revoke API KeyΒΆ
This immediately invalidates the API key. All subsequent requests with that key will fail.
π Rotate API KeyΒΆ
Best practice: Periodically rotate API keys for security.
# Create new key
POST /api/apiKeys:create
X-App: main
{
"role": {"name": "admin"},
"expiresIn": "30d"
}
# Update applications to use new key
# Verify new key works
# Delete old key
POST /api/apiKeys:destroy?filterByTk={old-key-id}
X-App: main
π§ Using API KeysΒΆ
π‘ Making Authenticated RequestsΒΆ
Include the API key in the Authorization header:
curl 'https://continuum.example.com/api/articles:list' \
-H 'Authorization: Bearer {your-api-key}' \
-H 'X-App: main'
π Application-Specific KeysΒΆ
API keys are specific to the application they were created in:
# Create key for main application
POST /api/apiKeys:create
Authorization: Bearer {user-token}
X-App: main
{
"role": {"name": "admin"}
}
# Create key for sub-application
POST /api/apiKeys:create
Authorization: Bearer {user-token}
X-App: marketing-platform
{
"role": {"name": "editor"}
}
Important: Keys from main app cannot access marketing-platform and vice versa.
π Example RequestsΒΆ
List Records:
Create Record:
POST /api/products:create
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
X-App: main
Content-Type: application/json
{
"name": "Laptop",
"price": 999.99
}
Update Record:
POST /api/products:update?filterByTk=1
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
X-App: main
Content-Type: application/json
{
"price": 899.99
}
β° Expiration ManagementΒΆ
π Expiration FormatsΒΆ
When creating API keys, you can specify expiration using:
| Format | Description | Example |
|---|---|---|
{n}h | Hours | 24h = 24 hours |
{n}d | Days | 7d = 7 days |
{n}w | Weeks | 2w = 2 weeks |
{n}m | Months | 3m = 3 months |
{n}y | Years | 1y = 1 year |
never | No expiration | Key never expires |
Examples:
# 1 hour expiration
{"expiresIn": "1h"}
# 30 days expiration
{"expiresIn": "30d"}
# 1 year expiration
{"expiresIn": "1y"}
# Never expires
{"expiresIn": "never"}
π Expiration HandlingΒΆ
When an API key expires: - All requests with that key return 401 Unauthorized - The key remains in the database but is marked as expired - You can see expired keys in the list - Create a new key to replace the expired one
π Security ConfigurationΒΆ
π APP_KEY Environment VariableΒΆ
Critical: Set the APP_KEY environment variable before generating API keys.
Why it matters: - API keys are signed using APP_KEY - If APP_KEY changes, all existing keys become invalid - Without APP_KEY, keys are invalidated on server restart
Generating a secure APP_KEY:
π‘οΈ Security Best PracticesΒΆ
DO: - β
Set and persist APP_KEY in production - β
Use HTTPS for all API requests - β
Store API keys securely (environment variables, secrets management) - β
Use different keys for different environments - β
Set appropriate expiration times - β
Rotate keys periodically - β
Revoke unused or compromised keys immediately - β
Use least-privilege roles for API keys
DON'T: - β Commit API keys to version control - β Share API keys between applications - β Use the same key for development and production - β Create keys without expiration in production - β Give API keys more permissions than needed - β Expose API keys in client-side code - β Log API keys in application logs
π― Access LevelsΒΆ
Continuum defines three main access levels:
1οΈβ£ Public AccessΒΆ
No authentication required. Anyone can access.
// Configuration (internal)
acl.allow('articles', 'list', 'public');
acl.allow('articles', 'get', 'public');
Use Cases: - Public blog posts - Public product catalog - Public documentation
2οΈβ£ Logged In (loggedIn)ΒΆ
Requires valid API key or user session.
Use Cases: - Creating content - Updating own records - Accessing user-specific data
3οΈβ£ Configure Access (allowConfigure)ΒΆ
Requires administrative permissions.
Use Cases: - Managing collections - Creating API keys - System configuration
π Integration with RolesΒΆ
API keys inherit all permissions from their associated role.
π Example Role ConfigurationΒΆ
Admin Role: - Full access to all resources - Can create/delete collections - Can manage users and API keys
Editor Role: - Can create/update/delete content - Cannot modify schema - Cannot manage users
Viewer Role: - Read-only access to content - Cannot create or modify data - Cannot access admin functions
π― Creating Keys with Different RolesΒΆ
# Admin key - full access
POST /api/apiKeys:create
X-App: main
{
"role": {"name": "admin"},
"expiresIn": "30d"
}
# Editor key - content management only
POST /api/apiKeys:create
X-App: main
{
"role": {"name": "editor"},
"expiresIn": "7d"
}
# Viewer key - read-only access
POST /api/apiKeys:create
X-App: main
{
"role": {"name": "viewer"},
"expiresIn": "1y"
}
π SDK SupportΒΆ
JavaScript/TypeScript SDKΒΆ
import { APIClient } from '@nocobase/sdk';
const api = new APIClient({
baseURL: 'https://continuum.example.com/api',
headers: {
'X-App': 'main',
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...'
}
});
// Use the API
const articles = await api.resource('articles').list();
Python ExampleΒΆ
import requests
API_KEY = "eyJhbGciOiJIUzI1NiIs..."
BASE_URL = "https://continuum.example.com/api"
headers = {
"Authorization": f"Bearer {API_KEY}",
"X-App": "main",
"Content-Type": "application/json"
}
# List articles
response = requests.get(
f"{BASE_URL}/articles:list",
headers=headers
)
articles = response.json()
cURL ExampleΒΆ
#!/bin/bash
API_KEY="eyJhbGciOiJIUzI1NiIs..."
BASE_URL="https://continuum.example.com/api"
APP_NAME="main"
# Function to make API requests
api_request() {
local method=$1
local endpoint=$2
local data=$3
curl -X "$method" \
-H "Authorization: Bearer $API_KEY" \
-H "X-App: $APP_NAME" \
-H "Content-Type: application/json" \
-d "$data" \
"$BASE_URL/$endpoint"
}
# List products
api_request GET "products:list"
# Create product
api_request POST "products:create" '{"name":"Laptop","price":999.99}'
π§ TroubleshootingΒΆ
β Error: "Unauthorized" (401)ΒΆ
Possible Causes: 1. API key is invalid or malformed 2. API key has expired 3. APP_KEY changed after key was generated 4. Wrong application specified
Solutions:
# Verify key format
echo "Authorization: Bearer {your-key}" | grep "^Authorization: Bearer eyJ"
# Check key expiration
GET /api/apiKeys:list
X-App: main
# Look for your key's expiresAt field
# Generate new key
POST /api/apiKeys:create
X-App: main
{"role": {"name": "admin"}}
β Error: "No permissions" (403)ΒΆ
Possible Causes: 1. Role lacks required permissions 2. API key's role doesn't allow the operation 3. Resource-level permissions deny access
Solutions:
# Check your role's permissions
GET /api/roles:get?filterByTk={role-name}&appends=permissions
X-App: main
# Create key with higher privileges
POST /api/apiKeys:create
X-App: main
{"role": {"name": "admin"}}
β Error: "Application not found"ΒΆ
Possible Causes: 1. Wrong X-App header value 2. Application doesn't exist 3. Using key from different application
Solutions:
# List available applications
GET /api/applications:list
X-App: main
# Ensure X-App matches your key's application
β API Key Not Working After Server RestartΒΆ
Cause: APP_KEY environment variable not set
Solution:
π Monitoring & AnalyticsΒΆ
π Track API Key UsageΒΆ
Response includes: - Last used timestamp - Total requests count - Failed authentication attempts - Most accessed endpoints
π Key Expiration AlertsΒΆ
Set up monitoring for keys expiring soon:
# Get keys expiring in next 7 days
GET /api/apiKeys:list?filter={"expiresAt":{"$gte":"{{now}}","$lte":"{{now+7d}}"}}
X-App: main
π Related DocumentationΒΆ
- Permissions System: Fine-grained access control
- Multi-App Manager: Application-specific authentication
- API Gateway: Overall API architecture
- Best Practices: Security and optimization guidelines
Note: Proper API key management is crucial for maintaining security and access control in your Continuum deployment.