Row-Level Access Control builds upon StarTree’s Role-Based Access Control (RBAC) system. Ensure you have RBAC enabled before implementing row-level policies.
How Row-Level Access Control Works
Unlike table-level RBAC which provides all-or-nothing access to a table, Row-Level Access Control allows you to define conditions that determine which rows a user can access within a table. When a user with row-level policies queries a table, StarTree automatically:- Identifies the user’s assigned roles and associated row-level policies
- Extracts the row filter conditions from the policies
- Applies these conditions as additional WHERE clauses to the query
- Returns only the rows that match both the original query and the row filter conditions
Policy Configuration
Row-level policies use the same structure as standard RBAC policies but include aconditions section with rowFilters:
Row Filter Syntax
Single Condition Filters
Row filters are valid SQL expressions that can be used in WHERE clauses:Multi-Condition Filters
Combine multiple conditions using SQL operators:Dynamic Row Filters (available from Startree release 0.17)
Static row filters work well when you can enumerate every value up front — for example, writing one policy per vendor ID. For multi-tenant applications where the tenant (or user, region, account, etc.) isn’t known until query time, you can write one policy with a placeholder, and have StarTree fill it in automatically from a value the caller supplies with the query.Dynamic row filters use the same policy structure as static row filters — the only difference is the filter text contains a placeholder instead of a literal value.
Placeholder Syntax
A placeholder has the form${parameterName} or ${parameterName:TYPE}:
STRING. Supported types:
A placeholder must stand in for a whole value being compared to a column — for example on the right-hand side of
=, >, BETWEEN, or inside an IN (...) list:
Supplying Values at Query Time
The caller supplies each placeholder’s value as a URL query parameter on the HTTP request to the query endpoint — it is not part of the SQL text itself. For example, with the policy above (tenant_id = ${tenant_id}), the query request becomes:
tenant_id=acme_corp off the request URL, substitutes it into the policy’s row filter as a properly typed, escaped literal, and applies it the same way a static row filter is applied — the caller never needs to (and cannot) write the filter into the SQL itself.
This is particularly useful for embedded or white-labeled dashboards, where a single widget or service account queries on behalf of many tenants, and the tenant identifier is known to the embedding application at query time but shouldn’t be hard-coded per-tenant into a policy.
Validation and Error Handling
Every value is validated before the query runs; nothing partial is ever returned:- A required parameter that is missing or empty fails the query.
- A parameter supplied more than once (ambiguous) fails the query.
- A value that doesn’t match its declared type (for example, non-numeric text for an
INTplaceholder) fails the query.
Implementation Steps
Row-Level Access Control follows the same implementation process as any other RBAC policy:- Create a policy with row filter conditions in the Security Manager
- Create a role and attach the policy to it
- Assign the role to users or groups
conditions section with rowFilters to your policy configuration.
You can use the StarTree Security Manager UI to apply these policies.
Use Cases
Vendor Data Isolation
Allow vendors to see only their own orders in a shared table:Sales Territory Management
Restrict sales reps to view only their assigned accounts:Regional Data Compliance
Enforce data residency by region within a global table:Multi-Tenant Embedded Dashboards
Serve every tenant from one policy, with the embedding application supplying the tenant at query time:Limitations
- Row-level policies may take up to one hour to propagate and become effective after creation or modification.
- Dynamic row filter values must be supplied as URL query parameters on the HTTP request to the query endpoint. This is not available on access paths that don’t expose a URL query string.
- Exactly one value is required per placeholder on each request — zero, empty, or multiple values for the same parameter name fail the query.
- Placeholder values are strictly typed (
STRING,INT,LONG,FLOAT,DOUBLE,BOOLEAN); a value that doesn’t match its declared type fails the query rather than being coerced. - String placeholder values are limited to 1024 characters and may not contain control characters.
- The parameter names
sql,trace,getcursor,numrows, andoffsetare reserved by the query API and cannot be used as placeholder names.
Next Steps
- Learn about Custom Policy Configuration
- Explore RBAC API usage
- Review Security Actions available for policies

