Skip to main content

Route Registry

Route Registry is the Wormhole service that records routes, validates app authorization metadata, and returns the connection details needed to reach apps through Piko and Holepunch.

Table of Contents

Description

Route Registry is a Python FastAPI service that maps public Wormhole route names and URLs to target tunnel endpoints with authorization metadata. It registers routes for the Wormhole CLI, fetches and validates app-served /-/airlock/authz.json, stores route/community/domain/user/group state, issues Piko JWTs for tunnel access, and notifies Holepunch when route state changes. Major dependencies include FastAPI, SQLAlchemy, Alembic, Dynaconf, Celery, RabbitMQ, APScheduler, Authlib, cryptography, bcrypt, jsonschema, psycopg2, and fastapi-offline.

The code uses a layered service architecture. route_registry/command.py provides the CLI entry point for run, listen-tasks, openapi, and generate-jwks; route_registry/server.py assembles FastAPI routes and dependencies; route_registry/routers contains public and administrative API routers; route_registry/models.py defines attrs-based domain objects; route_registry/pydantic_models.py defines wire schemas; route_registry/store and route_registry/service/uow.py implement SQLAlchemy repositories and unit of work; route_registry/services.py contains domain workflows; and route_registry/celery.py plus route_registry/track.py handle async route validation and periodic status tracking.

Within Wormhole, Route Registry is the control-plane service that tells the CLI and gateway how a named app should be reached. A route registration returns the public Wormhole URL, the Airlock/Token Service JWT issuer URL, the Piko tunnel connect URL, a route endpoint ID, and a signed Piko JWT. Holepunch consumes this route state to configure Envoy, and Token Service/JWKS are used to authenticate users and automated callers.

How Route Registry Fits Into Wormhole

flowchart LR
    CLI["Wormhole CLI"]
    Registry["Route Registry API"]
    DB["Postgres"]
    Worker["Celery worker"]
    MQ["RabbitMQ"]
    Tracker["APScheduler tracker"]
    Token["Token Service"]
    Holepunch["Holepunch admin API"]
    Piko["Piko server"]
    App["Airlock-protected app"]

    CLI --> Registry
    Registry --> DB
    Registry --> Token
    Registry --> Piko
    Registry --> MQ
    MQ --> Worker
    Worker --> App
    Worker --> Holepunch
    Tracker --> DB
    Tracker --> Holepunch

The service bridges user-facing route creation and operator-facing gateway state. It owns route metadata and validation, while Holepunch owns active proxy behavior.

Configuration

Route Registry uses Dynaconf. Defaults live in route_registry/config/settings.toml; local overrides can be supplied with settings.toml, settings.local.toml, .secrets.toml, or DYNACONF_* environment variables.

Important configuration groups include:

Group Purpose
server FastAPI host, port, and loop settings.
db SQLAlchemy database URL and credentials.
celery RabbitMQ broker and result backend configuration.
auth Admin auth, JWT/JWKS, Token Service, and optional OIDC session auth.
url Public entry URL, Piko tunnel URL, Token Service URL, and Holepunch admin URL.
track.routes Route status check interval and stale-route threshold.

Generate per-environment JWKS material rather than reusing local files:

uv run route_registry generate-jwks --write-settings --overwrite

This creates jwks/private.pem, jwks/public.pem, jwks/kid.txt, and a local settings override when requested. Treat generated private keys as secrets.

Deployment

OpenShift and Helm

Production and development deployments are CI/OpenShift/Helm based. The parent chart in helm/route_registry deploys:

  • route-registry-core: FastAPI API service.
  • route-registry-worker: Celery worker for route validation tasks.
  • postgres: database stateful workload.
  • rabbitmq: broker for Celery tasks.

The core image starts the API with OpenTelemetry instrumentation. The worker image starts route_registry listen-tasks. The core deployment runs an init container that executes scripts/migrate-db, which waits for Postgres and runs:

alembic upgrade head

Required runtime secrets include:

Secret Purpose
postgres-credentials Supplies POSTGRESQL_USER and POSTGRESQL_PASSWORD to the API and migration container.
rabbitmq-secret Supplies rabbitmq-username and rabbitmq-password.
route-registry Supplies sensitive Dynaconf values such as auth/JWT/OIDC/admin secrets.

Manual deployment from route-registry/helm/route_registry follows the normal Helm pattern:

helm upgrade --install route-registry . -f values.yaml

CI validates, publishes, builds the API and worker images, copies images into OpenShift, deploys pre-production automatically for new versions, and deploys production manually.

Local Database

Local development can use SQLite for basic API work, but use Postgres whenever creating, testing, or reviewing Alembic migrations.

Start a local Postgres instance with Podman:

podman run --name some-postgres \
  -e POSTGRES_PASSWORD=secret \
  -p 5432:5432 \
  -d postgres:16.10

Update settings.toml or settings.local.toml with the local database URL and credentials as needed.

Development

Requirements:

  • Python 3.11 or newer
  • uv
  • Postgres for migration work
  • RabbitMQ for worker and e2e flows

Create a local environment and install the package:

uv venv
uv pip install -e .

Run the API:

uv run route_registry run --host localhost --port 5001

Run the Celery worker:

uv run route_registry listen-tasks

Run migrations:

uv run alembic upgrade head

