Skip to main content

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.

RoleDescription
OwnerFull access including billing and destructive operations. One per organization.
AdminFull access except billing. Can manage users, policies, and environments.
AnalystQuery execution only. Cannot modify schema, policies, or users.
AuditorRead-only access to audit logs. Cannot execute queries or modify anything.
DeveloperQuery execution and schema modification. Cannot manage policies or users.
ServiceAccountProgrammatic query execution only. Used for agents and automated pipelines.

Permission Matrix

PermissionOwnerAdminAnalystAuditorDeveloperServiceAccount
Execute queriesYesYesYes--YesYes
Read schemaYesYesYes--YesYes
Modify schemaYesYes----Yes--
Manage policiesYesYes--------
Manage usersYesYes--------
Manage API keysYesYes--------
View audit logsYesYes--Yes----
Manage billingYes----------
Manage webhooksYesYes--------
Configure SSOYesYes--------
Delete organizationYes----------

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"
}'
Role Elevation

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

  1. Deny rules are evaluated first -- any matching deny rule immediately rejects the request
  2. Allow rules are evaluated second -- at least one allow rule must match
  3. 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.

OperationEndpoint
List policiesGET /v1/environments/{env_id}/policies
Create policyPOST /v1/environments/{env_id}/policies
Update policyPUT /v1/environments/{env_id}/policies/{policy_id}
Delete policyDELETE /v1/environments/{env_id}/policies/{policy_id}
List ABAC policiesGET /v1/environments/{env_id}/abac-policies
Create ABAC policyPOST /v1/environments/{env_id}/abac-policies
Simulate policyPOST /v1/environments/{env_id}/abac-policies/simulate
Agent summaryGET /v1/environments/{env_id}/abac-policies/agent-summary

Next Steps

Stay in the loop

Product updates, engineering deep-dives, and agent-native insights. No spam.