Notifier Bootstrap Pack Guide
The Bootstrap Pack gives operators a deterministic set of configuration files to stage the Notifier service in sealed or fully air-gapped environments. The assets ship alongside the Offline Kit under bootstrap/notify/ and can be copied directly onto the hosts that run StellaOps.Notifier.WebService.
Contents
| File | Purpose |
|---|---|
notify.yaml | Sealed-mode configuration derived from etc/notify.airgap.yaml. It disables external resolution by pointing to in-cluster services and honours the shared EgressPolicy. |
plugins/notify/base/ | Required Notify base connector bundle. It is generated by devops/build/package-runtime-plugins.ps1 -Module notify -Profile base and contains only the StellaOps.Notify.Connectors.InApp and StellaOps.Notify.Connectors.InAppInbox entry assemblies, their dependency DLLs such as StellaOps.Notify.Connectors.Shared.dll, notify-plugin.json, checksums, and detached assembly signatures such as <assembly>.dll.sig. Missing either base connector keeps /readyz unready. |
plugins/notify/recommended/ | Optional recommended delivery overlay generated by devops/build/package-runtime-plugins.ps1 -Module notify -Profile recommended. The current admissible bundle set contains the real Email and Webhook connector entry assemblies, dependency DLLs, manifests, checksums, and detached signatures. |
plugins/notify/harness/ | Deterministic harness overlay generated by devops/build/package-runtime-plugins.ps1 -Module notify -Profile harness. It includes the required InApp/InAppInbox base connectors plus StellaOps.Notify.Plugin.Dummy, a dry-run INotifyChannelConnector that responds without external delivery. |
plugins/notify/{email,chat,paging,regulatory}/ | Optional connector overlays generated by devops/build/package-runtime-plugins.ps1 -Module notify -Profile <profile>. External delivery overlays contain Email, Slack, Teams, Webhook, PagerDuty, OpsGenie, Discord, and Telegram; the regulatory overlay contains CSAF, DORA, DoraInfoSharing, ENISA, and NCS. DORA runtime adapters ship generated manifest.json metadata because their source projects intentionally do not carry notify-plugin.json. |
notify-web.secret.example | Deterministic template for the Authority client secret. Replace the value before running the service. |
rules/airgap-ops.rule.json | Bootstrap rule subscribing to air-gap drift, bundle import, and portable export completion events. Update channel identifiers before import. |
templates/airgap-ops-email.template.json | Email template used by the bootstrap rule with remediation guidance, checksum context, and download locations. |
README.md | This guide, also embedded in the pack for quick operator reference. |
Usage
Populate secrets – copy
notify-web.secret.exampletonotify-web.secret, changeNOTIFY_WEB_CLIENT_SECRETto the value issued by Authority, and store it with restrictive permissions (for examplechmod 600).Drop configuration – place
notify.yamlin the location expected by the runtime (/app/etc/notify/notify.yamlfor the containers we ship). The file assumes PostgreSQL is reachable atHost=postgres;Database=stellaops;Username=stellaops;Password=airgap-passwordand Authority athttps://authority.airgap.local– adjust if your deployment uses different hostnames.Build and sign base plug-ins - run
devops/build/package-runtime-plugins.ps1 -Module notify -Profile base -SignNotifyBundles -NotifyCosignKeyPath <offline-cosign-key> -NotifyCosignPublicKeyPath <offline-cosign-pub>before creating the bootstrap pack. Without the detached Cosign signatures, production compose rejects the mounted bundle during readiness. The private key is an operator-supplied input; only the public key is copied into the mounted trust-root directory ascosign.pub. For local compose acceptance and air-gapped bootstrap proof, the same producer can generate therecommended,harness,email,chat,paging, andregulatoryprofiles with-UseOfflineDevSigner; never commit or distribute the generated private key.Import rule/template – with the Notify CLI or REST API, import
templates/airgap-ops-email.template.jsonfirst, thenrules/airgap-ops.rule.json. Update thechannelidentifiers inside the rule so they match your sealed SMTP relay (for exampleemail:airgap-ops).
The rule now also delivers portable export completion notices; ensure your downstream process watches for checksum and location details in the payload.Mount secrets/config – for Docker Compose use:
volumes: - ./bootstrap/notify/notify.yaml:/app/etc/notify/notify.yaml:ro env_file: - ./bootstrap/notify/notify-web.secretKubernetes Secret and pod mounting instructions are unsupported for Stella Ops deployments.
Verify plug-in readiness - set
notify:plugins:directoryto the mounted profile root such as/app/plugins/notify/base, keepnotify:plugins:ensureDirectoryExists=false, and callGET /readyzafter mounting the base bundle and trust root.GET /healthzonly proves the process is alive;/readyzfails with the missing base connector assembly names when the base plug-ins are absent or mounted at a path that does not matchnotify:plugins:directory. If a mounted connector is unsigned or the Cosign verifier cannot verify it against/app/trust-roots/plugins/notify,/readyzremains unready andGET /internal/plugins/statusreports the plugin asrejectedwith the admission reason.Verify sealed mode – with the configuration in place the Notifier resolves channels that point to local relays (SMTP, syslog, file sink). Any attempt to contact an external webhook is denied by
StellaOps.AirGap.Policywith remediation guidance.
How it is packaged
ops/offline-kit/build_offline_kit.py automatically copies the configuration and secret template into bootstrap/notify/ during Offline Kit creation. The same staging directory is what we sign and publish as the Bootstrap Pack, so the artefacts stay deterministic across releases.
Refer to etc/notify.airgap.yaml if you need to regenerate the pack or build a site-specific overlay from source control.
