4.5 KiB
4.5 KiB
Project: Farmer Portal AI Agent
Created: 2026-02-25
Source: #work-assistant
Status: Planning
Overview
Implement an AI agent for the farmer portal that provides detailed data analysis while maintaining strict row-level security isolation per farmer.
Background
Farmers currently access daily delivery reports via a form-driven web interface. They can search their historical data but need a conversational interface for deeper insights. The critical requirement: agent can ONLY access the currently logged-in farmer's data — no cross-farm data access possible.
Current Architecture
- Existing token-based authentication
- Row-level security (RLS) already implemented for web UI
- Farmers "locked" to their data via session tokens
- No accidental data overlap in current system
Goal
Add an AI agent interface that:
- Provides conversational access to farmer data
- Uses existing RLS/session infrastructure
- Maintains same security guarantees as current form-based search
- Cannot be bypassed via prompt engineering or user manipulation
Technical Approach
Security Model (Layered)
| Layer | Implementation | Responsibility |
|---|---|---|
| 1. Session/Auth | Existing token validation | Verify farmer identity |
| 2. API Gateway | Inject farmer_id from session | Never accept ID from user/agent |
| 3. Database RLS | SQL policies on farmer_id | Hard enforcement at data layer |
| 4. Agent Context | Read-only session injection | Agent sees farmer_id as context, not input |
Data Flow
Farmer Login → Session Token (farmer_id: "FARMER_2847")
↓
Farmer Asks Agent → Request includes session token
↓
API Validates → Extracts farmer_id from session
↓
Agent Tool Call → API injects farmer_id, ignores any agent-provided ID
↓
Database Query → RLS policy: WHERE farmer_id = session_farmer_id
↓
Response → Filtered results returned to agent
Components
1. Session-Aware API Endpoints
- Extend existing API for agent access
- Endpoint:
POST /api/agent/query - Session token extracted from headers (same as web UI)
- Agent tools call these endpoints, never direct DB access
2. MCP Tool Design (if using MCP)
@mcp.tool()
def query_farmer_deliveries(ctx: Context, date_range: str, commodity: str = None):
"""Query farmer's delivery history."""
farmer_id = ctx.session["farmer_id"] # Injected by app, not agent
return api_client.post("/api/agent/query", {
"farmer_id": farmer_id, # Server-side only
"date_range": date_range,
"commodity": commodity
})
3. Agent Context Injection
System prompt includes:
You are helping a farmer view their own delivery data.
Farmer ID: {{farmer_id}} (read-only context)
Access Level: Self-data only
You can:
- Search their historical deliveries
- Summarize trends
- Compare time periods
- Answer questions about their data
You CANNOT:
- Access other farmers' data
- Accept farmer_id from user (it's already set)
- Bypass database filters
4. Database RLS (Existing)
- SQL Server: Row-level security policies
- PostgreSQL:
CREATE POLICYper farmer_id - Middleware:
SET LOCAL app.current_user_id = ?
Key Principles
✅ Do
- Derive farmer_id exclusively from validated session
- Pass farmer_id via secure context/cookies, not parameters
- Use existing RLS policies (no new security model)
- Log all agent queries with farmer_id for audit
- Treat agent as untrusted — all enforcement at API/DB layer
❌ Don't
- Ever accept farmer_id from user/agent input
- Allow agent to construct raw SQL with farmer_id
- Trust prompt instructions to enforce security
- Give agent database credentials
Tasks
- Design agent API endpoints (extend existing auth)
- Create MCP tools or API client with session injection
- Implement agent context (farmer_id read-only)
- Write system prompt with security boundaries
- Add audit logging for agent queries
- Test with farm boundary verification (attempt cross-farm access)
- Deploy to staging
- Farmer acceptance testing
Related Projects
- Requisition and Purchase Order System — similar multi-tenant pattern
- Scale projects — may need similar agent integration later
Notes
(Add technical decisions, vendor discussions, security review notes here)
Created from Discord discussion on AI agent data isolation