Skip to main content
Views combined with Role-Based Access Control (RBAC) in Firebolt are very flexible and allow you to implement many important real-world security scenarios. This approach uses the owner rights model that Firebolt applies to views, where access to underlying data is checked against the view owner’s permissions rather than the querying user’s permissions. This guide walks through three common use cases with end-to-end examples:
  1. Column-level security using views — control which columns users can see through a view.
  2. Data masking — expose columns in a transformed or redacted form rather than hiding them entirely.
  3. Row-level security — control which rows users can see.
Firebolt also supports native column-level security using GRANT SELECT (column_list) ON TABLE syntax. Native column-level security restricts column access directly at the table level without requiring views. The view-based approach described in this section remains useful when you need data masking (transforming or redacting column values) or when you want to combine column restrictions with row-level filtering.

How owner rights work in views

When a user queries a view, Firebolt checks two sets of permissions:
  1. The querying user must have SELECT on the view.
  2. The view owner (the user who created the view) must have SELECT on every underlying table or view that the view references.
The querying user does not need any direct permissions on the underlying tables. This is the owner rights model: the view owner’s privileges determine whether the view can access the base data, and the querying user’s privileges determine whether they can access the view. This model lets you grant users access to specific slices of data through views while keeping the underlying tables locked down.
If the view owner loses access to any referenced object (for example, if USAGE on the schema or SELECT on a table is revoked from the owner’s role), all users who query the view will receive an authorization error — even if their own SELECT on the view is still in place. For more details, see View permissions.

Prerequisites

Before implementing view-based security, ensure the following:
  • You have a user with privileges to create views, tables, and roles (typically an account_admin or a user with the relevant CREATE and GRANT privileges).
  • You understand RBAC basics and view permissions.
  • The database and schema already exist, and you have USAGE on both.

Column-level security using views

For direct column-level access control without views, see Column-level security. The view-based approach described here is useful when you also need data masking or row-level filtering.
Column-level security restricts which columns a user can see. To implement it, create a view that exposes only the permitted columns from the base table, then grant users SELECT on the view instead of the table. There are two approaches to choosing which columns a view exposes:
  • Allowlist — explicitly list the columns that should be visible. Any new columns added to the base table later are not visible through the view by default. This is the more restrictive approach.
  • Denylist — use the EXCLUDE clause to remove specific columns that must be secured. Any new columns added to the base table later are visible through the view by default. This is more convenient but requires you to update the view whenever a new sensitive column is added.

Example: Hiding sensitive columns

Suppose you have an employees table with sensitive salary and SSN data:
Allowlist approach — explicitly list only the columns to expose:
If a hire_date column is later added to the employees table, it will not appear in employees_public until the view is updated. Denylist approach — exclude only the sensitive columns using EXCLUDE:
If a hire_date column is later added to the employees table, it will automatically appear in employees_public. If a new sensitive column is added, you must update the EXCLUDE list. Set up roles and permissions (same for either approach):
Verify access:
Alice can query the view and see only the non-sensitive columns. She has no direct access to the employees table, so she cannot see salary or ssn.

Multiple views for different access levels

You can create multiple views on the same table to provide different levels of column visibility. You can mix and match allowlist and denylist approaches:

Row-level security

Row-level security restricts which rows a user can see. To implement it, create a view with a WHERE clause that filters rows, then grant users SELECT on the view instead of the table.

Static row-level security

Use a static filter when specific roles should see a fixed subset of rows.

Dynamic row-level security using SESSION_USER

For more flexible row-level security, use the SESSION_USER function inside a view. SESSION_USER() returns the name of the user who is running the query, so the view dynamically filters rows based on the current user. Step 1 — Create a mapping table that associates users with the data they are allowed to see:
Step 2 — Create a view that joins the base table with the mapping table using SESSION_USER():
Step 3 — Set up roles and permissions:
Step 4 — Verify access:
Both users query the same view, but each sees only the rows they are authorized to access.
The view owner must have SELECT on both the orders table and the user_region_access table. The querying users only need SELECT on the orders_secure view.

Data masking

Data masking lets users see that a column exists, but replaces the actual values with redacted or transformed versions. This is useful when users need to know that data is present — for example, to join or group on a column — without seeing the sensitive values. To implement data masking, create a view that applies transformation functions to sensitive columns. The following subsections describe common masking techniques.

Nulling out

Replace sensitive data with NULL. This is the simplest form of masking — the column is present in the result set but contains no usable value.
A query against employees_nulled returns every row, but ssn and salary are always NULL.

Substitution

Replace real data with fake but realistic values from a lookup table. This preserves the look and feel of the data, which can be useful for testing or demo environments.
Users see realistic-looking names (James Miller) instead of the real employee names.

Hashing (pseudonymization)

Use a cryptographic hash function such as MD5 to turn data into a fixed-length string. The same input always produces the same output, so hashed values can still be used for joins, grouping, and deduplication without revealing the original data.
A query returns values like c14fa496dfd5ebbb08aaca16a7c2781b instead of the real name or SSN.

Redaction (masking out)

Replace specific characters with a generic character such as * while preserving enough structure for the value to remain recognizable. This is especially useful for email addresses, phone numbers, and identifiers.
Users see emails like m...p@acme.com — enough to identify the domain and rough address without revealing the full mailbox name.

Blurring (generalization)

Replace a specific value with a range or a more general category to prevent precise identification. This is common for numeric data such as age, salary, or transaction amounts.
Instead of seeing an exact salary like 72500, users see a range like 70000-79999.

Combining masking with column exclusion

You can combine data masking with column-level security to mask some columns and hide others entirely:

Combining column-level, masking, and row-level security

You can combine all three techniques in a single view to control which columns are visible, how sensitive values are displayed, and which rows a user can see:
This view hides internal_notes entirely, masks amount into a rounded range, and filters rows based on the querying user’s region access.

Managing view ownership

The owner rights model means that the view owner’s permissions are critical. Keep the following best practices in mind:
  • Use a dedicated admin user or role to create security views. This ensures the view owner always has the necessary permissions on the underlying tables.
  • Do not revoke base table permissions from the view owner. If the view owner loses SELECT on a referenced table or USAGE on the schema, all queries through the view will fail.
  • Transfer ownership deliberately. If you need to change the view owner, use ALTER VIEW to transfer ownership and ensure the new owner has all required permissions:
    For more information about ownership, see Ownership.
  • Audit view ownership regularly. Query information_schema.views to check who owns each view and verify they still have the correct permissions:

Setting up default privileges for security views

If you create security views regularly, use ALTER DEFAULT PRIVILEGES to automatically grant SELECT on new views to the appropriate roles:
This ensures that every new view created in the account is automatically accessible to analyst_role, reducing manual grant overhead.

Summary

In all cases, the owner rights model ensures that:
  • The view owner’s permissions on underlying tables control whether the view can access the data.
  • The querying user only needs SELECT on the view, not on the underlying tables.