Skip to content

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.

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,
},
});

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,
},
});

For tables containing personal data (notes, drafts, preferences):

WHERE notes.user_id = userContext.userId;

You can combine different scoping levels across tables in the same agent:

TableScopeFilter
ordersOrganisationorganisation_id = userContext.organisationId
projectsTeamteam_id = userContext.teamId
notesUseruser_id = userContext.userId
productsOrganisationorganisation_id = userContext.organisationId

The corresponding userContext would include all required fields:

userContext: {
organisationId: 1,
teamId: 42,
userId: "user_123",
}
  1. Create two conversations with different userContext values
  2. Ask the same question in both (e.g. “How many orders do we have?”)
  3. Verify each returns only the expected data for their context
  4. Check the traces to confirm context filters were applied
MistakeImpactFix
Missing filter on a tableData leaks across tenantsAdd context filters to every Queryable table
Wrong column in filterQueries fail or return wrong dataDouble-check column names match your schema
Forgetting to pass userContext400 Invalid userContext errorAlways pass all required context fields when creating conversations