Row-Level Security
Implement fine-grained data access controls with context filters and user context.
Row-level security (RLS) ensures that each user only sees the data they’re authorized to access. Inconvo implements RLS through context filters that are applied automatically to every query.
Single-level: Organisation scoping
Section titled “Single-level: Organisation scoping”The most common pattern — every queryable table is filtered by organisationId. You set a context filter on each table individually:
WHERE orders.organisation_id = userContext.organisationId;WHERE users.organisation_id = userContext.organisationId;WHERE products.organisation_id = userContext.organisationId;const conversation = await inconvo.agents.conversations.create(agentId, { userIdentifier: "user_123", userContext: { organisationId: 1, },});Multi-level: Organisation + Team
Section titled “Multi-level: Organisation + Team”Some tables should be scoped to the organisation, while others should be further restricted to a team:
-- Organisation-level tables (orders, products, etc.)WHERE orders.organisation_id = userContext.organisationId;
-- Team-level tables (projects, tasks, etc.)WHERE projects.team_id = userContext.teamId;const conversation = await inconvo.agents.conversations.create(agentId, { userIdentifier: "user_123", userContext: { organisationId: 1, teamId: 42, },});User-level: Personal data
Section titled “User-level: Personal data”For tables containing personal data (notes, drafts, preferences):
WHERE notes.user_id = userContext.userId;Mixed scoping
Section titled “Mixed scoping”You can combine different scoping levels across tables in the same agent:
| Table | Scope | Filter |
|---|---|---|
orders | Organisation | organisation_id = userContext.organisationId |
projects | Team | team_id = userContext.teamId |
notes | User | user_id = userContext.userId |
products | Organisation | organisation_id = userContext.organisationId |
The corresponding userContext would include all required fields:
userContext: { organisationId: 1, teamId: 42, userId: "user_123",}Testing your RLS setup
Section titled “Testing your RLS setup”- Create two conversations with different
userContextvalues - Ask the same question in both (e.g. “How many orders do we have?”)
- Verify each returns only the expected data for their context
- Check the traces to confirm context filters were applied
Common mistakes
Section titled “Common mistakes”| Mistake | Impact | Fix |
|---|---|---|
| Missing filter on a table | Data leaks across tenants | Add context filters to every Queryable table |
| Wrong column in filter | Queries fail or return wrong data | Double-check column names match your schema |
Forgetting to pass userContext | 400 Invalid userContext error | Always pass all required context fields when creating conversations |