Verifier setup for 2026.07.0 through 2026.08.2
Positron Server 2026.07.0 through 2026.08.2 do not validate a license file. These versions accept only a signed license token, so the Hub must mint one for each session. This page covers that setup.
This setup is not recommended. It applies only to Positron Server 2026.07.0 through 2026.08.2. Positron Server 2026.09.0 and newer validate a license file directly, which removes the signing key, the Hub service, and the extra Python package. For those versions, follow the Get started guide instead.
What you need from Posit
Send email to academic-licenses@posit.co to request both files:
- Signing key (
signing-key.pem): the RSA private key that mints per-session license tokens - License file (
license.lic): proof of entitlement
Positron spells the CPU architecture three ways. The download filename uses x64 or arm64, the CDN path uses x86_64 or arm64, and the activation directory uses x86_64 or aarch64. Throughout this guide, <arch> means the activation directory name.
Step 1: Install Positron Server in the single-user image
Terminal
curl -L "https://cdn.posit.co/positron/releases/server/x86_64/positron-server-linux-x64-2026.08.2-4.tar.gz" \
-o /tmp/positron-server.tar.gz
mkdir -p /opt/positron-server
tar -xzf /tmp/positron-server.tar.gz -C /opt/positron-server --strip-components=1For the arm64 build, replace the CDN path segment with arm64 and the filename segment with arm64.
Place the license file inside Positron Server, and restrict it so only root, which covers the Hub and the verifier, can read it:
Terminal
install -m 600 license.lic /opt/positron-server/resources/activation/linux/<arch>/license.licMode 600 is correct for these versions only. The verifier reads this file as root, and sessions never touch it. Positron Server 2026.09.0 and newer need mode 644, because each session reads the file itself.
Step 2: Install jupyter-positron-server in the single-user image
Terminal
# for example, in The Littlest JupyterHub
/opt/tljh/user/bin/pip install 'jupyter-positron-server>=0.0.5'This proxy extension runs as the user. It requests a license from the Hub at session start and passes it to positron-server. Version 0.0.5 or newer is required for compatibility with these Positron Server releases.
Step 3: Install jupyter-positron-verifier on the Hub
Install the minting service in the Hub Python environment, not the single-user image:
Terminal
# for example, in The Littlest JupyterHub
/opt/tljh/hub/bin/pip install jupyter-positron-verifierStore the signing key where the Hub service account can read it and users cannot:
Terminal
mkdir -p /etc/positron
install -m 600 -o <hub-user> signing-key.pem /etc/positron/signing-key.pemThe signing key pairs with the public key embedded in positron-server. The license file is already in place from Step 1. The verifier reads it through license-manager, so the Hub needs no separate copy.
Step 4: Register the verifier as a JupyterHub service
Add this to jupyterhub_config.py:
jupyterhub_config.py
c.JupyterHub.services = [
{
"name": "positron-license",
"url": "http://127.0.0.1:10101",
"command": ["positron-verifier"],
"environment": {
"POSITRON_MINTING_KEY_FILE": "/etc/positron/signing-key.pem",
"POSITRON_LICENSE_MANAGER_PATH": "/opt/positron-server/resources/activation/linux/<arch>/license-manager",
"PORT": "10101",
},
}
]
c.JupyterHub.load_roles = [
{
"name": "positron-license-service",
"services": ["positron-license"],
"scopes": ["read:users"],
}
]POSITRON_MINTING_KEY_FILE points at the signing key from Step 3. POSITRON_LICENSE_MANAGER_PATH points at the license-manager binary inside the Positron Server install, which the verifier runs to confirm entitlement against license.lic. That binary sits in the same directory as the license.
Step 5: Point single-user servers at the minting endpoint
Tell jupyter-positron-server where to fetch licenses, and put positron-server on the session PATH, by adding this to jupyterhub_config.py:
jupyterhub_config.py
import os
c.Spawner.environment = {
"PATH": "/opt/positron-server/bin:" + os.environ.get("PATH", "/usr/local/bin:/usr/bin:/bin"),
"POSITRON_LICENSE_MINTING_ENDPOINT": "http://127.0.0.1:10101/services/positron-license/mint",
}Step 6: Restart JupyterHub
Terminal
systemctl restart jupyterhubThe verifier starts automatically as a managed JupyterHub service.
How it works
When a student opens Positron:
jupyter-positron-servercalls the Hub minting endpoint, authenticated with itsJUPYTERHUB_API_TOKEN, and sends the connection token for the session.jupyter-positron-verifierverifies the user token, confirms entitlement throughlicense-manager, which readslicense.lic, and returns a signed license JSON bound to that connection token.jupyter-positron-serverstartspositron-serverwith the license inPOSITRON_LICENSE_KEY.positron-serververifies the RSA signature with its embedded public key and starts.
Hub (privileged)
signing-key.pem /etc/positron/, root-only, never reaches users
jupyter-positron-verifier confirms entitlement, mints a signed license
at each session start
Single-user server
jupyter-positron-server requests a license, passes it to positron-server
positron-server verifies the signed license and starts
license.lic mode 600, read only by the Hub and the verifier
Next steps
- To move off this setup, see Move an existing deployment off the verifier.
- Configuration covers the environment variables that
jupyter-positron-serverreads. - Troubleshooting covers a verifier that does not start and a mint call that fails.