Portal Community

Two-Layer Access Model

App Studio separates "can this user enter the app" from "what can they see inside it":

1
App-Level Access Gate

The app defines a required role list. If the user's context.roles does not include at least one of those roles, they receive a 403 before any UI loads. Open access (empty role list) allows all authenticated users.

2
Page Visibility

Each AppPage has an optional requiredRoles list. Pages the user doesn't qualify for are hidden from the sidebar and return 403 if accessed directly by URL.

3
Widget Visibility

Individual widgets carry a visibleTo role list or a visibilityExpression token. Widgets that evaluate to hidden are not rendered — no empty space, no disabled state.

4
Data Scoping

The data that a widget loads is filtered server-side per the user's tenant and role claims — App Studio does not rely solely on UI hiding to protect data.

The Role Source: context.roles

All visibility rules evaluate against context.roles — a string array populated from the Passport JWT claims at session start. Roles are set by the IAM layer; App Studio only reads them.

// context object available in all token expressions
context.userId       →  "user-abc"
context.tenantId     →  "tenant-acme"
context.roles        →  ["admin", "sales-manager", "viewer"]
context.displayName  →  "Jane Smith"
context.email        →  "jane@acme.com"

Quick Reference

LayerConfig fieldWhereEffect if denied
App accessallowedRolesApp config403 page, no UI loads
Page visibilityrequiredRolesAppPage configHidden from sidebar; 403 on direct URL
Widget visibilityvisibleTo / visibilityExpressionWidget placementWidget not rendered
Data scopingServer-side filtersData serviceEmpty data set returned

In This Guide