Skip to main content

wyrmctl

Owner-scoped GitOps for Nginx Proxy Manager

Validate desired-state YAML, plan safe owner-scoped changes, apply clean reconciles, and adopt existing NPM resources only when you ask for it.

PyPI version Python versions CI Live NPM Gate SSOT governed Apache 2.0 License

wyrmctl package hits wyrmctl downloads

wyrmctl architecture infographic

wyrmctl is the Python package and console script for declarative, owner-scoped Nginx Proxy Manager automation. It manages proxy hosts, certificates, access lists, redirection hosts, dead hosts, streams, users, settings, and provider-backed DNS records without silently mutating foreign-owned resources.

Supported Python Versions

wyrmctl supports Python 3.10, 3.11, 3.12, 3.13, and 3.14.

Why wyrmctl

  • Owner-scoped reconciliation instead of global mutable state
  • Explicit plan, apply, and adopt flows instead of ad hoc API scripting
  • Safe reference handling for certificates and access lists
  • Fail-closed behavior when the target NPM schema does not support a required operation
  • CLI-first workflows that fit GitOps, CI, and controlled repair operations
  • Independently versioned contracts, reproducibility lockfiles, and immutable reviewed plan artifacts
  • Transactional adjacent migrations with backups, chained ledgers, leases, and explicit recovery classification

FAQ

What is wyrmctl?

Answer: wyrmctl is a GitOps-style controller for Nginx Proxy Manager that reads desired-state YAML, compares it to the live NPM API, and produces safe owner-scoped plans before any mutation happens.

What problem does wyrmctl solve?

Answer: wyrmctl replaces manual NPM clicking and one-off API scripts with repeatable desired state, explicit adoption, conflict detection, and controlled reconciliation for reverse-proxy resources.

Does wyrmctl modify resources it does not own?

Answer: No. wyrmctl treats NPM resources as owner-scoped, refuses to mutate foreign-owned resources, and only attaches metadata to unmanaged resources when you run wyrmctl adopt.

How does wyrmctl handle certificate issuance and rotation?

Answer: wyrmctl treats certificates as declarative resources in the same desired state as proxy hosts. Issuance happens when a desired certificate must be created, and rotation happens through explicit reconcile policy rather than hidden mutation of unrelated resources.

Can wyrmctl adopt existing manually created NPM resources?

Answer: Yes. wyrmctl adopt can attach wyrmctl ownership metadata to compatible unmanaged resources so future plans and applies can manage them under explicit owner scope.

Install

Use pipx for an isolated CLI install:

pipx install wyrmctl
wyrmctl --version

Use uv if you manage tools with uv:

uv tool install wyrmctl
wyrmctl --help

Use pip inside an existing virtual environment:

python -m venv .venv
. .venv/bin/activate
python -m pip install wyrmctl
wyrmctl --help

PowerShell activation:

python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install wyrmctl
wyrmctl --help

Configure NPM

Set Nginx Proxy Manager API credentials as environment variables:

export NPM_BASE_URL=http://127.0.0.1:81/api
export NPM_IDENTITY=admin@example.com
export NPM_SECRET=changeme

Or pass them directly:

wyrmctl --base-url http://127.0.0.1:81/api --identity admin@example.com --secret changeme health

Quick Start

Validate desired state without touching the API:

wyrmctl validate ./desired-state
wyrmctl --output json validate ./desired-state

Plan owner-scoped changes:

wyrmctl plan ./desired-state --owner workload-a

Apply a clean plan:

wyrmctl apply ./desired-state --owner workload-a

Adopt unmanaged matching resources:

wyrmctl adopt ./desired-state --owner workload-a
wyrmctl adopt ./desired-state --owner workload-a --allow-field-drift

Desired State

Every managed resource needs wyrmctl ownership metadata:

apiVersion: wyrmctl.com/v1
schemaVersion: 2
proxy_hosts:
  - domain_names: [app.example.com]
    forward_scheme: http
    forward_host: app
    forward_port: 3000
    meta:
      managed_by: wyrmctl
      owner: workload-a
      resource_id: proxy.app

References use resource_id values:

apiVersion: wyrmctl.com/v1
schemaVersion: 2
certificates:
  - name: wildcard-example
    domain_names: ["*.example.com", example.com]
    certificate_type: letsencrypt
    api_payload:
      provider: letsencrypt
    meta:
      managed_by: wyrmctl
      owner: workload-a
      resource_id: cert.wildcard-example
access_lists:
  - name: private-admins
    api_payload:
      satisfy_any: 0
      items: []
      clients: []
    meta:
      managed_by: wyrmctl
      owner: workload-a
      resource_id: acl.private-admins
proxy_hosts:
  - domain_names: [app.example.com]
    forward_host: app
    forward_port: 3000
    certificate_ref: cert.wildcard-example
    access_list_ref: acl.private-admins
    ssl_forced: 1
    allow_websocket_upgrade: 1
    caching_enabled: 1
    block_exploits: 1
    meta:
      managed_by: wyrmctl
      owner: workload-a
      resource_id: proxy.app

More Documentation

Metadata

Release files for wyrmctl 0.4.8

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

Source distribution (sdist)

Source distribution for wyrmctl 0.4.8
File Size Uploaded Provenance Actions
wyrmctl-0.4.8.tar.gz 74.3 kB With provenance Details for wyrmctl-0.4.8.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for wyrmctl 0.4.8
File Interpreter ABI Platform Actions
wyrmctl-0.4.8-py3-none-any.whl Python 3 none any Details for wyrmctl-0.4.8-py3-none-any.whl

Total release size: 171.4 kB

Release files / wyrmctl-0.4.8.tar.gz

Download URL wyrmctl-0.4.8.tar.gz
Size 74.3 kB
Tags Source
SHA-256 checksum
How to use checksums
dac542f2f53a8f9b6037f8d9db5a2df39a070a2a3efa00f02698b17f966e413b
BLAKE2b-256 checksum
How to use checksums
56ebb169dde9b7b528de85aebe45fb7363933c7f838e73cae0f000e194e1d0e5
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 Nov 2, 2026.

Transparency log

Release files / wyrmctl-0.4.8-py3-none-any.whl

Download URL wyrmctl-0.4.8-py3-none-any.whl
Size 97.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f9b02b5ba9868501b6da48adbb3bdd2dd0b455b8d5a20aa93a780e09acd287dd
BLAKE2b-256 checksum
How to use checksums
e7450b15e31348a84511b0313a0bd07e6da353ff176ae8534609a712aaf0c568
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 Nov 2, 2026.

Transparency log

Security for wyrmctl 0.4.8

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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for wyrmctl-0.4.8.tar.gz

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 Nov 2, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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