No description
  • Go 69.9%
  • PLpgSQL 13%
  • Shell 10.1%
  • JavaScript 3.3%
  • TypeScript 3.1%
  • Other 0.5%
Find a file
Stefan Tanta 7d712cca19
Some checks failed
Continuous verification / verify (push) Failing after 30m19s
P10.9: remove agent release backfill
2026-09-02 10:28:03 +02:00
.forgejo/workflows P10.9: remove agent release backfill 2026-09-02 10:28:03 +02:00
cmd P10.8: complete operational integration 2026-09-01 13:41:37 +02:00
deploy P11.2: add Forgejo release artifacts 2026-09-02 02:40:50 +02:00
docs P10.9: publish permanent agent releases 2026-09-02 10:25:48 +02:00
internal P10.9: add release campaign harness 2026-09-01 14:25:56 +02:00
migrations P10.8: complete operational integration 2026-09-01 13:41:37 +02:00
proofs P10.5: complete ASVS verification matrix 2026-09-01 05:52:33 +02:00
proto/agent/v1 P9.6: track KSK and ZSK rollovers 2026-08-31 20:15:53 +02:00
scripts P10.9: remove agent release backfill 2026-09-02 10:28:03 +02:00
tests P10.9: remove agent release backfill 2026-09-02 10:28:03 +02:00
web P10.3: complete responsive accessibility verification 2026-09-01 04:14:28 +02:00
.dockerignore P1.7: build hardened OCI images 2026-08-23 04:36:32 +00:00
.gitignore P11.2: add Forgejo release artifacts 2026-09-02 02:40:50 +02:00
AGENTS.md add canonical KnotOps logo 2026-08-22 17:07:57 +00:00
buf.gen.yaml P7.1: checkpoint agent protocol implementation 2026-08-26 19:44:18 +00:00
buf.yaml P7.1: checkpoint agent protocol implementation 2026-08-26 19:44:18 +00:00
go.mod P7.2: checkpoint machine authentication work 2026-08-26 22:08:18 +00:00
go.sum P7.1: checkpoint agent protocol implementation 2026-08-26 19:44:18 +00:00
KnotOps-KICKOFF-PROMPT.md add canonical KnotOps logo 2026-08-22 17:07:57 +00:00
knotops-logo.svg add canonical KnotOps logo 2026-08-22 17:07:57 +00:00
README.md P10.9: publish permanent agent releases 2026-09-02 10:25:48 +02:00
TASKS.md P10.9: complete release campaign 2026-09-02 02:01:29 +02:00
toolchain.lock.json P10.9: publish permanent agent releases 2026-09-02 10:25:48 +02:00

KnotOps

KnotOps logo

KnotOps is a self-hosted control plane for authoritative DNS domains managed by Knot DNS. It manages domain records, zone lifecycle, DNSSEC, and TSIG within explicit tenant and server boundaries.

Components

  • api serves the HTTP API and the compiled web frontend.
  • worker performs durable DNS work and verifies authoritative results.
  • controller accepts the typed, authenticated agent protocol.
  • migrator applies the database schema as a one-shot process.
  • agent runs on a Knot host as a constrained systemd service.

The frontend is not a separate runtime image. The API image contains the exact frontend build for the same release.

Forgejo releases

Two tag-only Forgejo Actions workflows create release artifacts:

  • Publish control-plane images builds, checks, and publishes the API, worker, controller, and migrator images.
  • Build agent release builds the production systemd agent twice, compares the binaries, creates a deterministic archive, publishes its checksum, and attaches the verified files to a permanent Forgejo Release.

Configure a trusted Forgejo runner with the docker label. Give the runner a dedicated Docker daemon. Do not share the daemon with untrusted repositories. Add these repository Actions secrets:

  • REGISTRY_USERNAME: a dedicated Forgejo package publisher
  • REGISTRY_TOKEN: its limited package-write token

Allow only trusted release maintainers to create version tags. Protect those tags against deletion and replacement. Push a final semantic version tag to run both workflows:

git tag v1.2.3
git push origin v1.2.3

Manual workflow dispatch is accepted only when the selected ref is a valid release tag. Pull requests and branches cannot publish a release. The workflow does not create a mutable latest tag.