Generate OpenAPI:

uv run route_registry openapi

Local Dev Authentication

Most endpoints require an authenticated user, which normally means standing up an external identity provider. For local development there is a local_dev authenticator that skips authentication entirely and resolves every request to a single seeded user.

This is for local development only. It accepts no credential and verifies nothing; never enable it anywhere else.

Seed the user (defaults to your machine username, idempotent):

uv run wormhole_route_registry seed-dev-user

Then start the server with the authenticator enabled:

DYNACONF_AUTH__auth_name=local_dev uv run wormhole_route_registry run

Or do both in one step -- make run-dev seeds the user and starts the server with local_dev auth already enabled:

make run-dev

Every API call now authenticates as that user, with no header, cookie or token:

curl http://localhost:5001/api/v1/community

Options:

  • --uid <uid> seeds a specific user instead of your machine username.
  • --admin / --no-admin control admin rights; re-running reconciles the flag on an already-seeded user. Defaults to auth.local_dev.is_admin (true).
  • Exporting LOGNAME=<uid> makes both the command and the authenticator act as another seeded user, which is handy for testing non-admin behavior.

Rather than setting the environment variable on every run, you can opt in from settings.local.toml, which is not checked in:

dynaconf_merge = true

[default.auth]
auth_name = "local_dev"

[default.auth.local_dev]
uid = ""        # defaults to the local machine username
is_admin = true

The default auth_name in route_registry/config/settings.toml stays base_auth -- do not change it there.

Common Commands

A Makefile wraps the commands above:

Target What it does
make sync-dev Install the dev environment
make sync-prod Install from the lockfile, without dev dependencies
make test Run the test suite under tox
make seed Seed the local dev user
make run-dev Seed, then run the API with local_dev auth
make listen-tasks Run the Celery worker (needs RabbitMQ)
make migrate Apply alembic migrations
make jwks Generate local JWKS and settings.local.toml
make openapi Write openapi.json
make lock / make lock-check Regenerate / verify uv.lock
make build Build the wheel into dist/

HOST and PORT override the bind address: make run-dev PORT=8001.

API and Workflow Notes

Important workflows:

  • Register a route: the API creates or updates route state, validates authorization metadata, and returns public URL plus Piko tunnel details.
  • Validate route authorization: the worker fetches the app-served /-/airlock/authz.json, validates it against the configured JSON schema, and stores resulting allow/deny rules.
  • Refresh Holepunch: route validation and tracking workflows call Holepunch admin endpoints so the gateway can refresh cached route state.
  • Authenticate callers: dependencies support admin header auth, Token Service token exchange, route JWT rotation, and optional OIDC session auth.
  • Manage communities: community routes allow shared policy and subtoken behavior across related routes.

The API is versioned under paths such as /api/v1, /api/v2, /api/latest, and /api/stable.

Testing

Run lint checks:

uvx tox -e lint

Run non-e2e tests:

uvx tox -- -m "not e2e"

Run e2e tests:

uv run route_registry generate-jwks --write-settings --overwrite
uvx tox -- -m e2e

E2E tests need live supporting resources such as RabbitMQ and generated local JWKS/settings. Tox delegates to pytest, so specific tests can be selected with normal pytest arguments after --.

Developer Notes

  • alembic/versions contains database migrations; use Postgres when creating or validating migrations.
  • tests/integration covers repository, unit-of-work, and service behavior.
  • tests/e2e exercises route registration, validation, JWT rotation, tracker status transitions, community endpoints, and admin CRUD.
  • Generated artifacts such as virtual environments, local databases, caches, and JWKS private keys should not be treated as reusable deployment assets.

Governance

Contributions are welcome. Contributors should look in CONTRIBUTING.md for project guidelines on how to create and structure pull requests.

This project is licensed under the Apache 2.0 license with LLVM exception. The full license text is available in LICENSE.

LLNL-CODE-2020712

Metadata

Release files for wormhole-route-registry 0.1.3

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

Source distribution (sdist)

Source distribution for wormhole-route-registry 0.1.3
File Size Uploaded
wormhole_route_registry-0.1.3.tar.gz 218.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for wormhole-route-registry 0.1.3
File Interpreter ABI Platform
wormhole_route_registry-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 271.1 kB

Release files / wormhole_route_registry-0.1.3.tar.gz

Download URL wormhole_route_registry-0.1.3.tar.gz
Size 218.2 kB
Tags Source
SHA-256 checksum
How to use checksums
cacca81d9b861d1b1563c7c52d39b1643013874107b3c51e53a767a87ea5edbb
BLAKE2b-256 checksum
How to use checksums
b3c4802b2959cea2a190912990061845a0d5c24c2ab3486d5ee328b7151e0655
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.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 Oct 5, 2026.

Transparency log

Release files / wormhole_route_registry-0.1.3-py3-none-any.whl

Download URL wormhole_route_registry-0.1.3-py3-none-any.whl
Size 52.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
10f7b21f989a5b451cf8be2304f16ad0df061a0f8d592e422e3e085b89c78f04
BLAKE2b-256 checksum
How to use checksums
089c0fc8450451f0d280752bc3c758ae711313bc1fdb92a0c1ef94f02e30eafd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.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 Oct 5, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.4

2 release files

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.0

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