Row-Level Permission
In Veezoo, we provide a method to achieve row-level authorization using SQL templating with the virtual_table
feature. This allows for custom data access restrictions down to the row level based on user-specific values.
SQL Templating
SQL templating allows parts of your SQL properties to be adjusted dynamically based on user-specific values. For example, you can use it to compare a user's email with a column in your table.
Support
Currently, SQL templating is supported in the following locations:
- Identifiers of database/schema/table/column
- Including database identifier in DB connection
- Virtual table SQL
Templating Language
Template sections are marked using ${...}
and will be transformed to SQL on execution. The templating expression inside ${...}
consists of a small DSL supporting:
- Accessing user attributes using syntax
user_attribute("attribute_name")
- Direct variables, e.g.
veezoo.Tenant.Id
. - Functions with syntax
function(...)
- The
quote
andraw
functions are used to convert strings to SQL code string_list
is used for lists of strings, mapping them to an expression usable withIN
in SQL
- The
Pre-Defined Attributes and Variables
The following user attributes can be accessed through the user_attribute
function, e.g. ${user_attribute("veezoo.User.Email")}
:
- veezoo.User.First_Name
- veezoo.User.Full_Name
- veezoo.User.Email
- veezoo.User.Roles (list of values, which may require
string_list
for SQL)
In addition, you can access custom user attributes as specified by SAML or JWT.
The following attributes can be accessed directly, e.g. ${veezoo.Tenant.Id}
:
Row-Level Authorization
To implement row-level authorization, you can transform a table into a virtual_table and include user-specific SQL templates.
import: [
db.postgres.orders_db.public.ORDERS
]
db.orders_db.public {
virtual_table orders {
identifier: "orders"
virtual_table_sql:
"""
SELECT
o.*
FROM
"orders_db"."public"."orders" o
WHERE
o."customer_email" = ${quote(user_attribute("veezoo.User.Email"))}
"""
...
}
}
In the example above, the virtual_table_sql
will only return the rows of the orders
table where the customer_email
matches the logged-in user's email.
As another example in the case of Multi-Tenant Self-Service Analytics, we can restrict the data based on the tenant ID.
db.storage.hiring_app {
virtual_table candidates {
identifier: "candidates"
# Only show candidates from the current tenant
virtual_table_sql:
"""
SELECT
*
FROM
candidates c
WHERE
c.company_id = ${quote(veezoo.Tenant.Id)}
"""
column ID {
identifier: "ID"
is_primary_key: true
primitive_type: "varchar"
}
...
}
}
By using row-level authorization, you can enhance your data security and maintain a high degree of data access control within Veezoo. Remember to always review your SQL templates to ensure that they are accurate and efficient.