Skip to main content

tessera logo

Acquire and securely store OAuth2/OIDC tokens in JupyterHub.

CI Documentation PyPI Python License


tessera adds a per-server button in JupyterLab. On click, the user runs an OAuth2/OIDC authorization-code flow (confidential client, PKCE). A JupyterHub Service receives the callback, exchanges the code, and stores the refresh token encrypted at rest. Notebooks then read a fresh access token from the Service on demand. The button is green when a valid refresh token exists, red otherwise. tessera is generic: any OAuth2/OIDC provider is a configuration entry.

tessera is not an Authenticator. It never signs anyone in to JupyterHub: your Hub keeps whatever Authenticator it already uses (PAM, LDAP, OAuth, or any other). tessera runs a separate step after that login, acquiring tokens from external OAuth2/OIDC providers so notebooks can call the APIs those providers protect.

The tessera panel in JupyterLab: one button per declared server, green when a valid refresh token is stored, with token details on demand

Signed in on 6 August, still green on 10 August: the access token expired several times in between, and each one was renewed from the stored refresh token, on demand.

How it works

  1. One button per declared server. The panel shows a button for each OAuth server in your configuration, green when a valid refresh token is stored for that user, red otherwise.
  2. A click starts an authorization-code flow with PKCE. The Service generates the state and the PKCE verifier, sends the browser to the provider with the S256 challenge, and keeps the verifier to itself.
  3. The provider calls back to the Service, which validates the state against the flow it started and exchanges the code for tokens. The browser never handles a token.
  4. The refresh token is encrypted at rest, with the encryption key held separately from the database file, so the database on its own reveals nothing.
  5. Notebooks read an access token on demand. The kernel client (get_token("my-idp"), or TESSERA_TOKEN["my-idp"]) fetches a fresh token from the Service on each access. Nothing is cached kernel-side and no token ever sits in an environment variable, so a token revoked at the provider is never served from a stale copy.

Architecture (three surfaces)

Surface Stack Role
Frontend TypeScript/React Per-server status button (green/red), shipped as a prebuilt JupyterLab extension.
Service Python 3.10+ JupyterHub Service exposing /login, /callback, /token; encrypted token store.
Admin CLI Python (Typer) Deployment and ops helpers: config-snippet, init-config, doctor, install-kernel-config.

Install

pip install jupyterhub-tessera

Installing the Python package also ships the prebuilt JupyterLab extension; no manual frontend copy is required.

Project layout

Path What lives there
src/tessera/ Service, admin CLI, kernel client, and the prebuilt lab extension
frontend/src/ TypeScript/React panel sources, with their tests alongside them
tests/ Python test suite (config, flow, store, service, kernel, end to end)
docs/ Sphinx documentation sources

Development

Requirements: Python 3.10+, Node.js 20+.

# Python (use a virtual environment created outside any synced folder)
pip install -e ".[dev]"

# Frontend
npm install
npm run build

Security

A refresh token and a client secret are encrypted at rest, with the encryption key held separately from the database. The frontend never reads, stores, or logs a token; it only consumes a boolean status.

License

MIT, Copyright (c) 2026 Michel TRUONG.

Metadata

Release files for jupyterhub-tessera 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jupyterhub-tessera 1.1.0
File Size Uploaded
jupyterhub_tessera-1.1.0.tar.gz 757.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jupyterhub-tessera 1.1.0
File Interpreter ABI Platform
jupyterhub_tessera-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 848.0 kB

Release files / jupyterhub_tessera-1.1.0.tar.gz

Download URL jupyterhub_tessera-1.1.0.tar.gz
Size 757.8 kB
Tags Source
SHA-256 checksum
How to use checksums
d7d57e20a278cbe2e57f9049d57014486a5d1044efd1b26f4b7dbc421d886275
BLAKE2b-256 checksum
How to use checksums
158761b218862dd9e78fd25e942773c46f3fbcc13789bc746eb6eb58d79de738
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.

Transparency log

Release files / jupyterhub_tessera-1.1.0-py3-none-any.whl

Download URL jupyterhub_tessera-1.1.0-py3-none-any.whl
Size 90.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
586040f5a6d6391a63318f93042c132c29bf72fe2cbc94c2d4988fdbf9f6c121
BLAKE2b-256 checksum
How to use checksums
a8fea87c75e5299718961e433d5ead7f33b40ae0c16328fea46cd6cdb0b9d086
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page