Authorization
HatiData combines Role-Based Access Control (RBAC) with Attribute-Based Access Control (ABAC) to provide fine-grained authorization. RBAC defines what a user can do; ABAC defines when and how they can do it.
RBAC: Role-Based Access Control
Six Predefined Roles
Every user is assigned exactly one role within an organization. Roles follow the principle of least privilege.
| Role | Description |
|---|---|
| Owner | Full access including billing and destructive operations. One per organization. |
| Admin | Full access except billing. Can manage users, policies, and environments. |
| Analyst | Query execution only. Cannot modify schema, policies, or users. |
| Auditor | Read-only access to audit logs. Cannot execute queries or modify anything. |
| Developer | Query execution and schema modification. Cannot manage policies or users. |
| ServiceAccount | Programmatic query execution only. Used for agents and automated pipelines. |
Permission Matrix
| Permission | Owner | Admin | Analyst | Auditor | Developer | ServiceAccount |
|---|---|---|---|---|---|---|
| Execute queries | Yes | Yes | Yes | -- | Yes | Yes |
| Read schema | Yes | Yes | Yes | -- | Yes | Yes |
| Modify schema | Yes | Yes | -- | -- | Yes | -- |
| Manage policies | Yes | Yes | -- | -- | -- | -- |
| Manage users | Yes | Yes | -- | -- | -- | -- |
| Manage API keys | Yes | Yes | -- | -- | -- | -- |
| View audit logs | Yes | Yes | -- | Yes | -- | -- |
| Manage billing | Yes | -- | -- | -- | -- | -- |
| Manage webhooks | Yes | Yes | -- | -- | -- | -- |
| Configure SSO | Yes | Yes | -- | -- | -- | -- |
| Delete organization | Yes | -- | -- | -- | -- | -- |
Role Assignment
Roles are assigned when inviting users or updated via the API:
# Invite a user with a specific role
curl -X POST https://api.hatidata.com/v1/organizations/org_abc/users \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"email": "analyst@company.com",
"role": "analyst"
}'
# Update an existing user's role
curl -X PUT https://api.hatidata.com/v1/organizations/org_abc/users/usr_123/role \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"role": "developer"
}'
Only Owners can promote users to Admin. Admins cannot self-elevate to Owner. Role changes are recorded in the IAM audit trail.
ABAC: Attribute-Based Access Control
ABAC extends RBAC by evaluating policies against contextual attributes at query time. This enables dynamic access decisions based on who is asking, what they are asking, and when they are asking.
Evaluation Context
Every request builds an AbacEvaluationContext with 10 attributes:
struct AbacEvaluationContext {
user_role: Role, // RBAC role
user_id: Uuid, // Authenticated user
org_id: Uuid, // Organization scope
environment: String, // "production", "staging", "dev"
source_ip: IpAddr, // Client IP address
query_origin: String, // "dashboard", "api", "agent", "sdk"
agent_framework: Option<String>, // "langchain", "crewai", etc.
agent_id: Option<String>, // Unique agent identifier
time_of_day: NaiveTime, // Server time
day_of_week: Weekday, // Monday-Sunday
}
Rule Conditions
ABAC policies use rule conditions to express complex access logic. Seven condition types are available:
QueryOriginIs
Restrict access based on how the query was initiated:
{
"condition": "QueryOriginIs",
"values": ["dashboard", "sdk"],
"action": "deny",
"message": "Direct API queries are not permitted in production"
}
AgentFrameworkIs
Control which AI agent frameworks can access data:
{
"condition": "AgentFrameworkIs",
"values": ["langchain", "crewai"],
"action": "allow",
"message": "Only approved agent frameworks may query production data"
}
TimeOfDay
Enforce time-based access windows:
{
"condition": "TimeOfDay",
"start": "09:00",
"end": "18:00",
"timezone": "America/New_York",
"action": "deny_outside",
"message": "Production queries restricted to business hours"
}
DayOfWeek
Restrict operations by day of week:
{
"condition": "DayOfWeek",
"values": ["Saturday", "Sunday"],
"action": "read_only",
"message": "Weekend access is read-only"
}
AttributeEquals
Match custom key-value attributes from the session context:
{
"condition": "AttributeEquals",
"key": "department",
"value": "engineering",
"action": "allow"
}
LicenseTierIs
Gate features or access by subscription tier:
{
"condition": "LicenseTierIs",
"values": ["Growth", "Enterprise"],
"action": "allow",
"message": "Column masking requires Growth tier or above"
}
ScopeRequired
Require a specific API key scope for the operation:
{
"condition": "ScopeRequired",
"scope": "query:write",
"action": "deny",
"message": "Write operations require the query:write scope"
}
CompiledPolicySet
For performance, ABAC policies are compiled into a CompiledPolicySet at load time. This pre-compilation avoids repeated parsing and enables sub-millisecond evaluation:
Policy JSON → Parse → Validate → Compile → CompiledPolicySet (in-memory)
│
evaluate(context) → Allow / Deny
Policy changes trigger automatic recompilation. The compiled set is shared across all request-handling threads via an Arc.
Policy Evaluation Order
- Deny rules are evaluated first -- any matching deny rule immediately rejects the request
- Allow rules are evaluated second -- at least one allow rule must match
- Default deny -- if no allow rule matches, the request is denied
Creating an ABAC Policy
curl -X POST https://api.hatidata.com/v1/environments/env_abc/abac-policies \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"name": "production-agent-policy",
"description": "Restrict production access to approved agent frameworks during business hours",
"rules": [
{
"condition": "AgentFrameworkIs",
"values": ["langchain", "crewai"],
"action": "allow"
},
{
"condition": "TimeOfDay",
"start": "06:00",
"end": "22:00",
"timezone": "UTC",
"action": "deny_outside"
}
],
"priority": 10,
"enabled": true
}'
Policy Simulation
Test policies without enforcing them using the simulation endpoint:
curl -X POST https://api.hatidata.com/v1/environments/env_abc/abac-policies/simulate \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"context": {
"user_role": "developer",
"query_origin": "agent",
"agent_framework": "langchain",
"time_of_day": "14:30",
"day_of_week": "Wednesday"
},
"query": "SELECT * FROM customers"
}'
Response:
{
"decision": "allow",
"matching_policies": [
{
"policy_id": "pol_abc",
"name": "production-agent-policy",
"matched_rules": [
{ "condition": "AgentFrameworkIs", "result": "allow" },
{ "condition": "TimeOfDay", "result": "allow" }
]
}
],
"evaluation_time_ms": 0.3
}
Agent-Specific Policies
HatiData provides dedicated policy primitives for AI agents:
Agent Capability Grants
Grant specific capabilities to individual agents:
{
"agent_id": "agent-data-analyst",
"capabilities": {
"allowed_tables": ["public.customers", "public.orders"],
"max_queries_per_hour": 1000,
"max_rows_per_query": 10000,
"allowed_operations": ["SELECT"],
"expires_at": "2026-03-01T00:00:00Z"
}
}
Agent Framework Restrictions
Apply policies at the framework level rather than per-agent:
{
"condition": "AgentFrameworkIs",
"values": ["langchain"],
"apply": {
"row_limit": 5000,
"column_masking": ["email", "phone"],
"allowed_schemas": ["public", "analytics"]
}
}
Policy Management API
For complete API endpoint documentation, see Policies API.
| Operation | Endpoint |
|---|---|
| List policies | GET /v1/environments/{env_id}/policies |
| Create policy | POST /v1/environments/{env_id}/policies |
| Update policy | PUT /v1/environments/{env_id}/policies/{policy_id} |
| Delete policy | DELETE /v1/environments/{env_id}/policies/{policy_id} |
| List ABAC policies | GET /v1/environments/{env_id}/abac-policies |
| Create ABAC policy | POST /v1/environments/{env_id}/abac-policies |
| Simulate policy | POST /v1/environments/{env_id}/abac-policies/simulate |
| Agent summary | GET /v1/environments/{env_id}/abac-policies/agent-summary |
Next Steps
- Data Protection -- Column masking and row-level security
- Authentication -- JWT, API keys, federated tokens
- Policies API -- Full endpoint reference