gameplane / docs
AUTHOR MODULES

Test, Publish & Sign Modules

Prove a module locally, publish immutable OCI bundles, and use digest pinning and signatures for trustworthy upgrades.

Modules & Sourcesv0.220 MIN
Signature mismatches fail safely

A signature mismatch must leave the Module failed without replacing the last known-good GameTemplate.

Local acceptance

Validate and install through the same source path users will run, then exercise every advertised capability and version.

Validate metadata/schemaWait for ModuleSource synchronization to confirm catalog visibility.
Test server operationsCreate, readiness, console, files, players, backup, restore, and stop.
Verify PVC persistencePrevious version-specific PVCs survive version/loader switches.

Before publishing, validate that your module.yaml and template.yaml meet the schema requirements and that they appear in the ModuleSource catalog. Then create a test GameServer from your module and exercise every advertised feature: start the server, verify readiness, interact with the console, download files, check player lists, create and restore backups, and cleanly stop. Test upgrading from the previous version to confirm that data persists across version boundaries and that loader switches (if supported) don’t corrupt PVCs.

Sources and upgrades

Use semantic versions and immutable digests, then test discovery, explicit installation, rollback, and source failure.

Prefer OCI for productionImmutable digests and signature verification are OCI-registry concepts.
Keep catalog refresh separateSource polling should not trigger implicit upgrades; use explicit install/upgrade requests.
Test failure pathsBad bundles, missing versions, uninstall blockers, and recovery flows.

Publish modules to an OCI registry (ghcr.io, quay.io, or your self-hosted registry) and tag each release with a semantic version. OCI registries give you immutable content digests (sha256:…) and enable cosign signature verification, which are not available for git/http/local/upload sources.

Test discovery by pulling the catalog from your ModuleSource; confirm the module and all versions appear. Test explicit installation by specifying a version and a digest pin. Test upgrade by installing a previous version, then upgrading to the latest. Finally, test rollback and failure recovery by verifying that a misbehaving bundle does not replace the last known-good GameTemplate.

Supply-chain trust

Sign official bundles by digest, publish the matching public key, and keep private keys only in CI Secrets.

Key generationGenerate a signing key pair once; store the private key in CI Secrets.
Sign by digestUse cosign to attach a signature to each published bundle, recorded in Sigstore Rekor.
Verify offlineThe operator verifies signatures without requiring Rekor connectivity (air-gap friendly).

Sign each OCI bundle with a private key using cosign. The public key is committed to your repository and shipped to users; the private key never leaves your CI environment. Signatures are recorded in the public Sigstore Rekor transparency log, allowing users to prove that a bundle was signed and when. The operator’s verification path is keyed and offline — it does not require Fulcio or Rekor connectivity — so air-gapped clusters can still verify signatures.

To get started, generate a key pair using cosign generate-key-pair, store the private key in your CI system’s Secrets (e.g., GitHub Actions “release-signing” environment), and commit the public key to your repository root.

MODULE RELEASE

01   01 make dev-up && make modules-push
02   02 cosign sign --key env://COSIGN_PRIVATE_KEY --tlog-upload=false <digest>
03   03 cosign verify --key cosign.pub --insecure-ignore-tlog=true <digest>

The make modules-push command builds and pushes your module bundle, returning its OCI digest (in the form sha256:…). Use that digest to sign with cosign: --key env://COSIGN_PRIVATE_KEY reads the private key from an environment variable, and --tlog-upload=false keeps signing local (offline-friendly). To verify offline, use cosign verify --insecure-ignore-tlog=true with the public key committed to your repo.

For production releases, enable --tlog-upload=true to record signatures in the Rekor log, giving users proof that the bundle was signed at a specific time. For air-gapped authoring, keep the default (--tlog-upload=false) so bundles can be signed in CI and installed offline.


Further reading