Agent Identity Model
Agents acquire their identity through self-registration. Read Agent Registry first to understand how agents register before reading about the identity model.
Every AI agent connecting to HatiData carries a unique identity — and that identity determines what the agent can see, do, and how much it costs.
Why Agents Need Identity
When dozens of agents share a data layer, you need answers to questions that traditional databases never ask:
- Who ran this query? — Audit attribution to a specific agent, not just a database user
- What can this agent access? — Fine-grained scopes beyond read/write
- How much did this agent cost? — Per-agent billing for cost allocation
- Should this query be allowed? — ABAC policies that match on agent identity, framework, and time of day
HatiData's identity model answers all of these by making agent identity a first-class concept in the data layer.
How Agents Identify Themselves
Agents pass identity through Postgres startup parameters when they connect:
| Parameter | Purpose | Example |
|---|---|---|
agent_id | Unique agent identifier | analytics-agent-1 |
framework | AI framework name | langchain, crewai, autogen, custom |
request_id | Optional per-request trace ID | req-abc-123 |
priority | Query priority | low, normal, high, critical |
These parameters flow through the entire multi-stage query pipeline:
- Policy evaluation uses
agent_idandframeworkfor ABAC rules - Row-level security resolves
{agent_id}placeholders in WHERE filters - Metering tracks per-agent credit usage for billing
- Audit records agent identity in every log entry
- Scheduling uses
priorityto order queued queries
from hatidata_agent import HatiDataAgent
agent = HatiDataAgent(
host="your-org.proxy.hatidata.com",
agent_id="my-agent", # Sent as startup parameter
framework="langchain", # Sent as startup parameter
password="hd_live_your_key", # Used for authentication
)
API Key Format
Keys follow a predictable format that indicates their environment:
| Prefix | Environment | Example |
|---|---|---|
hd_live_ | Production | hd_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 |
hd_test_ | Development / Test | hd_test_x9y8z7w6v5u4t3s2r1q0p9o8n7m6l5k4 |
Production keys have full billing metering. Test keys do not count toward billing quotas.
Scopes
Keys are authorized using 22 granular scopes organized into four bundles:
| Bundle | Scopes Included | Use Case |
|---|---|---|
read_only | query:read, tables:list, tables:describe, schemas:read, audit:read | BI tools, read-only agents |
developer | All read_only + query:write, tables:create, tables:alter, functions:execute, branches:create, branches:merge | Development agents, CI/CD |
admin | All developer + users:manage, keys:manage, policies:manage, orgs:manage, billing:manage, webhooks:manage | Human administrators |
agent | query:read, query:write, tables:list, tables:describe, memory:read, memory:write, cot:write, triggers:read, branches:create | AI agents with standard capabilities |
All 22 Scopes
| Scope | Description |
|---|---|
query:read | Execute SELECT queries |
query:write | Execute INSERT, UPDATE, DELETE |
tables:list | List available tables |
tables:describe | Get column schemas |
tables:create | Create new tables |
tables:alter | Modify table schemas |
schemas:read | Read schema metadata |
functions:execute | Execute stored functions |
memory:read | Search and retrieve agent memories |
memory:write | Store new agent memories |
cot:write | Write chain-of-thought traces |
triggers:read | List and test semantic triggers |
triggers:manage | Create, update, delete triggers |
branches:create | Create state branches |
branches:merge | Merge branches back to main |
audit:read | Read audit logs |
users:manage | Create and manage users |
keys:manage | Create and revoke API keys |
policies:manage | Create and manage ABAC policies |
orgs:manage | Manage organization settings |
billing:manage | View and manage billing |
webhooks:manage | Manage webhook subscriptions |
Creating Keys
Via the Dashboard
- Navigate to Settings > API Keys
- Click Create Key
- Set name, scope bundle, agent ID, expiration, and IP allowlist
- Copy the key immediately — it will not be shown again
Via the API
curl -X POST https://control.hatidata.com/v1/api-keys \
-H "Authorization: Bearer hd_live_admin_key" \
-H "Content-Type: application/json" \
-d '{
"name": "langchain-agent-prod",
"scopes": ["query:read", "tables:list", "tables:describe", "memory:read", "memory:write"],
"agent_id": "langchain-prod-01",
"expires_at": "2026-01-01T00:00:00Z",
"ip_allowlist": ["10.0.1.0/24", "172.16.0.0/16"]
}'
Via Python SDK
admin = HatiDataAgent(
host="control.hatidata.com",
port=8080,
agent_id="admin",
password="hd_live_admin_key",
)
key = admin.create_api_key(
name="crewai-analyst",
scopes=["query:read", "tables:list", "tables:describe", "memory:read", "memory:write", "cot:write"],
agent_id="crewai-analyst-01",
expires_at="2026-06-01T00:00:00Z",
)
IP Allowlisting
Keys can be restricted to specific IP addresses or CIDR ranges:
{
"ip_allowlist": ["10.0.1.100", "10.0.2.0/24", "172.16.0.0/16"]
}
Requests from unlisted IPs are rejected with 403 Forbidden. For agent deployments:
- Kubernetes — Use the pod CIDR range
- Cloud Run / Lambda — Use the service's NAT gateway IP
- Local development — Leave empty (all IPs allowed)
Capability Grants
Beyond scopes (API-level access), capability grants provide data-level controls:
Table Allowlists
{
"agent_id": "analyst-01",
"capabilities": {
"allowed_tables": ["customers", "orders", "products"],
"denied_tables": ["internal_metrics", "employee_data"]
}
}
Query Count Limits
{
"agent_id": "analyst-01",
"capabilities": {
"max_queries_per_hour": 1000,
"max_queries_per_day": 10000
}
}
Time-Bounded Access
{
"agent_id": "contractor-agent",
"capabilities": {
"allowed_tables": ["public_data"],
"expires_at": "2025-02-01T00:00:00Z"
}
}
Per-Agent Billing
Every query is metered and attributed to the agent's identity:
SELECT
agent_id, framework,
COUNT(*) as query_count,
SUM(credits_used) as total_credits,
AVG(duration_ms) as avg_latency_ms
FROM _hatidata_audit_log
WHERE created_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY agent_id, framework
ORDER BY total_credits DESC;
Credit Tracking
| Factor | Credit Weight |
|---|---|
| Base query | 1 credit |
| Per table scanned | +0.5 credits |
| Full table scan (no WHERE) | +2 credits |
SELECT * (all columns) | +1 credit |
| Result set > 10,000 rows | +1 credit per 10K rows |
Quota Enforcement
Per-organization credit limits are enforced at query time. When a query would exceed remaining credits, it is rejected with QUOTA_EXCEEDED.
Best Practices
- Rotate production keys every 90 days — Create a new key, update agent configs, revoke the old key
- Grant minimum scopes — Read-only agents should use the
read_onlybundle - Use descriptive agent IDs — Include environment (e.g.,
langchain-revenue-analyst-prod) - Always set IP allowlists for production — Use CIDR ranges for dynamic environments
Related Concepts
- Security Model — RBAC, ABAC, and the full security architecture
- Persistent Memory — Memory scoped by agent identity
- Cost Model — Per-agent billing details