Secure your Domino App with access control and permissions. This page explains how to control who can view and edit your apps, how to manage access requests from users, and how apps can identify viewers and act on their behalf.
Domino provides three levels of identity propagation for Apps, each offering different capabilities and security levels:
-
Basic identity: Know who is viewing your app (username only)
-
Enhanced identity: Verify user identity with tokens (username, email, user ID)
-
Extended identity: Act on behalf of users with their full permission (access data, submit jobs, manage projects)
Control who can view and edit your Apps to protect sensitive data and manage collaboration.
Edit permissions are inherited from the project level because apps are part of projects. When you add someone as a project collaborator, they can automatically edit any apps in that project. To add new editors, add them as collaborators to the project where the app resides.
View permissions are set at the app level and can follow one of two modes:
-
Restricted: Only users you explicitly list and project collaborators can view (or edit). Use Restricted mode when your app handles sensitive data or is intended for specific team members only.
-
Anyone in Domino: Anyone with a Domino account can view (or edit). Use Anyone in Domino for internal tools, dashboards, or resources that all employees should access.
Discovery vs. viewing
Domino distinguishes between:
-
Discovering an App: Seeing it listed in App views
-
Viewing an App: Opening and using it
This separation lets you create a browsable app catalog where users can explore available apps and request access to ones they need, without giving them immediate access to potentially sensitive content.
Restricted mode options
When an app’s view permissions are set to Restricted, additional options appear:
-
Globally discoverable: All Domino users can find the app and request access to view it
-
Viewers: App owners can manage the list of users who can view the app, and accept or deny requests for access
Where to set permissions
You can set these permissions when publishing an App in the Access and sharing tab, or at any time after publication by selecting Share from the App list view.
After you set permissions, users with view access can open and interact with your app. Users without access will see the app listed (if globally discoverable) with a Request access button.
Access requests create a self-service model for app discovery. Users can find and request access to apps they need without contacting IT or app owners directly, while owners maintain full control over who can view their apps.
Request access to an app
If you see Request access next to an app in the Domino apps list view, the app is globally discoverable but you don’t have view permissions yet. To request access:
-
Find the app in the Domino Apps list view.
-
Click Request access.
You’ll receive a Domino notification and an email when the owner grants you access.
Domino apps can identify and authenticate viewers at three different levels. Each level provides different information and capabilities to help you build personalized, secure applications.
-
Basic identity tells you who is viewing your app by passing the username in an HTTP header. Use this for loading user-specific defaults, preferences, or displaying personalized content.
-
Enhanced identity verifies user identity with signed tokens that include username, email, and user ID. Use this when you need cryptographic proof of identity or additional user attributes beyond the username.
-
Extended identity lets your app act on behalf of users with their full permissions. Your app can access user data, submit jobs, manage projects, and perform other authorized actions in Domino. Users must explicitly grant consent before the app receives these permissions.
Basic identity propagation
Use basic identity when you need to know who is viewing your app. This is useful for loading user-specific defaults, preferences, or displaying personalized content. Domino passes the username in an HTTP header called domino-username.
If users who aren’t logged in to Domino view your apps, the domino-username header value is Anonymous.
|
Note
| Identity headers are only available in frameworks that support proxied HTTP headers. Flask and Dash support them by default. Shiny requires that you use Server Pro. |
- Example: Display the viewer’s username
-
This Flask example shows how to get the Domino username of an app viewer:
#!/usr/bin/env bash
export LC_ALL=C.UTF-8
export LANG=C.UTF-8
export FLASK_APP=app.py
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0Create an app.py file that renders a template called index.html:
import flask
from flask import request, redirect, url_for
class ReverseProxied(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
if script_name:
environ['SCRIPT_NAME'] = script_name
path_info = environ['PATH_INFO']
if path_info.startswith(script_name):
environ['PATH_INFO'] = path_info[len(script_name):]
return self.app(environ, start_response)
app = flask.Flask(__name__)
app.wsgi_app = ReverseProxied(app.wsgi_app)
# Homepage which uses a template file
@app.route('/')
def index_page():
return flask.render_template("index.html")Create a template file at templates/index.html:
<!DOCTYPE html>
<html>
<body>
<h1>Your username is {{ request.headers.get("domino-username") }}</h1>
</body>
</html>When you host this app in Domino and open it, you’ll see the username that matches the app user.
Enhanced identity propagation
Use enhanced identity when you need verified user information beyond just the username. This approach validates the token to make sure that identity information is authentic and hasn’t been tampered with.
When the SecureIdentityPropagationToAppsEnabled feature flag is enabled, Domino hosts apps at a different URL structure (https://<domino-domain>/apps/<app-id>/) and passes a JWT authorization token in the Authorization HTTP Header.
|
Note
|
When com.cerebro.domino.apps.extendedIdentityPropagationToAppsEnabled is enabled, it supersedes SecureIdentityPropagationToAppsEnabled.
|
You can verify the token’s integrity and decode it to get the user’s username, email, and Domino userID. The token audience is scoped to a limited set of Domino endpoints, restricting what operations the app can perform.
|
Note
| Identity headers are only available in frameworks that support proxied HTTP headers. Flask and Dash support them by default. Shiny requires that you use Server Pro. |
- Configure the base path
-
Some application servers need to know their base path to correctly handle routing, generate URLs, and serve static assets. Without proper base path configuration, your app may fail to load resources or generate broken links.
If your application server requires a base path configuration, read it from the DOMINO_RUN_HOST_PATH environment variable.
- Example: Verify and decode JWT token
-
Extract the token from the
Authorizationheader:
def extract_token(self, headers):
auth_header = headers.get('Authorization', '')
return auth_header[7:] if auth_header.startswith('Bearer ') else NoneVerify and decode the token (using this example JWKS):
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from jwt import decode, get_unverified_header
import base64, json, jwt, requests
def verify_and_decode_jwt_token(token):
keycloak_domain = "http://keycloak-http.domino-platform"
jwks_url = f"{keycloak_domain}/auth/realms/DominoRealm/protocol/openid-connect/certs"
jwks_dict = requests.get(jwks_url).json()
kid = get_unverified_header(token).get('kid')
public_key = None
for key in jwks_dict['keys']:
if key['kid'] == kid:
x5c = key['x5c'][0]
cert = x509.load_der_x509_certificate(base64.b64decode(x5c), default_backend())
public_key = cert.public_key()
break
if not public_key:
raise ValueError("No public key found for kid")
pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
return jwt.decode(token, pem, algorithms=['RS256'], audience="apps")Here is a decoded payload example:
{
"sub": "66d9fc7a538b60bef7c02c9c",
"preferred_username": "userName",
"email": "userName@domain.com",
"given_name": "givenName",
"family_name": "familyName"
}Extended identity propagation
Use extended identity when your app needs to perform actions on behalf of users. Your app can access user data, submit jobs, manage projects, and perform other actions the user is authorized to do in Domino.
When the com.cerebro.domino.apps.extendedIdentityPropagationToAppsEnabled configuration control is enabled, apps can request permission to act on behalf of users. Users must explicitly grant consent before the app receives these permissions.
|
Important
| This feature is disabled by default. Extending identity propagation provides full access to Domino APIs that a user has permission to access. Only SysAdmins or CloudAdmins can publish apps with this feature enabled. |
- How it works
-
-
Users see a consent prompt when they open an app that requests extended permissions.
-
If users grant consent, the app can retrieve a token with full user scope.
-
The app implements code to retrieve the user’s token from the Authorization header.
-
The app calls Domino APIs as the user using this token.
-
Users can choose to remember their consent for an extended period.
-
Consent has an expiration date and is auditable. The default expiration is 8 hours, but users can specify up to 30 days for an expiration date on the App consent page.
- Retrieve user token
auth_token = request.headers.get('Authorization', '')
token = auth_token[7:] if auth_token.startswith('Bearer ') else ""Without extended identity propagation enabled, the same code can retrieve a token, but it will have limited scope instead of full user permissions.
When com.cerebro.domino.apps.extendedIdentityPropagationToAppsEnabled is enabled, it supersedes SecureIdentityPropagationToAppsEnabled. The app has access to the user’s full credentials only if the publisher enables extended propagation in the app and the user grants consent.
|
Warning
| Apps with extended permissions can access all data the user can access and perform actions as the user. Only enable this for apps you trust. Once you have enabled extended identity propagation on an app, it can’t be disabled. |
- To enable extended identity propagation
-
-
The configuration record must be enabled.
-
The app must have extended app propagation enabled.
-
The app’s code must actually use the viewer’s token.
-
The viewer must consent.
-
- Example: Use extended permissions
-
The application base path can be read from the
DOMINO_RUN_HOST_PATHenvironment variable and used to set the base path in your server configuration:
import os
from flask import (
Flask,
)
class ReverseProxied(object):
def __init__(
self,
app,
):
self.app = app
def __call__(
self,
environ,
start_response,
):
script_name = os.environ.get('DOMINO_RUN_HOST_PATH', '')
if script_name:
environ["SCRIPT_NAME"] = script_name
path_info = environ["PATH_INFO"]
if path_info.startswith(script_name):
environ["PATH_INFO"] = path_info[len(script_name) :]
# Setting wsgi.url_scheme from Headers set by proxy before app
scheme = environ.get(
"HTTP_X_SCHEME",
"https",
)
if scheme:
environ["wsgi.url_scheme"] = scheme
return self.app(
environ,
start_response,
)
app = Flask(__name__)
from app import (
views,
)
app.wsgi_app = ReverseProxied(app.wsgi_app)-
Publish and share an app: Learn how to publish apps and manage permissions.
-
Allow external resources in Apps: Apps may be blocked from loading content unless those URLs are explicitly allowlisted.
-
Feature flags reference: View all available feature flags and configuration controls.
