Role management
This recipe shows how to manage tenant roles and assignments in FVI. FVI ships with a built-in role catalog (tenant_admin, tenant_analyst, tenant_lead, tenant_reviewer, tenant_auditor, tenant_viewer, etc.) and supports custom roles for tenant-specific responsibilities.
Endpoints
GET /v1/roles # List all roles (built-in and custom)
POST /v1/roles # Create a custom role
GET /v1/roles/{id} # Get role details
PATCH /v1/roles/{id} # Update custom role
DELETE /v1/roles/{id} # Soft-delete custom role
POST /v1/users/{id}/roles # Assign role to user
DELETE /v1/users/{id}/roles/{roleId} # Revoke role from user
Prerequisites
- A valid
tenantIdand bearer JWT. - The user must have the
tenant_adminrole.
Built-in role catalog
| Role | Description | Key permissions |
|---|---|---|
tenant_admin | Full administrative access | All permissions |
tenant_analyst | Day-to-day reconciliation work | Read/write exceptions, read reconciliations |
tenant_lead | Team lead with assignment rights | Read/write exceptions, assign to team |
tenant_reviewer | Senior analyst with override rights | All analyst permissions plus override assignments |
tenant_auditor | Audit trail access | Read audit trail, read-only on all data |
tenant_compliance | Compliance officer | Read evidence packs, generate reports |
tenant_viewer | Read-only access | Read accounts, reconciliations, exceptions |
tenant_rule_author | Rule authoring | Read/write reconciliation rules |
tenant_ai_prompter | AI copilot user | Use AI copilots within role scope |
List roles
curl -X GET "https://api.falconveritas.com/v1/roles" \
-H "Authorization: Bearer $FVI_JWT" \
-H "X-Tenant-Id: $FVI_TENANT_ID" \
-H "Content-Type: application/json"
Create custom role
curl -X POST https://api.falconveritas.com/v1/roles \
-H "Authorization: Bearer $FVI_JWT" \
-H "X-Tenant-Id: $FVI_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "FX Reconciliation Specialist",
"description": "Specialized role for FX reconciliation across multiple currencies",
"permissions": [
"exception.read",
"exception.write",
"exception.assign",
"exception.resolve.fx_difference",
"rule.read",
"rule.write.fx",
"ai_copilot.use.fx"
],
"idempotency_key": "role-fvi-$RANDOM"
}'
Assign role to user
curl -X POST https://api.falconveritas.com/v1/users/user-001/roles \
-H "Authorization: Bearer $FVI_JWT" \
-H "X-Tenant-Id: $FVI_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"role_id": "role-001",
"expires_at": "2027-08-22T00:00:00Z",
"justification": "Promoted to FX Reconciliation Specialist per HR-2026-Q3-042",
"idempotency_key": "role-assign-fvi-$RANDOM"
}'
Response
{
"user_id": "user-001",
"role_id": "role-001",
"role_name": "FX Reconciliation Specialist",
"assigned_by": "user:admin",
"assigned_at": "2026-08-22T16:30:00Z",
"expires_at": "2027-08-22T00:00:00Z",
"audit_trail_id": "audit-003"
}
Use cases
- Segregation of duties — assign different roles to separate the people who create vs. approve reconciliation rules.
- Specialized access — grant FX specialists access to FX-only actions.
- Time-bound access — set role expirations for project-based engagements.
- Just-in-time access — grant temporary roles with expiry for incident response.
Code samples
TypeScript
import { FVI } from '@falconveritas/sdk';
const fvi = new FVI({
baseUrl: 'https://api.falconveritas.com',
bearer: process.env.FVI_JWT!,
tenantId: process.env.FVI_TENANT_ID!,
});
// Create a custom role
const role = await fvi.roles.create({
name: 'FX Reconciliation Specialist',
permissions: [
'exception.read',
'exception.write',
'exception.resolve.fx_difference',
],
idempotencyKey: `role-fvi-${Date.now()}`,
});
// Assign role to user
const assignment = await fvi.users.assignRole('user-001', {
roleId: role.id,
expiresAt: '2027-08-22T00:00:00Z',
idempotencyKey: `role-assign-fvi-${Date.now()}`,
});
console.log('Role assigned, expires:', assignment.expires_at);
Python
from falconveritas import FVI
client = FVI(
bearer=os.environ["FVI_JWT"],
tenant_id=os.environ["FVI_TENANT_ID"],
)
role = client.roles.create(
name="FX Reconciliation Specialist",
permissions=[
"exception.read",
"exception.write",
"exception.resolve.fx_difference",
],
idempotency_key=f"role-fvi-{int(time.time())}",
)
assignment = client.users.assign_role(
"user-001",
role_id=role.id,
expires_at="2027-08-22T00:00:00Z",
idempotency_key=f"role-assign-fvi-{int(time.time())}",
)
print("Role assigned, expires:", assignment.expires_at)
Related articles
Last updated: 2026-08-22 · Page owner: Documentation · Source: src/lib/api/roles.ts.