API Roles & Authentication
All Torvus Platform API endpoints require authentication. This guide explains role requirements, error responses, and best practices for working with role-based access control.
Authentication Model​
Required Headers​
All API requests must include authentication:
Authorization: Bearer <supabase_access_token>
Cookie: <session_cookies>
Minimum Role​
The minimum role for all endpoints is VAULT_VIEWER, which is automatically granted to all authenticated users.
Role Requirements by Endpoint​
Vault Endpoints​
GET /api/vaults​
List all vaults owned by the current user.
Authentication: Required Minimum Role: VAULT_VIEWER (owner only)
Response:
{
"vaults": [
{
"id": "vault-123",
"name": "My Vault",
"ownerUid": "user-456",
"created_at": "2025-10-01T00:00:00Z"
}
],
"_meta": {
"role": "VAULT_VIEWER",
"canCreate": true
}
}
GET /api/vaults/[id]​
Retrieve vault details.
Authentication: Required Minimum Role: VAULT_VIEWER (owner only) or VAULT_ADMIN (any vault, future)
Error Responses:
401 Unauthorized- Not authenticated403 Forbidden- VAULT_VIEWER but not owner404 Not Found- Vault does not exist
Response with Metadata:
{
"vault": {
"id": "vault-123",
"name": "My Vault",
"ownerUid": "user-456"
},
"_meta": {
"viewingAsOwner": true,
"canModify": false,
"role": "VAULT_VIEWER"
}
}
POST /api/vaults​
Create a new vault.
Authentication: Required Minimum Role: VAULT_VIEWER (any authenticated user)
Note: Creator automatically becomes VAULT_OWNER of the new vault.
Request:
{
"name": "New Vault"
}
Response:
{
"vault": {
"id": "vault-789",
"name": "New Vault",
"ownerUid": "user-456"
},
"_meta": {
"autoGrantedOwnership": true
}
}
DELETE /api/vaults/[id]​
Delete a vault permanently.
Authentication: Required Minimum Role: VAULT_OWNER (ownership required)
Error Responses:
401 Unauthorized- Not authenticated403 Forbidden- VAULT_VIEWER/VAULT_OPERATOR but not VAULT_OWNER404 Not Found- Vault not found
403 Error Example:
{
"ok": false,
"error": "Insufficient permissions",
"required": ["VAULT_OWNER"],
"actual": ["VAULT_VIEWER"]
}
Document Endpoints​
POST /api/vaults/[id]/documents/initiate​
Upload a document to a vault.
Authentication: Required Minimum Role: VAULT_VIEWER (owner of vault)
Request:
{
"fileName": "document.pdf",
"fileSize": 1024000
}
GET /api/documents/[id]​
Retrieve document details.
Authentication: Required Minimum Role: VAULT_VIEWER (owner only)
DELETE /api/documents/[id]​
Delete a document.
Authentication: Required Minimum Role: VAULT_OWNER (ownership of vault required)
Release Endpoints​
POST /api/vaults/[id]/release/execute​
Execute a vault release (shadow or real).
Authentication: Required Minimum Role:
- Shadow releases: VAULT_OPERATOR+
- Real releases: VAULT_ADMIN+
Additional Requirements (Real Releases):
- Multi-factor authentication (MFA) verified
- Approval granted (if policies require)
- Clean document scans (no threats)
Request:
{
"shadowMode": true
}
Error for Insufficient Role:
{
"ok": false,
"error": "Insufficient role",
"required": ["VAULT_ADMIN"],
"actual": ["VAULT_VIEWER"],
"requestId": "req-123"
}
Signing Endpoints​
POST /api/sign​
Sign a document with PAdES.
Authentication: Required Minimum Role: VAULT_VIEWER (any authenticated user)
Note: Document signing is available to all authenticated users.
GET /api/signing/jobs/owner​
List signing jobs owned by current user.
Authentication: Required Minimum Role: VAULT_VIEWER (own jobs only)
Audit Endpoints​
GET /api/audit-events​
List audit events for the current user.
Authentication: Required Minimum Role: VAULT_VIEWER (own events only)
Query Parameters:
limit- Number of events to return (default: 50)offset- Pagination offsetaction- Filter by action type
Error Responses​
401 Unauthorized​
User is not authenticated.
{
"ok": false,
"error": "Authentication required",
"requestId": "req-123"
}
Solution: Provide valid authentication credentials.
403 Forbidden​
User is authenticated but lacks required role.
{
"ok": false,
"error": "Insufficient permissions",
"required": ["VAULT_OWNER"],
"actual": ["VAULT_VIEWER"],
"requestId": "req-123"
}
Solution: Request role upgrade or contact vault owner.
404 Not Found​
Resource does not exist.
{
"ok": false,
"error": "Vault not found",
"requestId": "req-123"
}
Note: For security, 404 is returned even if the resource exists but user lacks access (to prevent information disclosure).
Role-Based Filtering​
List Endpoints​
List endpoints automatically filter by ownership:
VAULT_VIEWER:
- Returns only owned resources
- Cannot see other users' data
Future: VAULT_ADMIN may see all resources for operational monitoring.
Metadata Fields​
API responses include metadata for client-side role handling:
{
"_meta": {
"role": "VAULT_VIEWER", // User's primary role
"viewingAsOwner": true, // Is user the owner?
"canModify": false, // Can user modify this resource?
"requiredRoleForModify": "VAULT_OWNER"
}
}
Best Practices​
Client-Side Role Checks​
Use metadata to show/hide UI elements:
const response = await fetch('/api/vaults/123');
const data = await response.json();
if (!data._meta.canModify) {
// Disable edit/delete buttons
// Show "View-Only Mode" alert
}
Error Handling​
Handle role-based errors gracefully:
try {
await fetch('/api/vaults/123', { method: 'DELETE' });
} catch (error) {
if (error.status === 403) {
const body = await error.json();
showRoleUpgradeDialog(body.required);
}
}
Optimistic UI​
Don't show actions users cannot perform:
import { useUserRole } from '@/hooks/useUserRole';
function VaultActions({ vaultOwnerId }) {
const { hasRole, isOwner } = useUserRole();
const canDelete = isOwner(vaultOwnerId) && hasRole('VAULT_OWNER');
return (
<>
{canDelete && (
<Button onClick={handleDelete}>Delete Vault</Button>
)}
</>
);
}
Caching Role Information​
Cache user roles to reduce API calls:
// Fetch once, cache in memory
const { roles } = await fetchUserRoles();
localStorage.setItem('user_roles', JSON.stringify(roles));
// Reuse for permission checks
const hasRole = (required) => roles.includes(required);
Testing with Different Roles​
Creating Test Users​
For testing, create users with specific roles:
-- Grant VAULT_OWNER to test user
INSERT INTO role_grants (user_id, role)
VALUES ('test-user-id', 'VAULT_OWNER');
-- Grant VAULT_ADMIN to another user
INSERT INTO role_grants (user_id, role)
VALUES ('admin-user-id', 'VAULT_ADMIN');
Test Scenarios​
- VAULT_VIEWER - Basic access testing
- VAULT_OPERATOR - Shadow release testing
- VAULT_ADMIN - Real release testing
- VAULT_OWNER - Full management testing
- Cross-user access - Verify 403 errors
Migration Guide​
Updating Existing Integrations​
If your integration predates role-based access:
-
Check Error Responses
- 403 errors now include
requiredandactualroles - Use this to guide users to upgrade
- 403 errors now include
-
Add Role Checks
- Use
_metafields in responses - Show appropriate UI based on permissions
- Use
-
Handle Disabled Actions
- Show tooltips explaining role requirements
- Provide role upgrade flows
-
Update Tests
- Test with VAULT_VIEWER (minimum role)
- Verify error responses for insufficient roles
- Check metadata fields in responses
Related Documentation​
Last Updated: October 5, 2025