Overview
The REPOSITORY schema includes a set of VW_SECURE_DATASET_* views that mirror the base VW_DATASET_* views but add row-level security filtering. These secure views enforce the same permissions that exist in the Validatar application — ensuring that users querying the replicated data only see objects they are authorized to access.
Validatar's permission model operates on two independent axes: data source permissions and project permissions. Different views are filtered by different permission types depending on the nature of the data they expose.
The Permission Model
Two Permission Axes
| Permission Axis | Controls Access To | Granted Via |
|---|---|---|
| Data Source Permissions | Metadata objects — schemas, tables, columns, profiles | ViewMetadata role on the data source |
| Project Permissions | Tests, jobs, folders, schedules | Project membership |
These are independent — a user can have access to a data source's metadata without being a member of any project that uses it, and vice versa.
Three Security Tiers in the Secure Views
The secure views use one of three filtering strategies depending on what data they expose:
| Tier | Filter | Used By | Reasoning |
|---|---|---|---|
| Data Source | User must have ViewMetadata on the data source | Tables, Columns, Metadata Objects | These views expose metadata catalog information owned by data sources |
| Project | User must be a member of the project | Tests, Jobs, Job Executions | These views expose test/job configuration that lives within projects |
| Combined (Results) | User must have BOTH project membership AND ViewTestResults on the test's data source | Test Executions, Template Test Executions | Results span both domains — you need project access to see the test AND data source access to see its results |
Event History: Context-Dependent Filtering
VW_SECURE_DATASET_EVENT_HISTORY uses a hybrid approach based on the event's context type:
- Project context events — filtered by project membership
- Data Source context events — filtered by data source ViewMetadata permission
- Global context events — visible to all users (USER_ID is NULL)
Available Secure Views
Data Source Permission (ViewMetadata)
These views filter rows based on VW_SECURE_USER_DATA_SOURCE_ACCESS — the user must have ViewMetadata permission on the data source:
| Base View | Secure View | Join Key |
|---|---|---|
| VW_DATASET_TABLES | VW_SECURE_DATASET_TABLES | DATA_SOURCE_ID |
| VW_DATASET_COLUMNS | VW_SECURE_DATASET_COLUMNS | DATA_SOURCE_ID |
| VW_DATASET_METADATA_OBJECTS | VW_SECURE_DATASET_METADATA_OBJECTS | DATA_SOURCE_ID |
Project Permission (Project Membership)
These views filter rows based on VW_SECURE_USER_PROJECT_ACCESS — the user must be a member of the project:
| Base View | Secure View | Join Key |
|---|---|---|
| VW_DATASET_TESTS | VW_SECURE_DATASET_TESTS | PROJECT_ID |
| VW_DATASET_JOBS | VW_SECURE_DATASET_JOBS | PROJECT_ID |
| VW_DATASET_JOB_EXECUTIONS | VW_SECURE_DATASET_JOB_EXECUTIONS | PROJECT_ID |
Combined Permission (Project + Data Source ViewTestResults)
These views filter rows based on VW_SECURE_USER_RESULTS_ACCESS — the user must have BOTH project membership AND the ViewTestResults data source permission:
| Base View | Secure View | Join Keys |
|---|---|---|
| VW_DATASET_TEST_EXECUTIONS | VW_SECURE_DATASET_TEST_EXECUTIONS | PROJECT_ID + TEST_DATA_SOURCE_ID + CONTROL_DATA_SOURCE_ID |
| VW_DATASET_TEMPLATE_TEST_EXECUTIONS | VW_SECURE_DATASET_TEMPLATE_TEST_EXECUTIONS | PROJECT_ID + META_DATA_SOURCE_ID + CONTROL_DATA_SOURCE_ID |
For test executions, the user must have results access to both the test-side and control-side data sources (when a control data source exists). If the test has no control data source, only test-side access is required.
Context-Dependent (Event History)
| Base View | Secure View | Filter Logic |
|---|---|---|
| VW_DATASET_EVENT_HISTORY | VW_SECURE_DATASET_EVENT_HISTORY | Project events → project access; Data Source events → data source access; Global events → visible to all |
Access Resolution
Data Source Access (VW_SECURE_USER_DATA_SOURCE_ACCESS)
A user gains data source access through any of these paths:
| Path | Description |
|---|---|
| Explicit user permission | Direct ViewMetadata role assignment to the user |
| Group permission | ViewMetadata role assigned to a user group the user belongs to |
| Global Admin | Users with Global.Admin role have access to all data sources |
| Global Data Source Admin | Users with Global.DataSourceAdmin role have access to all data sources |
| Data Source Owner | The user who owns the data source has full access |
Schema:
| Column | Type | Description |
|---|---|---|
| META_DATA_SOURCE_ID | NUMBER | Data source ID |
| USER_ID | NUMBER | User ID |
| ACCESS_TYPE | VARCHAR | How access was granted (e.g., "User - View Metadata", "Group - View Metadata", "Data Source Owner", "Multiple") |
Project Access (VW_SECURE_USER_PROJECT_ACCESS)
A user gains project access by being added as a project member (directly or via a user group):
| Path | Description |
|---|---|
| Direct membership | User added directly to the project |
| Group membership | User is a member of a user group added to the project |
Schema:
| Column | Type | Description |
|---|---|---|
| PROJECT_ID | NUMBER | Project ID |
| USER_ID | NUMBER | User ID |
| ACCESS_TYPE | VARCHAR | "User", "Group", or "User and Group" |
Results Access (VW_SECURE_USER_RESULTS_ACCESS)
The compound view that requires BOTH data source and project access. It resolves the intersection of:
- User has ViewTestResults permission on the data source (not just ViewMetadata)
- User is a project member for a project that uses that data source
Schema:
| Column | Type | Description |
|---|---|---|
| META_DATA_SOURCE_ID | NUMBER | Data source ID |
| PROJECT_ID | NUMBER | Project ID |
| USER_ID | NUMBER | User ID |
This view is built by joining PROJECT_DATA_SOURCES (which data sources are used in which projects) with the user's data source ViewTestResults permissions and project membership. A row only exists when the user satisfies both conditions.
Secure View Schema (Additional Columns)
Every VW_SECURE_DATASET_* view includes all columns from its base view plus:
| Column | Type | Description |
|---|---|---|
| USER_ID | NUMBER | The Validatar user ID who has access to this row |
| ACCESS_TYPE | VARCHAR | How access was granted (present on data source and project filtered views; absent on results-filtered views) |
Note: VW_SECURE_DATASET_TEST_EXECUTIONS and VW_SECURE_DATASET_TEMPLATE_TEST_EXECUTIONS only add USER_ID (no ACCESS_TYPE column) because access is resolved through the compound results view.
VW_DATASET_EFFECTIVE_USER_PERMISSIONS
A comprehensive audit view of all effective permissions across data sources, projects, and reports — including both explicit assignments and implicit permissions (from global roles and ownership). This view resolves all permission inheritance into a flat list.
| Column | Type | Description |
|---|---|---|
| USER_LOGIN_NAME | VARCHAR | User's login name |
| USER_FIRST_NAME | VARCHAR | First name |
| USER_LAST_NAME | VARCHAR | Last name |
| USER_EMAIL | VARCHAR | Email address |
| USER_DATE_LAST_LOGIN | TIMESTAMP | Last login date |
| USER_DATE_CREATED | TIMESTAMP | User creation date |
| USER_DATE_MODIFIED | TIMESTAMP | User modification date |
| USER_CREATED_BY | VARCHAR | Who created the user |
| USER_MODIFIED_BY | VARCHAR | Who last modified the user |
| USER_TIME_ZONE | VARCHAR | User's configured time zone |
| OBJECT_TYPE | VARCHAR | "Data Source", "Project", or "Report" |
| OBJECT_ID | NUMBER | ID of the object |
| OBJECT_NAME | VARCHAR | Name of the object |
| PERMISSION_NAME | VARCHAR | Specific permission/role name (e.g., "Manage Permissions", "Manage Connections", "View Metadata", "Project Admin") |
| PERMISSION_DATE_CREATED | TIMESTAMP | When the permission was granted |
| PERMISSION_DATE_MODIFIED | TIMESTAMP | When the permission was last modified |
| PERMISSION_CREATED_BY | VARCHAR | Who granted the permission |
| PERMISSION_MODIFIED_BY | VARCHAR | Who last modified the permission |
How to Use Secure Views
Filtering by User
The secure views contain one row per user per object. To see what a specific user can access, filter by their USER_ID:
-- What tables can user 42 see? (data source permission)
SELECT
TABLE_NAME,
SCHEMA_NAME,
DATA_SOURCE_NAME,
TRUST_SCORE,
ACCESS_TYPE
FROM REPOSITORY.VW_SECURE_DATASET_TABLES
WHERE USER_ID = 42
ORDER BY DATA_SOURCE_NAME, FULL_PATH;
-- What tests can user 42 see? (project permission)
SELECT
TEST_NAME,
PROJECT_NAME,
TEST_TYPE,
OVERALL_RESULT_STATUS,
ACCESS_TYPE
FROM REPOSITORY.VW_SECURE_DATASET_TESTS
WHERE USER_ID = 42
ORDER BY PROJECT_NAME, TEST_NAME;
-- What test executions can user 42 see? (requires both project + data source)
SELECT
TEST_NAME,
PROJECT_NAME,
RESULT,
DATE_COMPLETED,
TEST_DATA_SOURCE
FROM REPOSITORY.VW_SECURE_DATASET_TEST_EXECUTIONS
WHERE USER_ID = 42
AND LATEST_TEST_EXECUTION_INDEX = 1
ORDER BY DATE_COMPLETED DESC;
Finding a User ID
SELECT DISTINCT
USER_ID,
USER_LOGIN_NAME,
USER_FIRST_NAME,
USER_LAST_NAME,
USER_EMAIL
FROM REPOSITORY.VW_DATASET_EFFECTIVE_USER_PERMISSIONS
WHERE USER_EMAIL = 'john.smith@company.com';
Example Queries
Audit: Which Users Can See a Specific Data Source
SELECT
USER_ID,
ACCESS_TYPE
FROM REPOSITORY.VW_SECURE_USER_DATA_SOURCE_ACCESS
WHERE META_DATA_SOURCE_ID = 28
ORDER BY USER_ID;
Audit: Which Users Are Members of a Project
SELECT
USER_ID,
ACCESS_TYPE
FROM REPOSITORY.VW_SECURE_USER_PROJECT_ACCESS
WHERE PROJECT_ID = 5
ORDER BY USER_ID;
Audit: Who Has Results Access (Both Project + Data Source)
SELECT
r.USER_ID,
r.PROJECT_ID,
r.META_DATA_SOURCE_ID,
p.USER_LOGIN_NAME,
p.USER_EMAIL
FROM REPOSITORY.VW_SECURE_USER_RESULTS_ACCESS r
JOIN REPOSITORY.VW_DATASET_EFFECTIVE_USER_PERMISSIONS p
ON p.USER_ID = r.USER_ID
AND p.OBJECT_TYPE = 'Project'
AND p.OBJECT_ID = r.PROJECT_ID
WHERE r.PROJECT_ID = 5
GROUP BY r.USER_ID, r.PROJECT_ID, r.META_DATA_SOURCE_ID,
p.USER_LOGIN_NAME, p.USER_EMAIL;
Permission Gap: Users with Project Access but Missing Data Source Access
-- Find users who can see tests but not the underlying metadata
SELECT
pa.USER_ID,
pa.PROJECT_ID,
pds.META_DATA_SOURCE_ID,
mds.NAME AS DATA_SOURCE_NAME
FROM REPOSITORY.VW_SECURE_USER_PROJECT_ACCESS pa
CROSS JOIN PROJECT_DATA_SOURCES pds
INNER JOIN META_DATA_SOURCES mds ON mds.ID = pds.META_DATA_SOURCE_ID
WHERE pds.PROJECT_ID = pa.PROJECT_ID
AND pds.IS_ACTIVE = TRUE
AND NOT EXISTS (
SELECT 1
FROM REPOSITORY.VW_SECURE_USER_DATA_SOURCE_ACCESS dsa
WHERE dsa.USER_ID = pa.USER_ID
AND dsa.META_DATA_SOURCE_ID = pds.META_DATA_SOURCE_ID
);
Compare Visibility Across Permission Tiers
-- For user 42: what can they see at each tier?
SELECT 'Data Sources (metadata)' AS TIER, COUNT(DISTINCT DATA_SOURCE_ID) AS COUNT
FROM REPOSITORY.VW_SECURE_DATASET_TABLES WHERE USER_ID = 42
UNION ALL
SELECT 'Projects (tests/jobs)', COUNT(DISTINCT PROJECT_ID)
FROM REPOSITORY.VW_SECURE_DATASET_TESTS WHERE USER_ID = 42
UNION ALL
SELECT 'Results (executions)', COUNT(*)
FROM REPOSITORY.VW_SECURE_DATASET_TEST_EXECUTIONS
WHERE USER_ID = 42 AND LATEST_TEST_EXECUTION_INDEX = 1;
Data Sources a User Cannot Access
SELECT DISTINCT t.DATA_SOURCE_NAME, t.DATA_SOURCE_ID
FROM REPOSITORY.VW_DATASET_TABLES t
WHERE NOT EXISTS (
SELECT 1
FROM REPOSITORY.VW_SECURE_USER_DATA_SOURCE_ACCESS sec
WHERE sec.META_DATA_SOURCE_ID = t.DATA_SOURCE_ID
AND sec.USER_ID = 42
);
Users with Global Admin Access
SELECT DISTINCT
USER_LOGIN_NAME,
USER_EMAIL,
USER_DATE_LAST_LOGIN,
PERMISSION_NAME
FROM REPOSITORY.VW_DATASET_EFFECTIVE_USER_PERMISSIONS
WHERE PERMISSION_NAME IN ('Global Admin', 'Global Data Source Admin')
ORDER BY USER_LOGIN_NAME;
Important Considerations
Performance
Secure views perform a join to the access resolution views on every query. For large environments, this adds overhead. Always filter by USER_ID early.
Row Multiplication
Because secure views contain one copy of each row per authorized user, queries without a USER_ID filter return significantly more rows than the base views. Always filter by USER_ID unless you're intentionally analyzing cross-user access patterns.
ViewMetadata vs ViewTestResults
These are different data source permissions:
- ViewMetadata — grants visibility into the metadata catalog (schemas, tables, columns, profiles). Used by the metadata-filtered secure views.
- ViewTestResults — grants visibility into test execution results for that data source. Used (in combination with project access) by the results-filtered secure views.
A user can have ViewMetadata without ViewTestResults (they can see the catalog but not execution results), or vice versa.
When to Use Base vs Secure Views
| Use Case | Recommended View |
|---|---|
| Admin reporting (full visibility) | Base VW_DATASET_* views |
| User-facing metadata dashboards | VW_SECURE_DATASET_TABLES/COLUMNS with USER_ID filter |
| User-facing test/job dashboards | VW_SECURE_DATASET_TESTS/JOBS with USER_ID filter |
| User-facing results dashboards | VW_SECURE_DATASET_TEST_EXECUTIONS with USER_ID filter |
| Permission auditing | VW_DATASET_EFFECTIVE_USER_PERMISSIONS |
| System-level analytics | Base VW_DATASET_* views |
| Embedded analytics with SSO | VW_SECURE_DATASET_* with mapped USER_ID |
Databricks Notes
- Replace
DATEADD(day, -30, CURRENT_DATE)withDATE_ADD(CURRENT_DATE(), -30) - The permission model and view structure is identical between Snowflake and Databricks
- In Databricks, you may additionally layer Unity Catalog row-level security on top of these views for native enforcement