Authentication
work.studio supports multiple authentication methods for different use cases.
Authentication Methods
API Key Authentication
API Keys provide secure access for server-to-server integrations without user context.
Creating an API Key
- Navigate to Settings → API Keys in the work.studio console
- Click Create API Key
- Select the key type:
- Tenant Key: Full access to tenant resources
- Customer Key: Scoped to a specific customer/execution scope
- Set permissions and expiration
- Copy the key immediately (it won't be shown again)
Using API Keys
Include the X-API-Key header in your requests:
curl -X GET "https://api.work.studio/api/v1/workflow/workflows" \
-H "X-API-Key: sv_live_1234567890abcdef"
API Key Types
Tenant Keys
Tenant keys have access to all resources within a tenant. Optionally scope requests to a specific customer using the X-Scope-Key header:
curl -X GET "https://api.work.studio/api/v1/workflow/workflows" \
-H "X-API-Key: sv_live_tenant_key_here" \
-H "X-Scope-Key: customer_scope_id"
Customer Keys
Customer keys are bound to a specific execution scope and can only access resources within that scope:
curl -X GET "https://api.work.studio/api/v1/workflow/workflows" \
-H "X-API-Key: sv_live_customer_key_here"
API Key Management Endpoints
Bearer Token Authentication
Bearer tokens are JWT tokens obtained through OAuth 2.0 / OpenID Connect authentication with Keycloak.
Token Structure
The JWT token contains tenant authorization claims:
{
"sub": "user-uuid",
"email": "user@example.com",
"tenants": ["tenant-uuid-1", "tenant-uuid-2"],
"authorized_tenants": ["tenant-uuid-1"],
"iat": 1234567890,
"exp": 1234571490
}
Using Bearer Tokens
Include the token in the Authorization header along with tenant context:
curl -X GET "https://api.work.studio/api/v1/workflow/workflows" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "X-SELECTED-TENANT: tenant-uuid" \
-H "X-SELECTED-ENV: environment-uuid"
Required Headers for Bearer Auth
Endpoint Types
Different endpoints have different authentication requirements:
Public Endpoints
No authentication required. Examples:
- Health checks:
/actuator/health - API documentation:
/swagger-ui/**,/v3/api-docs/** - Public forms and embeds
System Endpoints
Authentication required, but no tenant context. Examples:
- Account signup
- Initial tenant creation
Tenant Endpoints (Default)
Both authentication and tenant context required. This is the default for all resource APIs.
Security Best Practices
API Key Security
- Store API keys in environment variables or secret managers
- Use least-privilege permissions
- Rotate keys regularly
- Use customer-scoped keys when possible
- Monitor key usage
- Commit API keys to version control
- Share keys across environments
- Use tenant keys when customer keys suffice
- Keep unused keys active
Token Security
- Use short token expiration times
- Implement token refresh flows
- Validate tokens server-side
- Use HTTPS for all requests
- Store tokens in localStorage (prefer httpOnly cookies)
- Pass tokens in URL parameters
- Share tokens between users
Error Responses
401 Unauthorized
Missing or invalid authentication:
403 Forbidden
Valid authentication but insufficient permissions:
{
"error": "Forbidden",
"message": "You don't have permission to access this resource",
"status": 403
}
400 Bad Request - Missing Tenant
Authenticated but missing required tenant header:
{
"error": "Bad Request",
"message": "X-SELECTED-TENANT header is required",
"status": 400
}
Multi-Tenancy
work.studio is a multi-tenant platform. When using Bearer token authentication:
- User authenticates and receives JWT with authorized tenants
- Client sends
X-SELECTED-TENANTheader with each request - Server validates tenant is in the JWT's authorized list
- All queries are automatically scoped via Row-Level Security (RLS)
sequenceDiagram
participant Client
participant API
participant Auth
participant DB
Client->>Auth: Login (OAuth)
Auth-->>Client: JWT with tenants claim
Client->>API: Request + JWT + X-SELECTED-TENANT
API->>API: Validate JWT
API->>API: Validate tenant authorization
API->>DB: Query with RLS (SET app.tenant_id)
DB-->>API: Tenant-scoped results
API-->>Client: ResponseCode Examples
Python
import requests
# API Key Authentication
headers = {
"X-API-Key": "sv_live_your_api_key"
}
response = requests.get(
"https://api.work.studio/api/v1/workflow/workflows",
headers=headers
)
# Bearer Token Authentication
headers = {
"Authorization": f"Bearer {access_token}",
"X-SELECTED-TENANT": "tenant-uuid",
"X-SELECTED-ENV": "env-uuid"
}
response = requests.get(
"https://api.work.studio/api/v1/workflow/workflows",
headers=headers
)
JavaScript/TypeScript
// API Key Authentication
const response = await fetch('https://api.work.studio/api/v1/workflow/workflows', {
headers: {
'X-API-Key': 'sv_live_your_api_key'
}
});
// Bearer Token Authentication
const response = await fetch('https://api.work.studio/api/v1/workflow/workflows', {
headers: {
'Authorization': `Bearer ${accessToken}`,
'X-SELECTED-TENANT': 'tenant-uuid',
'X-SELECTED-ENV': 'env-uuid'
}
});
cURL
# API Key
curl -X GET "https://api.work.studio/api/v1/workflow/workflows" \
-H "X-API-Key: sv_live_your_api_key"
# Bearer Token
curl -X GET "https://api.work.studio/api/v1/workflow/workflows" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "X-SELECTED-TENANT: tenant-uuid" \
-H "X-SELECTED-ENV: env-uuid"