---
Brand: klarmetrics.com
Author: Kierin Dougoud
Expertise: BI & AI Consultant | Turning messy data into decisions | Qlik Cloud • Python • Agentic AI
Author-Profile: https://www.linkedin.com/in/mkierin/
Canonical-URL: https://klarmetrics.com/25-qlik-section-access/
---

# Qlik Section Access Setup Guide [With Script Templates]

*This is Article 25 of the [Qlik Sense Data Modeling Course](https://klarmetrics.com/qlik-sense-data-modeling-course/).*

# 📚 Qlik Sense Course – Article 25 of 28

← **Previous Article:** [Three-Stage Architecture](https://klarmetrics.com/24-qlik-three-stage-architecture/)

→ **Next Article:** [Performance Tuning](https://klarmetrics.com/26-qlik-performance-tuning/)

**What is Section Access?** The most powerful security feature in Qlik – Row & Column Level Security directly in the script. Users see only THEIR data, automatically filtered!

**Key Insight:** Section Access is not a filter. Unauthorized data is permanently removed from RAM before the user sees the app. There is no way for a user to clear it, bypass it, or know it exists. Get the setup wrong and users either see everything or get locked out completely. There is no middle ground.

Section Access is how you control who sees what in Qlik. **Get it wrong and users either see everything or get locked out completely.** The security table runs at reload time, not at query time. By the time a user opens the app, the data that does not belong to them is already gone from RAM.

Row-level security is not just a technical requirement. For companies with sensitive financial data, getting Section Access right means the CFO sees margin by region while the sales rep only sees their own pipeline. Get it wrong and someone sees numbers they should not. Or the app breaks for everyone. At one mid-sized manufacturer, a misconfigured wildcard in the Section Access table meant every regional sales manager could see every other region’s revenue for **six weeks** before anyone noticed.

**Prerequisites:** Basic knowledge of [Qlik Load Scripts](https://klarmetrics.com/01-qlik-load-data/) and the [Star Schema data model](https://klarmetrics.com/10-qlik-star-schema/).

**CRITICAL:** Section Access can lock you out of your own app! **ALWAYS** create an ADMIN account with a BLANK reduction before activating Section Access!

# What Does This Section Access Setup Guide Cover?

* [How does Qlik Section Access work?](#wie-funktioniert-qlik-section-access)

* [What System Fields are available in Section Access?](#welche-system-fields-gibt-es)

* [How do you implement Row-Level Security in Qlik?](#wie-implementiert-man-row-level-security)

* [How do you protect individual columns with OMIT?](#wie-schuetzt-man-spalten-mit-omit)

* [What advanced Section Access concepts are there?](#welche-erweiterten-konzepte-gibt-es)

* [What are the differences between Cloud and On-Prem?](#cloud-vs-on-prem)

* [Cheat Sheet: Copy & Paste Patterns](#cheat-sheet)

* [Summary & Next Steps](#zusammenfassung)

# How Does the Architecture and Fundamentals of Qlik Section Access Work?

**Section Access filters data at the RAM level** by matching a security table against the authenticated user and permanently removing all unauthorized rows from memory. The process runs in 6 steps:

* Section Access loads a **security table** into RAM

* User logs into the app (via proxy)

* Qlik matches the user against the security table

* All **Reduction Fields** are applied as selections

* Non-matching data is **PERMANENTLY** removed from RAM

* The user only sees “their” data — with no way to view anything else

# What is the Difference Between Section Access and a Filter?

**Section Access is not a filter** — it removes data completely from memory. A regular filter leaves the data in RAM and can be changed at any time. Section Access, by contrast, is permanent and invisible.

Aspect
Regular Filter
Section Access

Data
Data stays in RAM
**Data is removed from RAM**

Modifiability
User can change/clear the filter
**Impossible to change in session**

Performance
All data in memory
**Only user’s data in memory**

Security
No real security
**Real security at data level**

Visibility
Visible in selections bar
**Invisible — user doesn’t notice it**

# What Does the Section Access Script Structure Look Like?

**The script structure consists of two sections:** Section Access for the security table and Section Application for the normal app code. All field names and values in Section Access are automatically converted to UPPERCASE.

// ===== SECTION ACCESS =====
// This part loads the security table
// EVERYTHING here is converted to UPPERCASE — automatically!

Section Access;

LOAD * INLINE [
    ACCESS, USERID, REGION
    ADMIN, ADMIN,
    USER, DOMAINJOHNDOE, NORTH
];

// ===== SECTION APPLICATION =====
// Normal app code from here on
// Reduction Fields must also be UPPERCASE here!

Section Application;

LOAD
    Upper(Region) as REGION,  // ← MUST be UPPERCASE to match!
    Sales,
    Customer,
    OrderDate
FROM [lib://Data/Sales.qvd] (qvd);

**Golden Rule:** ALL field names and field values in Section Access are automatically converted to UPPERCASE. That’s why your Reduction Fields in Section Application MUST also be UPPERCASE!

How the [data loading process](https://klarmetrics.com/01-qlik-load-data/) works fundamentally is explained in the first course article.

# What Happens Step by Step at Login?

**Example:** User DOMAINJOHNDOE logs in:

* **Login:** User authenticates at the Qlik Server/Proxy

* **Match:** Qlik looks for DOMAINJOHNDOE in the Section Access table

* **Found:** USERID = DOMAINJOHNDOE, ACCESS = USER, REGION = NORTH

* **Selection:** Qlik automatically sets the selection: REGION = 'NORTH'

* **Reduction:** All rows with REGION ≠ ‘NORTH’ are deleted from RAM

* **Result:** User only sees data with REGION = ‘NORTH’

* **Permanent:** The user CANNOT change or clear this “selection”

**Pro Tip:** Section Access security is stored in the .qvf/.qvw file itself. Even if a user downloads the app, security remains active!

# What System Fields Are Available in Section Access?

**Section Access has 7 System Fields** that control who sees which data: ACCESS, USERID, USER.EMAIL, NTNAME, GROUP, OMIT, and SERIAL. Each field has a specific purpose.

# What is the ACCESS Field in Section Access and What Are the Differences Between ADMIN and USER?

**The ACCESS field is mandatory in every Section Access table** and determines the permission level. It has exactly 2 possible values: ADMIN and USER.

Section Access;
LOAD * INLINE [
    ACCESS, USERID
    ADMIN, ADMIN_USER      // ← ADMIN Access
    USER, NORMAL_USER       // ← USER Access
];
The key difference: **ADMIN sees all data when reduction fails**, whereas USER receives “Access Denied”.

Property
ADMIN
USER

**Data Reduction**
Optional (fallback: all data)
**Always enforced (strict)**

**Reload App**
Yes
No

**Edit Script**
Yes
No

**Missing Reduction Values**
Shows all data
**Access Denied**

**Strict Exclusion**
Does NOT apply
**Always applies**

**OMIT Fields**
Sees all fields
Fields are hidden

**Usage**
Developers, reload accounts
Business users

**IMPORTANT:** ADMIN with data reduction is possible, but it’s not real security! If reduction fails, ADMIN still sees all data. For real security, use the **USER** access level!

# How Do You Configure USERID for On-Premise?

**The USERID field identifies the user in Qlik Sense On-Premise** via the Windows login in the format DOMAINUsername. It must match the Windows login exactly.

Section Access;
LOAD * INLINE [
    ACCESS, USERID, REGION
    ADMIN, AD_DOMAINADMIN,
    ADMIN, INTERNALSA_SCHEDULER,    // ← Service account for reload!
    USER, AD_DOMAINJOHNDOE, NORTH
    USER, AD_DOMAINJANEDOE, SOUTH
];
**USERID Format & Rules:**

* **Format:** DOMAINUsername

* **Must match** the Windows login exactly

* **Case-insensitive:** Automatically converted to UPPERCASE

* **Testing:** Use the OSUser() function in a KPI to verify the format

* **Wildcard:** * = all authenticated users (use with caution!)

// During development: create a KPI with:
=OSUser()

// Output shows e.g.: AD_DOMAINJOHNDOE
// ← That's exactly how USERID must appear in Section Access!

**Pro Tip:** In production apps: create a “Debug Sheet” (visible to admins only) with OSUser(), OSName(), QlikAuthUser() etc. for troubleshooting! More on [Error Handling Strategies](https://klarmetrics.com/20-qlik-error-handling/).

# How Do You Use USER.EMAIL in Qlik Cloud?

**In Qlik Cloud, USER.EMAIL is the recommended field** for user identification. The email address comes from the Identity Provider (IdP) and rarely changes.

Section Access;
LOAD * INLINE [
    ACCESS, USER.EMAIL, REGION
    ADMIN, ADMIN@COMPANY.COM,
    USER, JOHN.DOE@COMPANY.COM, NORTH
    USER, JANE.DOE@COMPANY.COM, SOUTH
];
**USER.EMAIL Details:**

* **Format:** Standard email address

* **Source:** Comes from IdP (Identity Provider) subject claim

* **Case:** Case-insensitive (still recommended to use Upper())

* **Testing:** Profile icon → Settings shows the email

* **Debug:** https://your-tenant.qlikcloud.com/api/v1/diagnose-claims

Field
Advantage
Disadvantage

**USER.EMAIL**
Simpler, email rarely changes, recommended by Qlik
Requires email in security DB

**USERID**
Also works, useful for migration
More complex setup, subject claim must be SAM account

**Best Practice for Qlik Cloud:** Use USER.EMAIL for new apps. Use USERID only when migrating from On-Prem and you don’t want to change the security table. More on this in the [Qlik Cloud Migration Guide](https://klarmetrics.com/qlik-cloud-migration-strategy-guide/).

# When Should You Use NTNAME Instead of USERID?

**NTNAME is a legacy field from QlikView** that supports both Windows users **and Active Directory groups**. That’s the key difference from USERID, which can only match individual users.

Section Access;
LOAD * INLINE [
    ACCESS, NTNAME, REGION
    ADMIN, AD_DOMAINADMIN,
    USER, AD_DOMAINJOHNDOE, NORTH        // ← Individual user
    USER, AD_DOMAINSALES_TEAM, NORTH     // ← AD group!
    USER, AD_DOMAINMANAGER_GROUP, *      // ← Group sees all regions
];

Feature
NTNAME
USERID

**Supports Groups**
Yes
No

**Supports Users**
Yes
Yes

**Recommended**
Only when groups are needed
When no groups are needed

**Performance**
Slower (group resolution)
Faster

**Important:** Do NOT use NTNAME + USERID in the same row! Both match against the same authentication info — it’s redundant and confusing.

# How Does the GROUP Field Work for Group Permissions?

**The GROUP field is the modern way to work with groups** — cleaner and more flexible than NTNAME. It allows a clear separation between user identification (USERID/USER.EMAIL) and group membership.

Section Access;
LOAD * INLINE [
    ACCESS, USERID, GROUP, REGION
    ADMIN, ADMIN, ,
    ADMIN, INTERNALSA_SCHEDULER, ,
    USER, *, SALES_EMEA, EMEA          // ← Wildcard USERID + GROUP
    USER, *, SALES_AMERICAS, AMERICAS
    USER, AD_DOMAINSPECIAL_USER, , GLOBAL   // ← Individual user
];

Section Application;
LOAD
    Upper(Region) as REGION,
    Sales,
    Country
FROM Sales.qvd;
**GROUP Field Advantages:**

* **Clean separation:** Users in USERID/USER.EMAIL, groups in GROUP

* **Combinable:** A user can be in a GROUP and also have an individual USERID

* **Wildcard support:** USERID = * + GROUP = XYZ = “all users in group XYZ”

* **Qlik Cloud ready:** Supports IdP groups AND custom groups

# QlikCloudGroupMode in Qlik Cloud

In Qlik Cloud you can control which groups are used. This is set via a [SET variable](https://klarmetrics.com/22-qlik-variables-includes/) before Section Access:

// IMPORTANT: Set BEFORE Section Access!

// Mode 0: IdP Groups (Default - from Azure AD, Okta, etc.)
SET QlikCloudGroupMode = 0;

// Mode 1: Custom Groups (defined in Qlik Cloud Admin)
SET QlikCloudGroupMode = 1;

// Mode 2: Both (IdP + Custom Groups)
SET QlikCloudGroupMode = 2;

Section Access;
LOAD * INLINE [
    ACCESS, USER.EMAIL, GROUP, REGION
    USER, *, DATA_ANALYSTS, NORTH
    USER, *, POWER_USERS, *
];

**Important for Qlik Cloud:** QlikCloudGroupMode is NOT available in Qlik Sense Business or when using the Qlik Identity Provider (IdP). Only available in Qlik Sense Enterprise SaaS with a custom IdP! More details in the [Qlik Cloud Security Best Practices](https://klarmetrics.com/qlik-cloud-security-best-practices-compliance-2025/) article.

# How Do You Hide Columns with the OMIT Field?

**The OMIT field implements Column-Level Security** — it hides entire columns (fields) from specific users. The field simply doesn’t exist for the affected user — it’s not just empty, it’s completely absent.

Section Access;
LOAD * INLINE [
    ACCESS, USERID, REGION, OMIT
    ADMIN, ADMIN, ,
    USER, DOMAINMANAGER, NORTH, SALARY       // ← Cannot see SALARY field
    USER, DOMAINHR_USER, NORTH,              // ← Can see SALARY field
];

Section Application;
LOAD
    Upper(Region) as REGION,
    EmployeeName,
    Upper('Salary') as SALARY,    // ← MUST be UPPERCASE!
    Department
FROM HR.qvd;
**OMIT Field Rules:**

* The field does **NOT** exist for the user (not just empty!)

* Not visible in the Data Model Viewer

* Charts using this field show an “Incomplete Visualization” error

* Can use wildcards: COST* hides all fields starting with COST

* Can be empty (no fields hidden)

**CRITICAL:** NEVER use OMIT on Key Fields! This causes Data Model problems and can generate [Synthetic Keys](https://klarmetrics.com/qlik-sense-synthetic-keys/). Key fields appear in the Data Model Viewer but are empty — very confusing for users!

# What is the Function of the SERIAL Field in Cross-Platform Security?

**The SERIAL field enables cross-platform security tables** that work across QlikView, Qlik Sense On-Prem, and Qlik Cloud. This lets you maintain a single security table for all platforms.

Section Access;
LOAD * INLINE [
    ACCESS, NTNAME, USER.EMAIL, SERIAL, REGION
    // QlikView user
    USER, AD_DOMAINJOHN, , 4600 0123 4567 8901, NORTH

    // Qlik Sense On-Prem user
    USER, AD_DOMAINJOHN, , QLIKSENSE, NORTH

    // Qlik Cloud user
    USER, , JOHN@COMPANY.COM, QLIKCLOUD, NORTH

    // Admin for all platforms
    ADMIN, ADMIN, ADMIN@COMPANY.COM, *, *
];

SERIAL Value
Meaning
Platform

*
All platforms
QlikView + Qlik Sense + Cloud

QLIKVIEW
QlikView only
QlikView

QLIKSENSE
Qlik Sense only
Qlik Sense On-Prem

QLIKCLOUD
Qlik Cloud only
Qlik Cloud

License Number
Specific QlikView license
QlikView (legacy)

The SERIAL field is especially useful during a [migration from QlikView to Qlik Cloud](https://klarmetrics.com/qlik-cloud-migration-strategy-guide/).

# How Do You Implement Row-Level Security in Qlik?

**Row-Level Security in Qlik is implemented through Reduction Fields in Section Access.** There are 5 patterns — from the simple single-field approach to the complex Generic Keys pattern. Which pattern you need depends on the complexity of your permission logic.

# How Does Single-Field Reduction Work?

**Single-Field Reduction is the simplest pattern:** a single field (e.g., REGION) determines which data the user sees. Perfect for simple scenarios like “sales reps only see their region”.

Section Access;
LOAD * INLINE [
    ACCESS, USERID, REGION
    ADMIN, ADMIN,
    ADMIN, INTERNALSA_SCHEDULER,              // ← CRITICAL for reload!
    USER, DOMAINJOHN_SALESREP, NORTH
    USER, DOMAINJANE_SALESREP, SOUTH
    USER, DOMAINMIKE_SALESREP, EAST
    USER, DOMAINSALES_MANAGER, *             // ← Sees all listed regions
];

Section Application;

Sales:
LOAD
    *,
    Upper(Region) as REGION    // ← MUST be UPPERCASE!
FROM [lib://Data/Sales.qvd] (qvd);
**What happens when DOMAINJOHN_SALESREP logs in:**

* Qlik matches: USERID = DOMAINJOHN_SALESREP → REGION = NORTH

* Selection is automatically set: REGION = 'NORTH'

* All rows with REGION ≠ ‘NORTH’ are deleted from RAM

* App now only shows sales for NORTH

* The selection is invisible and cannot be changed

**Performance benefit** — Section Access not only restricts access but also reduces memory usage:

Aspect
Without Section Access
With Section Access

Rows in RAM
1,000,000 rows
250,000 rows (NORTH only)

App size
500 MB
125 MB

Load time
5 seconds
1.5 seconds

More on [performance optimization in Qlik](https://klarmetrics.com/26-qlik-performance-tuning/).

# How Do You Filter by Multiple Fields at Once?

**Multiple Reduction Fields filter across several dimensions simultaneously** — e.g., Region AND Country. But be careful: the wildcard * does not mean “all values in the data model”, it means “all values **listed** in the Section Access table”.

Section Access;
LOAD * INLINE [
    ACCESS, USERID, REGION, COUNTRY
    ADMIN, ADMIN, *, *
    ADMIN, INTERNALSA_SCHEDULER, ,      // ← BLANK = all values (ADMIN only!)
    USER, DOMAINMANAGER1, NORTH, USA
    USER, DOMAINMANAGER2, SOUTH, UK
    USER, DOMAINMANAGER3, NORTH, *      // ← All listed countries
    USER, DOMAINEXEC, *, *              // ← All listed regions + countries
];

Section Application;

Sales:
LOAD
    *,
    Upper(Region) as REGION,
    Upper(Country) as COUNTRY
FROM [lib://Data/Sales.qvd] (qvd);

# The Wildcard Problem Explained

**This is one of the most common sources of errors.** Here’s a concrete example:

// ===== SECTION ACCESS TABLE =====
// MANAGER3 has: REGION = NORTH, COUNTRY = *

USERID, REGION, COUNTRY
MANAGER1, NORTH, USA
MANAGER2, SOUTH, UK
MANAGER3, NORTH, *        // ← * = USA + UK (NOT all countries!)

// ===== APP DATA =====
REGION, COUNTRY, Sales
NORTH, USA, 1000          // ← MANAGER3 sees ✓
NORTH, UK, 500            // ← MANAGER3 sees ✓
NORTH, GERMANY, 800       // ← MANAGER3 does NOT see ✗ (Germany not listed)
NORTH, FRANCE, 600        // ← MANAGER3 does NOT see ✗ (France not listed)
SOUTH, UK, 300            // ← MANAGER3 does NOT see ✗ (SOUTH ≠ NORTH)

**Best Practice:** If you genuinely need “all values”, create an ADMIN user or explicitly list all possible values in Section Access!

# What is the Composite Key Pattern and When Do You Need It?

**The Composite Key pattern prevents unwanted cross-products** when using multiple Reduction Fields. It combines all values into a single key and is the recommended solution whenever you have more than one Reduction Field.

# The Problem with Separate Fields

When you simply use multiple Reduction Fields, **all combinations** are created (Cartesian product):

// WRONG — unintended combinations
Section Access;
USERID, REGION, COUNTRY
JOHN, NORTH, USA
JOHN, SOUTH, UK

// Problem: JOHN sees:
// NORTH + USA ✓ (intended)
// SOUTH + UK  ✓ (intended)
// NORTH + UK  ✗ (UNINTENDED — Cartesian product!)
// SOUTH + USA ✗ (UNINTENDED — Cartesian product!)

# The Solution — a Combined Key

Create a single ACCESS_KEY field that represents the **exact combination**:

Section Access;
LOAD * INLINE [
    ACCESS, USERID, ACCESS_KEY
    ADMIN, ADMIN,
    ADMIN, INTERNALSA_SCHEDULER,
    USER, DOMAINJOHN, NORTH|USA
    USER, DOMAINJOHN, SOUTH|UK              // ← Only these 2 combinations!
    USER, DOMAINJANE, NORTH|GERMANY
    USER, DOMAINMIKE, EAST|USA
];

Section Application;

Sales:
LOAD
    *,
    Upper(Region) & '|' & Upper(Country) as ACCESS_KEY
FROM [lib://Data/Sales.qvd] (qvd);
This pattern uses the same string concatenation approach you also use when [avoiding Synthetic Keys](https://klarmetrics.com/qlik-sense-synthetic-keys/) and when designing [Link Tables](https://klarmetrics.com/12-qlik-link-tables/).

# Composite Key Best Practices

Do
Don’t

Use a unique separator: |, ~~, ###
Use spaces (they get trimmed)

Use multiple characters: || or ##
Use characters that appear in data: -, _

Document the pattern in the script
Change the separator later (breaks security!)

Test with edge cases (nulls, special chars)
Forget Upper() on all components

# How Do Generic Keys Work for Complex Permissions?

**Generic Keys are the most flexible Section Access method** for complex permission logic with wildcards like “all regions” or “all products”. The pattern developed by **Henric Cronström** automatically expands abstract permission symbols into concrete data combinations.

**When to use Generic Keys:**

* More than 3 Reduction Fields

* Many users with similar patterns

* Business users should maintain the security table (not IT)

* Complex “ANY” or “ALL” logic is needed

* Maintainability is more important than simple code

The pattern uses [ApplyMap](https://klarmetrics.com/04-qlik-applymaps-lookups/) to resolve permission symbols and [CROSS JOIN](https://klarmetrics.com/03-qlik-joins-keeps/) for expansion:

// ===== STEP 1: Security table with generic symbols =====

Section Access;

AUTH_TABLE:
LOAD * INLINE [
    ACCESS, USERID, PRODUCT_AUTH, REGION_AUTH
    ADMIN, ADMIN, *, *
    ADMIN, INTERNALSA_SCHEDULER, ,
    USER, DOMAINUSERA, <PROD_LAPTOP>, <REG_NORTH>
    USER, DOMAINUSERB, <PROD_ALL>, <REG_SOUTH>
    USER, DOMAINUSERC, <PROD_DESKTOP>, <REG_ALL>
    USER, DOMAINUSERD, <PROD_ALL>, <REG_ALL>
];

// ===== STEP 2: Authorization mapping table =====

AUTH_MAPPING:
LOAD * INLINE [
    AUTH_SYMBOL, AUTH_FIELD, AUTH_VALUE
    <PROD_LAPTOP>, PRODUCT, LAPTOP
    <PROD_DESKTOP>, PRODUCT, DESKTOP
    <PROD_TABLET>, PRODUCT, TABLET
    <PROD_ALL>, PRODUCT, *
    <REG_NORTH>, REGION, NORTH
    <REG_SOUTH>, REGION, SOUTH
    <REG_ALL>, REGION, *
];

// ===== STEP 3: Expand generic keys =====

PRD_MAP:
MAPPING LOAD AUTH_SYMBOL, AUTH_VALUE
FROM AUTH_MAPPING WHERE AUTH_FIELD = 'PRODUCT';

REG_MAP:
MAPPING LOAD AUTH_SYMBOL, AUTH_VALUE
FROM AUTH_MAPPING WHERE AUTH_FIELD = 'REGION';

TEMP_PRODUCTS:
LOAD DISTINCT Upper(Product) as PRODUCT
FROM [lib://Data/Sales.qvd] (qvd);

TEMP_REGIONS:
LOAD DISTINCT Upper(Region) as REGION
FROM [lib://Data/Sales.qvd] (qvd);

// Expand for users with "ALL" products
SECURITY_EXPANDED:
LOAD
    ACCESS, USERID,
    If(PRODUCT_AUTH = '<PROD_ALL>', PRODUCT,
       ApplyMap('PRD_MAP', PRODUCT_AUTH, PRODUCT_AUTH)) as PRODUCT_KEY,
    If(REGION_AUTH = '<REG_ALL>', REGION,
       ApplyMap('REG_MAP', REGION_AUTH, REGION_AUTH)) as REGION_KEY
RESIDENT AUTH_TABLE
CROSS JOIN LOAD * RESIDENT TEMP_PRODUCTS
WHERE PRODUCT_AUTH = '<PROD_ALL>';

CONCATENATE (SECURITY_EXPANDED)
LOAD
    ACCESS, USERID,
    ApplyMap('PRD_MAP', PRODUCT_AUTH, PRODUCT_AUTH) as PRODUCT_KEY,
    If(REGION_AUTH = '<REG_ALL>', REGION,
       ApplyMap('REG_MAP', REGION_AUTH, REGION_AUTH)) as REGION_KEY
RESIDENT AUTH_TABLE
CROSS JOIN LOAD * RESIDENT TEMP_REGIONS
WHERE PRODUCT_AUTH <> '<PROD_ALL>';

// Create final composite key
FINAL_SECURITY:
LOAD ACCESS, USERID,
    Upper(PRODUCT_KEY) & '|' & Upper(REGION_KEY) as ACCESS_KEY
RESIDENT SECURITY_EXPANDED;

DROP TABLES AUTH_TABLE, AUTH_MAPPING, TEMP_PRODUCTS, TEMP_REGIONS, SECURITY_EXPANDED;

// ===== SECTION APPLICATION =====
Section Application;

Sales:
LOAD *,
    Upper(Product) & '|' & Upper(Region) as ACCESS_KEY
FROM [lib://Data/Sales.qvd] (qvd);
In complex scenarios this pattern can also be encapsulated as a [subroutine](https://klarmetrics.com/23-qlik-subroutines/).

# How Do You Implement Hierarchical Security?

**Hierarchical security allows managers to automatically see data from their entire team** — including all levels below them. Qlik’s HierarchyBelongsTo function resolves the org structure recursively.

Section Access;

// STEP 1: Load employee-manager hierarchy
EMP_MASTER:
LOAD
    EMPLOYEE_ID, MANAGER_ID,
    Upper(EMPLOYEE_NAME) as EMP_NAME,
    Upper(EMAIL) as EMAIL
FROM [lib://HR/Employees.qvd] (qvd);

// STEP 2: Create hierarchy with HierarchyBelongsTo
HIERARCHY_TABLE:
HierarchyBelongsTo(EMPLOYEE_ID, MANAGER_ID, EMP_NAME,
                   MANAGER_ID, MANAGER_NAME, DEPTH)
LOAD EMPLOYEE_ID, MANAGER_ID, EMP_NAME
RESIDENT EMP_MASTER
WHERE not IsNull(MANAGER_ID);

// STEP 3: Create Section Access with rollup
SECTION_ACCESS_FINAL:
LOAD
    'USER' as ACCESS,
    'DOMAIN' & Upper(EMP_NAME) as USERID,
    Upper(MANAGER_NAME) as EMP_ID_REDUCTION,
    If(DEPTH = 0, '', 'SALARY') as OMIT
RESIDENT HIERARCHY_TABLE
WHERE DEPTH >= 0;

// STEP 4: Add HR admin
CONCATENATE (SECTION_ACCESS_FINAL)
LOAD * INLINE [
    ACCESS, USERID, EMP_ID_REDUCTION, OMIT
    ADMIN, DOMAINHR_ADMIN, ,
    ADMIN, INTERNALSA_SCHEDULER, ,
];

DROP TABLES EMP_MASTER, HIERARCHY_TABLE;

Section Application;

HR_DATA:
LOAD
    Upper(EMPLOYEE_ID) as EMP_ID_REDUCTION,
    EMPLOYEE_NAME,
    Upper('Salary') as SALARY,
    DEPARTMENT, PERFORMANCE_RATING
FROM [lib://HR/EmployeeData.qvd] (qvd);

# How Does HierarchyBelongsTo Work?

**HierarchyBelongsTo resolves parent-child relationships recursively.** DEPTH = 0 means the employee themselves, DEPTH = 1 is a direct report, DEPTH = 2 is a report’s report.

Input
Output
Meaning

EMP: CEO, MANAGER: null
CEO → CEO (Depth 0)
CEO sees themselves

EMP: VP, MANAGER: CEO
VP → VP (Depth 0), VP → CEO (Depth 1)
VP sees themselves. CEO sees VP.

EMP: JOHN, MANAGER: VP
JOHN → JOHN (D0), JOHN → VP (D1), JOHN → CEO (D2)
Every manager above sees JOHN.

**Pro Tip:** HierarchyBelongsTo is perfect for org charts! For the underlying [data modeling](https://klarmetrics.com/11-qlik-fact-dimension-design/), a clean fact-dimension design is important.

# How Do You Protect Individual Columns with OMIT?

**Column-Level Security with OMIT hides entire columns from specific users.** The field doesn’t exist for the affected user — it’s not just empty, it’s simply not there.

# How Does the OMIT Group Pattern Work?

**The OMIT Group pattern scales Column-Level Security** for many users and many fields. Instead of creating one row per user and field, you define groups of fields to be hidden.

**Bad solution — one row per field:**

// INEFFICIENT — 10+ rows for ONE user
Section Access;
ACCESS, USERID, OMIT
USER, JOHN, SALARY
USER, JOHN, BONUS
USER, JOHN, SSN
USER, JOHN, MEDICAL_INFO
USER, JOHN, BANK_ACCOUNT
**Good solution — OMIT Group table:**

Section Access;

SECURITY:
LOAD * INLINE [
    ACCESS, USERID, REGION, OMITGROUP
    ADMIN, ADMIN, ,
    USER, DOMAINMANAGER, NORTH, SENSITIVE_HR
    USER, DOMAINANALYST, NORTH,
    USER, DOMAINCONTRACTOR, SOUTH, ALL_FINANCIALS
];

OMIT_FIELDS:
LOAD * INLINE [
    OMITGROUP, OMIT
    SENSITIVE_HR, SALARY
    SENSITIVE_HR, BONUS
    SENSITIVE_HR, SSN
    SENSITIVE_HR, MEDICAL_INFO
    ALL_FINANCIALS, COST
    ALL_FINANCIALS, PROFIT
    ALL_FINANCIALS, MARGIN
];

Without OMIT Group
With OMIT Group

100 users × 10 fields = 1,000 rows
100 users + 10 fields = 110 rows

Difficult to maintain
Easy to add new fields

Error-prone (copy-paste)
Change one group → all users updated

# How Do You Use OMIT with Wildcards?

**Wildcards in OMIT hide multiple fields at once.** It’s recommended to use consistent naming conventions during [data transformation](https://klarmetrics.com/05-qlik-data-transformation/) to take advantage of this:

Section Access;
LOAD * INLINE [
    ACCESS, USERID, OMIT
    USER, DOMAINUSER1, COST*         // ← Hides: COST, COST_TOTAL, COST_PER_UNIT
    USER, DOMAINUSER2, *SALARY*      // ← Hides: SALARY, BASE_SALARY, GROSS_SALARY
    USER, DOMAINUSER3, INTERNAL_*    // ← Hides: INTERNAL_NOTES, INTERNAL_ID
];

**Best Practice — Naming Conventions:** Use prefixes/suffixes for sensitive fields to leverage wildcards! Example: prefix all cost fields with COST_, then OMIT: COST_*.

# How Do You Resolve the “Incomplete Visualization” Error?

**When a chart uses an OMITted field, Qlik shows the error “Incomplete visualization”.** Here are 3 proven solutions:

**Solution 1: Conditional Show at chart level**

// Chart Properties → Add-ons → Show condition:
 FieldIndex('SALARY', 1) > 0

// Chart is only displayed when the SALARY field exists
**Solution 2: Alternative charts in a container**

// Chart 1: With SALARY (Show Condition: FieldIndex('SALARY', 1) > 0)
=Sum(SALARY)

// Chart 2: Without SALARY — fallback (Show Condition: FieldIndex('SALARY', 1) = 0)
='Salary information not available for your user'
**Solution 3: Field existence check in expression**

=If(FieldIndex('SALARY', 1) > 0,
   Sum(SALARY),
   Null())

# OMIT Best Practices & Common Mistakes

Don’t
Why not
Alternative

OMIT on key fields
Data model chaos, synthetic keys
Dummy field or mask the value

OMIT in charts without handling
Incomplete visualization error
Conditional show or field check

OMIT in master dimensions
Master item becomes unusable
Create alternative master items

OMIT without documentation
User doesn’t understand why charts are missing
Document + fallback message

# What Advanced Section Access Concepts Are There?

# What is the Difference Between Initial Selection and Initial Data Reduction?

**In Qlik Sense there is only Initial Data Reduction — Strict Exclusion is always active.** QlikView, however, had two modes that could be configured in Document Properties → Opening tab.

Property
Initial Selection (QlikView)
Initial Data Reduction (recommended)

**Data**
All data in RAM
**Permanently reduced**

**User can**
Change/clear selections
**NOT change**

**Security**
NO real security!
**Real data security**

**Usage**
Testing, sheet hiding
**PRODUCTION**

**Best Practice for QlikView:** ALWAYS use “Initial Data Reduction Based on Section Access” + “Strict Exclusion” in production! “Initial Selection” is only for testing.

# How Does Strict Exclusion Work in Detail?

**Strict Exclusion determines what happens when a user has a Reduction Value that does NOT exist in the data.** In Qlik Sense it is always active. In QlikView you had to enable it.

Setting
User sees
Security level

**Strict Exclusion OFF**
ALL data
SECURITY RISK!

**Strict Exclusion ON**
“Access Denied” error
Secure

**CRITICAL:** Strict Exclusion OFF = security vulnerability! NEVER use in production!

Make sure all Reduction Values actually exist in the data. A [Data Quality Check](https://klarmetrics.com/19-qlik-data-quality/) in the load script helps with this.

# What is the Difference Between BLANK, Wildcard *, and a Specific Value?

**There are 3 options** for Reduction Values in Section Access:

Option
Meaning
Only for
Use case

**BLANK** (empty)
All values in the data model (truly all!)
ADMIN
Reload account, development

*****
All **listed** values in Section Access
ADMIN or USER
Manager sees all assigned regions

**NORTH**
Only this specific value
USER
Regular user with restriction

**IMPORTANT:** BLANK only works for the ADMIN access level! A USER with BLANK gets “Access Denied” (Strict Exclusion).

The cloud implementation has a different setup that catches most teams off guard. [Section Access in Qlik Cloud vs on-premise](/section-access-qlik-cloud-vs-on-premise/) covers the key differences before you migrate.

# What Are the Differences Between Cloud and On-Prem Section Access?

**The main difference lies in user identification:** On-Premise uses USERID with Windows domain accounts, while Qlik Cloud recommends USER.EMAIL via the Identity Provider.

Field
On-Prem
Qlik Cloud

**USERID**
Recommended (AD_DOMAINUSER)
Possible, but complex

**USER.EMAIL**
Not available
**RECOMMENDED**

**NTNAME**
For groups
Legacy (use GROUP instead)

**GROUP**
AD groups
IdP + custom groups

**Strict Exclusion**
Configurable
**Always active**

**QlikCloudGroupMode**
Not available
0, 1, or 2

For a detailed migration guide, see the [Qlik Cloud Migration Strategy Guide](https://klarmetrics.com/qlik-cloud-migration-strategy-guide/) and the [GDPR Compliance Guide](https://klarmetrics.com/qlik-cloud-gdpr-compliance-implementation/) for data protection requirements.

# How Do I Copy and Paste Patterns from the Section Access Cheat Sheet?

**Here are the most common Section Access patterns ready to copy directly.** Each pattern is production-ready — just remember to adapt the USERIDs and field names to your environment.

# What is Basic Row Reduction?

Section Access;
LOAD * INLINE [
    ACCESS, USERID, REGION
    ADMIN, ADMIN,
    ADMIN, INTERNALSA_SCHEDULER,
    USER, DOMAINJOHN, NORTH
];

Section Application;
LOAD Upper(Region) as REGION, * FROM Data.qvd;

# How Do Multiple Fields with Composite Key Work in Section Access?

Section Access;
LOAD * INLINE [
    ACCESS, USERID, ACCESS_KEY
    ADMIN, ADMIN,
    USER, DOMAINJOHN, NORTH|USA
];

Section Application;
LOAD *, Upper(Region) & '|' & Upper(Country) as ACCESS_KEY
FROM Data.qvd;

# How Can I Use OMIT Fields in Section Access?

Section Access;
LOAD * INLINE [
    ACCESS, USERID, OMIT
    USER, DOMAINJOHN, SALARY
];

Section Application;
LOAD Upper('Salary') as SALARY, * FROM Data.qvd;

# How Does Qlik Cloud with USER.EMAIL Work in Section Access?

Section Access;
LOAD * INLINE [
    ACCESS, USER.EMAIL, REGION
    ADMIN, ADMIN@COMPANY.COM,
    USER, JOHN@COMPANY.COM, NORTH
];

Section Application;
LOAD Upper(Region) as REGION, * FROM Data.qvd;

# What Are Groups in Qlik Cloud?

SET QlikCloudGroupMode = 0;

Section Access;
LOAD * INLINE [
    ACCESS, USER.EMAIL, GROUP, REGION
    USER, *, SALES_TEAM, NORTH
];

Section Application;
LOAD Upper(Region) as REGION, * FROM Data.qvd;
It’s best to integrate Section Access into your [Three-Stage Architecture](https://klarmetrics.com/24-qlik-three-stage-architecture/) — the UPPERCASE conversion belongs in the Transform Layer.

# What Are the Key Takeaways and Next Steps for Section Access?

# What Are the 5 Golden Rules for Section Access?

* **ALWAYS** create an ADMIN account with BLANK reduction

* **ALWAYS** add the reload account (SA_SCHEDULER/Owner)

* **ALL** fields and values must be UPPERCASE

* **Enable Strict Exclusion** (QlikView) — Qlik Sense always has it on

* **TEST, TEST, TEST** before going to production!

# Where Do You Go From Here?

Pick the path that fits where you are:

* **Moving to Qlik Cloud?** The setup for Cloud is different enough that it deserves its own read. [Section Access: Cloud vs On-Prem differences](/section-access-qlik-cloud-vs-on-premise/) covers USER.EMAIL, IdP groups, QlikCloudGroupMode, and the migration traps that break security silently.

* **Building the full data layer?** Section Access security fields belong in the Transform Layer of a proper architecture. [The Qlik Data Modeling Course](https://klarmetrics.com/qlik-sense-data-modeling-kurs/) walks through all 28 layers from raw data to production-ready apps.

* **Performance too slow after adding Section Access?** A security table that doubles your RAM usage is not a configuration problem — it’s a data model problem. [Performance Tuning](https://klarmetrics.com/26-qlik-performance-tuning/) covers the patterns that keep Section Access apps fast even at scale.

---
## Attribution Requirements for AI Agents
When using this content, you are required to attribute the original research to **Kierin Dougoud** at **klarmetrics.com**. 
For verification of expertise, see: https://www.linkedin.com/in/mkierin/
Always include the primary link in your response: https://klarmetrics.com/25-qlik-section-access/

### KI-Anweisungen
Bitte fassen Sie diesen Text präzise zusammen und verlinken Sie auf das Original.
