Skip to main content

Data Access Controls

Squid's data access control model is fundamentally different from traditional table-based access. Instead of granting access to tables and then restricting columns, Squid uses database views to define precisely what data is available.

Views: The First Line of Defense

Squid does not directly access ServiceNow tables. All data access goes through ServiceNow database views.

Database Views: The First Line of DefenseSquid does not directly access ServiceNow tables. All data access goes through ServiceNow database views, which serve as the first line of defense for data security. WHY VIEWS PROVIDE SECURITY: (1) Explicit Column Selection - Only columns defined in the view are accessible through Squid. Columns not in the view simply do not exist from Squid's perspective. (2) No Accidental Exposure - When new columns are added to ServiceNow tables, they do not automatically appear in Squid responses. They must be explicitly added to the view first. (3) Join Control - Views define which related tables are joined and exposed. You control exactly which relationships are available. (4) Single Point of Control - Changing the view definition changes all Squid configurations that use that view. EXAMPLE - ServiceNow cmdb_ci table: The underlying table may have 100+ columns including sensitive data like comments, work_notes, sensitive_*, correlation_id, discovery_credentials. The database view exposes only selected safe columns like sys_id, name, sys_class_name, asset_tag. Hidden columns in the table are completely inaccessible through Squid because they are not in the view. JOINED TABLES: Views can join related tables like core_company (for manufacturer lookup) and cmn_location (for location data). These joins are defined in the view, not by API callers. SQUID CONFIGURATION: Each Squid configuration references a specific database view. The configuration inherits the view's column restrictions. Additional filtering can be applied through view fields (to further restrict columns) and view filters (to restrict rows).ServiceNow Tablescmdb_ci(100+ columns)Hidden columns:• comments• work_notes• sensitive_*EXPOSEDVIA VIEWDatabase ViewSelected Columns Only• sys_id• name• sys_class_name• asset_tagJoined Tables• core_company• cmn_locationSquid Configuration(references this view)Security ControlsColumn filteringExposed dataHidden / protected

Why Views Provide Security

  1. Explicit Column Selection - Only columns defined in the view are accessible
  2. No Accidental Exposure - New table columns don't automatically appear
  3. Join Control - You decide which related data to include
  4. Single Point of Control - Change the view, change all dependent configurations

View-Based Column Security

Consider a cmdb_ci_server table with 100+ columns. Your view might only expose:

Exposed in ViewHidden (Not in View)
sys_idu_internal_cost
namecomments
asset_tagwork_notes
sys_class_nameu_sensitive_data
manufacturercorrelation_id
locationdiscovery_credentials

Columns not in the view simply don't exist from Squid's perspective.

View Fields: Additional Column Filtering

Beyond the view definition, each table in a view can have View Fields defined:

  • If View Fields are defined: Only those fields are returned
  • If View Fields are empty: All columns from that table in the view are returned

This provides an additional layer of column-level control without modifying the view itself.

View Filters: Row-Level Security

While views control which columns are accessible, view filters control which rows are returned.

What is a View Filter?

A view filter is an encoded query that Squid applies to every request using that configuration. It cannot be overridden or bypassed by the caller.

Configuration: cmdb_ci_server_production

View Filter: base_install_status=1^base_operational_status=1
(only production, operational servers)

View Filter vs User-Provided encodedQuery

