Skip to main content

GNY server

Project description

GNY

This is currently ALPHA software — lots of bits and pieces are missing.

GNY is a FastAPI-based server that manages DNS TXT records for ACME dns-01 certificate challenges. It is designed to be used as a hook target for certbot (or any ACME client) when automating TLS certificate issuance and renewal.

Overview

GNY exposes a small REST API (documented in openapi.yaml) that lets enrolled servers add and remove _acme-challenge.* DNS TXT records. Access is controlled by:

  1. Enrollment — a server registers its IP address and administrator email, receiving a Bearer token.
  2. Email confirmation — an administrator with access_level >= 1 confirms the enrollment via OIDC login (Google, Azure AD, or any standard OIDC provider), activating the token.
  3. PTR-based authorization — an enrolled server may only manage TXT records for its own hostname (as resolved by reverse-DNS lookup of its IP address).

Requirements

  • Python 3.11+
  • MariaDB or MySQL database
  • An OIDC client (Google Cloud OAuth2, Azure AD/Entra ID app registration, or any standard OIDC provider) for enrollment confirmation
  • The enrolling server must have a valid PTR (reverse-DNS) record

Installation

PyPI

pip install gny

Debian package

Pre-built .deb packages are attached to each GitHub Release:

wget https://github.com/svalgaard/gny/releases/latest/download/gny_<version>_all.deb
sudo dpkg -i gny_<version>_all.deb
sudo apt-get install -f   # resolve any missing dependencies

Docker

docker pull ghcr.io/svalgaard/gny:latest

Configuration

Create a .env file and set the following variables:

Variable Description
APP_URL Public base URL of this server (e.g. https://dns.example.com)
DB_HOST MariaDB/MySQL hostname
DB_DATABASE Database name
DB_USERNAME Database user
DB_PASSWORD Database password
OIDCProviderMetadataURL OIDC Discovery document URL (see below)
OIDCClientID OIDC client ID
OIDCClientSecret OIDC client secret
OIDCRedirectURI OIDC redirect path (default /.well-known/sso)
MAIL_HOST SMTP hostname for outgoing mail (default localhost)
MAIL_PORT SMTP port (default 25)
MAIL_ENCRYPTION SMTP encryption: tls, starttls, or none (default tls)
MAIL_USER SMTP username
MAIL_PASSWORD SMTP password
APP_MAIL_ADDRESS From-address for outgoing mail
ENROLL_CONFIRM_TIMEOUT_HOURS Hours before an unconfirmed enrollment expires (default 32)
LOG_LEVEL Logging level: debug, info, warning, error
DISPLAY_ERRORS Show error details in responses (true / false)

The redirect URI registered with the OIDC provider must be {APP_URL}{OIDCRedirectURI}, e.g. https://dns.example.com/.well-known/sso.

OIDC provider examples

Google:

OIDCProviderMetadataURL=https://accounts.google.com/.well-known/openid-configuration

Azure AD / Entra ID (replace {tenant_id} with your directory tenant ID):

OIDCProviderMetadataURL=https://login.microsoftonline.com/{tenant_id}/v2.0/.well-known/openid-configuration

Running

Direct

uvicorn gny.main:app --host 0.0.0.0 --port 8000

The database tables are created automatically on startup. Interactive API docs are available at http://localhost:8000/docs.

Docker

docker run --env-file .env -p 8000:8000 ghcr.io/svalgaard/gny:latest

Client Setup

The recommended certbot plugin is certbot-dns-gny, available from PyPI:

pip install certbot-dns-gny

Refer to its documentation for credentials file format and certbot integration.

API

All endpoints are under /api. Full spec: openapi.yaml.

Enrollment workflow

1. Enroll

POST /api/enroll
Content-Type: application/json

{ "mail": "admin@example.com" }

Returns a Bearer token, e.g., gny-ab3df26e48b2467bf705156d4c8914f2. The server's IP must resolve to a PTR record or the request is rejected with 409.

2. Confirm enrollment

Open the following URL in a browser as an administrator (a user with access_level >= 1):

GET /api/enroll/start?token={token}

This redirects to the configured OIDC provider (Google, Azure AD, etc.). After authenticating, the provider redirects back to /.well-known/sso, which upserts the user record and activates the enrollment token.

On first login, every user is created with access_level = 0. An existing administrator must grant access before a new user can confirm enrollments:

UPDATE users SET access_level = 1 WHERE mail = 'admin@example.com';

Alternatively, the /api/enroll/confirm endpoint accepts an OIDC Bearer token directly and confirms the enrollment programmatically (still requires access_level >= 1).

Managing TXT records

All requests below require Authorization: Bearer {enrollment_token}.

Add a record

POST /api/txt?name=_acme-challenge.example.com&text=<validation_token>

Delete a record

DELETE /api/txt?name=_acme-challenge.example.com&text=<validation_token>

Test authorization

GET /api/txt/test?name=_acme-challenge.example.com

Returns {"status": "ok"} if the authenticated server is allowed to manage that name, or 403 otherwise.

Authorization rules

A server enrolled from IP 1.2.3.4 whose PTR record resolves to server.example.com may manage any TXT record whose domain component (after stripping a leading _acme-challenge.) equals or is a subdomain of server.example.com.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gny-0.0.3.tar.gz (28.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gny-0.0.3-py3-none-any.whl (24.2 kB view details)

Uploaded Python 3

File details

Details for the file gny-0.0.3.tar.gz.

File metadata

  • Download URL: gny-0.0.3.tar.gz
  • Upload date:
  • Size: 28.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gny-0.0.3.tar.gz
Algorithm Hash digest
SHA256 59de4ff6aa60b239c1a2ecf5e20ff74ff6b4973494667c9cdaf2c695f299e62f
MD5 feaf58dfd2fd0540444a0b8c76196693
BLAKE2b-256 b0ef99a5343aadc14532637504eb67c3f36cff6026bc9d9cb8ac951a0ab13844

See more details on using hashes here.

Provenance

The following attestation bundles were made for gny-0.0.3.tar.gz:

Publisher: release.yml on svalgaard/gny

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gny-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: gny-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 24.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gny-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 3f3294f3a31f202cfb12670be40b7497eea96104c3235cb04425582989b8a7dc
MD5 6c12460edb1b23fa0d0ba9e1dcd05d94
BLAKE2b-256 1f95c07ea55b5aac7a1afc1b8b7da63562c1192d54efe51c6d6f7cff09c56014

See more details on using hashes here.

Provenance

The following attestation bundles were made for gny-0.0.3-py3-none-any.whl:

Publisher: release.yml on svalgaard/gny

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page