Authentication
FluxiQ SPB uses JWT (JSON Web Tokens) for API authentication. All protected endpoints require a valid Bearer token in the Authorization header.
Authentication Flow
1. Client sends credentials to /auth/login
2. Auth service validates credentials against database
3. Auth service returns JWT access token + refresh token
4. Client includes access token in subsequent requests
5. When access token expires, client uses refresh token to get a new one
6. For privileged operations, MFA verification may be requiredObtaining a Token
Login
Send your credentials to the login endpoint:
curl -X POST http://localhost:4000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "operator@institution.com.br",
"password": "your-secure-password"
}'Successful response:
{
"data": {
"token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTEyMyIsImlzcyI6ImZsdXhpcS1zcGIiLCJhdWQiOiJmbHV4aXEtc3BiLWFwaSIsImV4cCI6MTcwNjAwMDAwMCwiaWF0IjoxNzA1OTk2NDAwLCJ0ZW5hbnRfaWQiOiJ0ZW5hbnQtNDU2IiwiaXNwYiI6IjEyMzQ1Njc4Iiwicm9sZXMiOlsib3BlcmF0b3IiXSwicGVybWlzc2lvbnMiOlsidHJhbnNhY3Rpb25zOnJlYWQiLCJ0cmFuc2FjdGlvbnM6Y3JlYXRlIl19.signature",
"refresh_token": "rt_a1b2c3d4e5f6...",
"expires_in": 3600,
"token_type": "Bearer"
}
}Failed login response (HTTP 401):
{
"error": {
"code": "INVALID_CREDENTIALS",
"message": "Invalid username or password"
}
}Using the Token
Include the token in the Authorization header of every request:
curl http://localhost:4000/api/v1/str/balance \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiIs..."Token Refresh
Access tokens expire after the configured TTL (default: 1 hour). Use the refresh token to obtain a new access token without re-authenticating:
curl -X POST http://localhost:4000/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "rt_a1b2c3d4e5f6..."
}'Response:
{
"data": {
"token": "eyJhbGciOiJIUzUxMiIs...(new token)",
"refresh_token": "rt_g7h8i9j0k1l2...(new refresh token)",
"expires_in": 3600,
"token_type": "Bearer"
}
}Important: Refresh token rotation is enforced. Each refresh request issues a new refresh token and invalidates the previous one. If a previously-used refresh token is presented, all sessions for that user are revoked as a security precaution.
Token Revocation
Explicitly revoke a token (e.g., on user logout):
curl -X POST http://localhost:4000/api/v1/auth/revoke \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiIs..." \
-H "Content-Type: application/json" \
-d '{
"token": "eyJhbGciOiJIUzUxMiIs..."
}'JWT Token Claims
The JWT payload contains the following claims:
| Claim | Description |
|---|---|
sub | User UUID |
iss | Issuer (fluxiq-spb) |
aud | Audience (fluxiq-spb-api) |
exp | Expiration timestamp (Unix epoch) |
iat | Issued-at timestamp (Unix epoch) |
tenant_id | Tenant UUID for multi-tenant isolation |
ispb | Institution's ISPB code (8 digits) |
roles | Array of role names |
permissions | Array of permission strings |
Role-Based Access Control (RBAC)
FluxiQ SPB implements hierarchical RBAC with the following default roles:
| Role | Description | Key Permissions |
|---|---|---|
admin | Tenant administrator | All permissions |
treasury | Treasury operations | STR, TED, DOC, balance, settlements |
operator | Transaction operator | TED, DOC (with amount limits) |
securities | Securities desk | SEL, CTP operations |
forex | FX desk | CAM operations |
viewer | Read-only access | Read all, create nothing |
auditor | Compliance auditor | Read all + extract generation |
Permission Format
Permissions follow the pattern resource:action:
transactions:read - View transactions
transactions:create - Create new transactions
transactions:cancel - Cancel pending transactions
str:balance:read - View STR balance
settlements:read - View settlement data
settlements:create - Submit settlement batches
securities:transfer - Transfer securities
forex:create - Register FX contracts
cash:create - Create cash orders
extracts:create - Generate data extracts
users:create - Create new users
users:roles:assign - Assign roles to usersMulti-Factor Authentication (MFA)
MFA is required for privileged operations such as:
- Transactions above a configurable threshold
- User role assignments
- System configuration changes
- Extract generation with sensitive data
MFA Flow
# 1. Attempt a privileged operation
curl -X POST http://localhost:4000/api/v1/transactions/str \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiIs..." \
-H "Content-Type: application/json" \
-d '{"amount": "10000000.00", ...}'
# Response 403 - MFA Required
{
"error": {
"code": "MFA_REQUIRED",
"message": "This operation requires MFA verification",
"mfa_challenge_id": "mfa_ch_abc123"
}
}
# 2. Submit MFA code
curl -X POST http://localhost:4000/api/v1/auth/mfa/verify \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiIs..." \
-H "Content-Type: application/json" \
-d '{
"challenge_id": "mfa_ch_abc123",
"code": "123456"
}'
# Response 200 - MFA verified, token upgraded
{
"data": {
"token": "eyJhbGciOiJIUzUxMiIs...(upgraded token with mfa_verified claim)",
"mfa_verified": true,
"mfa_expires_in": 300
}
}
# 3. Retry the privileged operation with the upgraded token
curl -X POST http://localhost:4000/api/v1/transactions/str \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiIs...(upgraded)" \
-H "Content-Type: application/json" \
-d '{"amount": "10000000.00", ...}'Multi-Tenant Isolation
Every JWT token is scoped to a specific tenant (financial institution). The platform enforces strict data isolation:
- All database queries are automatically scoped by
tenant_id - Cross-tenant data access is impossible, even with admin privileges
- Each tenant has its own ISPB code and BACEN credentials
- Audit logs include the tenant context for every operation
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
INVALID_CREDENTIALS | 401 | Wrong username or password |
TOKEN_EXPIRED | 401 | JWT access token has expired |
TOKEN_REVOKED | 401 | Token has been explicitly revoked |
REFRESH_TOKEN_REUSE | 401 | Refresh token was already used (all sessions revoked) |
INSUFFICIENT_PERMISSIONS | 403 | User lacks required permission |
MFA_REQUIRED | 403 | Operation requires MFA verification |
MFA_INVALID_CODE | 401 | MFA code is incorrect |
ACCOUNT_LOCKED | 423 | Account locked due to failed login attempts |
Security Best Practices
- Store tokens securely: Use
httpOnlycookies or secure storage on the client side. Never store tokens inlocalStorage. - Use short-lived access tokens: The default 1-hour TTL minimizes exposure if a token is compromised.
- Always use HTTPS: The API Gateway should be accessed over TLS in production.
- Implement token refresh: Do not ask users to re-authenticate. Use the refresh token flow.
- Handle 401 responses: Implement automatic token refresh when a 401 is received.
- Revoke tokens on logout: Always call the revoke endpoint when a user logs out.