The release page contains the agent archive, SHA256SUMS, the verified content list, and public build metadata. Actions also retains the same files for 30 days as workflow evidence.

The control-plane workflow publishes these Linux AMD64 images:

git.step1.ro/stanta/knotops/api:1.2.3
git.step1.ro/stanta/knotops/worker:1.2.3
git.step1.ro/stanta/knotops/controller:1.2.3
git.step1.ro/stanta/knotops/migrator:1.2.3

Deploy the manifest digest from the workflow evidence, not the version tag. If a run publishes only some images, treat the release as failed. Do not replace the existing tags. Review the uploaded release.env and retry with a new version after the cause is fixed.

Control-plane installation

Production deployment needs PostgreSQL, the configured OIDC provider, Traefik, telemetry, and the fixed network flows in deploy/operations. Use the configuration examples in deploy/config. Store secret values only in protected files or mounts. Do not put them in image settings or command arguments.

Use this order for a first production deployment:

  1. Complete the read-only P11.1 inventory and compare it with the fixed topology.
  2. Create the database roles, protected secret mounts, and runtime configuration files.
  3. Resolve every candidate image to the digest recorded by Forgejo.
  4. Run the migrator once with its own database role.
  5. Start the API, worker, and controller with writes disabled.
  6. Verify health, identity, logs, metrics, database access, and authoritative DNS over UDP and TCP.
  7. Keep production DNS writes disabled until the later P11 gates pass.

The exact update, rollback, emergency mode, and verification procedure is in the operations runbook. It does not authorize a production DNS mutation.

Agent installation

The agent workflow produces knotops-agent-VERSION-linux-amd64.tar.gz, SHA256SUMS, CONTENTS, and release.env. Copy the archive and checksum to the Knot host through an authenticated channel. Verify them before installation:

sha256sum --check SHA256SUMS
tar --list --gzip --file knotops-agent-1.2.3-linux-amd64.tar.gz

Inspect CONTENTS and confirm that the version is the approved release. Extract the fixed package tree only after that check:

sudo tar --extract --gzip \
  --file knotops-agent-1.2.3-linux-amd64.tar.gz \
  --directory / \
  --strip-components=1 \
  --no-same-owner
sudo systemd-sysusers knotops-agent.conf
sudo systemd-tmpfiles --create knotops-agent.conf
sudo install -d -o root -g root -m 0755 \
  /etc/systemd/system/knotops-agent.service.d

Copy the two configuration examples from /usr/share/knotops-agent/examples to a private staging directory. Replace all placeholders. Set one exact controller IP in 20-controller-network.conf. Install the reviewed files with these destinations and modes:

sudo install -o root -g knotops-agent -m 0440 agent.json /etc/knotops/agent.json
sudo install -o root -g knotops-agent -m 0440 agent-mappings.json /etc/knotops/agent-mappings.json
sudo install -o root -g root -m 0444 20-controller-network.conf \
  /etc/systemd/system/knotops-agent.service.d/20-controller-network.conf
sudo /usr/local/sbin/render-knotops-agent-exec-paths \
  | sudo tee /etc/systemd/system/knotops-agent.service.d/10-knotc-exec-paths.conf >/dev/null
sudo chmod 0444 /etc/systemd/system/knotops-agent.service.d/10-knotc-exec-paths.conf
sudo systemd-analyze verify knotops-agent.service

Provision agent credentials as protected files under /etc/knotops/secrets/agent. Never copy secret values into logs, Forgejo artifacts, screenshots, or the repository. Start the service after the protected configuration and credential files are complete:

sudo systemctl daemon-reload
sudo systemctl enable --now knotops-agent.service

Confirm the service identity, network restriction, controller connection, and metrics before adoption.

Local verification

The full release check needs Docker and can take more than one hour:

bash scripts/ci/verify.sh

For a faster source check, use the pinned Go and Node versions from toolchain.lock.json:

go test ./...
cd web
npm ci --ignore-scripts --no-audit --no-fund
npm run typecheck
npm test

The kickoff document defines the product and trust boundaries. TASKS.md defines the ordered acceptance gates.