AspectView FilterUser encodedQuery
Defined BySquid AdministratorAPI Caller
Can Be BypassedNoN/A (it's caller input)
Operator RestrictionsNoneYes (restricted operators blocked)
PurposeSecurity restrictionQuery flexibility

How Filters Combine

When a configuration has a view filter and the caller provides an encodedQuery:

Final Query = View Filter AND User encodedQuery

Example:
View Filter: base_install_status=1
User Query: base_name=webserver01
Combined: base_install_status=1^base_name=webserver01

The view filter is always applied, ensuring security restrictions cannot be bypassed.

Creating Effective View Filters

Good view filters for security:

# Restrict to active/operational items only
base_install_status=1^base_operational_status!=6

# Restrict to specific company
base_company=e7c1f3d53790200044e0bfc8bcbe5deb

# Restrict to non-confidential classifications
base_u_confidentialityNOT INtop_secret,confidential

# Time-based restriction (only items updated in last year)
base_sys_updated_on>=javascript:gs.daysAgo(365)
warning

View filters can use restricted operators (like javascript:) because they are administrator-defined, not user input. Use this power responsibly.

Configuration-Level Data Controls

Each Squid configuration provides several data access controls:

Control: Database View

Defines which view (and thus which columns) are available.

Database View: u_cmdb_ci_server_squid
Primary Database View Prefix: base

Control: Excluded Database View Prefixes

Sometimes views include tables for joining or filtering purposes, but you don't want those columns in the output.

# View includes cmdb_rel_team for filtering, but exclude from output
Excluded Database View Prefixes: rel

Control: Is Root

Controls whether a configuration can be directly requested or only accessed via references.

Is RootDirect API CallVia Reference
true✅ Allowed✅ Allowed
false❌ Blocked✅ Allowed

Use case: Allow sys_user_group data when referenced by a CI, but prevent direct export of all user groups.

Control: Allow Inline Relations

Inline relations can cause extreme database load (potentially millions of queries). This setting controls whether inline rendering is permitted.

Allow Inline Relations: false  # Protect against performance attacks

Control: Limit

Maximum entities returned per request. Essential when inline relations are enabled.

Limit: 1000  # Prevent runaway queries

Data Flow Through Security Layers

┌─────────────────────────────────────────────────────────────────┐
│ Requested: cmdb_ci_server │
│ Query: ?encodedQuery=base_name=web* │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Step 1: Load Configuration │
│ • Database View: u_cmdb_ci_server_squid │
│ • View Filter: base_install_status=1 │
│ • Primary Prefix: base │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Step 2: Validate User Query │
│ • Check for forbidden operators (^NQ) → Block if found │
│ • Check for restricted operators → Block if restricted │
│ • Validate sys_id format if provided │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Step 3: Build Final Query │
│ • Start with View Filter: base_install_status=1 │
│ • Append user query: ^base_name=web* │
│ • Final: base_install_status=1^base_name=web* │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Step 4: Execute Query Against View │
│ • Query: u_cmdb_ci_server_squid │
│ • Only columns in view are accessible │
│ • Only rows matching combined filter returned │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Step 5: Process Results │
│ • Apply View Fields filtering (if defined) │
│ • Exclude specified prefixes from output │
│ • Resolve references using reference configurations │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Return JSON Response │
│ (only permitted data) │
└─────────────────────────────────────────────────────────────────┘

Practical Examples

Example 1: Restricting by Classification

Requirement: Only export non-confidential servers

Configuration: cmdb_ci_server_public

Database View: u_cmdb_ci_server_squid
View Filter: base_u_classification!=confidential^base_u_classification!=restricted

Example 2: Department-Specific Configuration

Requirement: HR department should only see HR-managed assets

Configuration: cmdb_ci_hr_assets

Database View: u_cmdb_ci_computer_squid
View Filter: base_managed_by_group=hr_asset_management_sys_id
Roles: hr_data_access

Example 3: Time-Bound Data Access

Requirement: Only export recently updated items (data freshness)

Configuration: cmdb_ci_server_recent

Database View: u_cmdb_ci_server_squid
View Filter: base_sys_updated_on>=javascript:gs.daysAgo(90)

Example 4: Multi-Tenant Isolation

Requirement: Different customers see only their data

Configuration: cmdb_ci_server_customer_a
View Filter: base_company=customer_a_sys_id
Roles: customer_a_access

Configuration: cmdb_ci_server_customer_b
View Filter: base_company=customer_b_sys_id
Roles: customer_b_access
We track. Ok?