ward-kdl: SigNoz ops guardfile (spec dialect, CRU-no-D, static API key) #241

Closed
opened 2026-06-24 04:07:00 +00:00 by coilyco-ops · 6 comments
Member

Goal

Add a ward-kdl.signoz.guardfile.kdl (plus its docs/ward-kdl.signoz.guardfile.md) so warded agents get a deny-by-default SigNoz ops surface, mirroring the existing spec-dialect guardfiles (forgejo, tailscale, open-webui). SigNoz is an HTTP API, so this is the spec dialect (spec / base-url / auth / can <verb> <resource>), not the exec dialect.

Where it lives

  • Guardfile: cmd/ward-kdl/ward-kdl.signoz.guardfile.kdl
  • Doc: docs/ward-kdl.signoz.guardfile.md (every guardfile has a sibling doc; link it from the guardfile header comment)
  • Vendored spec: cmd/ward-kdl/signoz.openapi.* (+ .lock.json if the toolchain emits one, like forgejo/tailscale/open-webui)
  • Register the new ward-kdl ops signoz surface wherever the other ops guardfiles are wired in (follow how forgejo is mounted).

SigNoz facts (from coilyco-bridge/deploy)

  • Runs on ser8: UI/API at http://ser8:30808 (NodePort). A tailnet service also exists in infrastructure/deploy/observability/signoz-tailscale-service.yml - prefer a stable tailnet base-url over the NodePort if one is published; resolve any opaque tailnet FQDN from SSM at runtime, never hardcode.
  • Charts: signoz/signoz 0.128.0, signoz/k8s-infra 0.16.0. Org coilyco, admin coilysiren@gmail.com.
  • Today deploy/services/signoz-pipelines/apply.py drives the API: it logs in via POST /api/v2/sessions/email_password (email + password + orgID from SSM /coilysiren/signoz-ser8/{admin-password,org-id}) and uses the returned session token. Endpoints in use: GET /api/v1/logs/pipelines/latest, POST /api/v1/logs/pipelines. Queries use POST /api/v3/query_range.

Decisions (from Kai)

  1. Auth: mint a static SigNoz API key. Do NOT replicate the email/password session exchange. Create a SigNoz PAT/API key (SigNoz settings → API keys), stash it in SSM (suggest /coilysiren/signoz-ser8/api-token, SecureString), and use a clean static auth header-token { header Authorization; ... value ssm "/coilysiren/signoz-ser8/api-token" } exactly like the forgejo guardfile. Confirm SigNoz's expected header/prefix for API keys (SigNoz typically uses SIGNOZ-API-KEY: <key> rather than Authorization: Bearer - verify against the running 0.128.0 instance and model the guardfile to match). If the key doesn't exist yet, mint it and add it to SSM + update agentic-os-kai/SSM.md in the same change; if minting must be done by a human, file a follow-up and leave a FILL_ME_IN note rather than blocking.

  2. Surface: CRU, no D (deny all deletion). Expose create / read / update across the SigNoz surfaces we use - queries (query_range), log pipelines (get latest + apply), dashboards (get/list/create/update), alert rules (get/list/create/update). Deny every delete/destroy verb with an explicit never ... { message ... } (consistent with the kubectl/ollama deny-destructive precedent and the forgejo never delete pattern). No archive/disable toggles that are effectively destructive either - if in doubt, deny and note it.

  3. Spec: research upstream first, fall back to hand-authored. SigNoz does not publish a clean public OpenAPI spec the way Forgejo/Tailscale do, but some versions ship a Swagger UI. First check whether the running SigNoz 0.128.0 exposes an OpenAPI/Swagger doc that can be vendored (like forgejo.swagger.lock.json / tailscale.openapi.yaml). If a usable spec exists, vendor it and lock it. If not, hand-author a minimal OpenAPI spec covering only the endpoints the guardfile grants (query_range, logs/pipelines, dashboards, alerts) and vendor that. Document which path was taken in the guardfile doc.

Acceptance

  • ward-kdl.signoz.guardfile.kdl parses and ward ops signoz describe (or the repo's equivalent) prints the mounted surface.
  • CRU verbs present; every delete-class verb is never-denied with a message.
  • Auth is a single static value ssm header-token; no email/password exchange in the guardfile.
  • Sibling docs/ward-kdl.signoz.guardfile.md written and cross-linked, matching the depth of the forgejo/kubectl docs (auth provenance, scope rationale, what's intentionally denied).
  • Run the repo's guardfile validators / pre-commit run --all-files; land per the repo's normal flow.
  • Keep everything public-safe: no opaque ids, tokens, or tailnet FQDNs in tracked files - SSM paths and <PLACEHOLDER> only.

Reference guardfiles to mirror

cmd/ward-kdl/ward-kdl.forgejo.guardfile.kdl (auth + can/never + actions), ward-kdl.tailscale.guardfile.kdl and ward-kdl.open-webui.guardfile.kdl (vendored-spec API dialect), ward-kdl.kubectl.guardfile.kdl (deny-destructive rationale).

Filed from coilyco-bridge/deploy after a scoping pass; SigNoz deploy surface lives in coilyco-bridge/deploy/services/{ser8-observability,signoz-pipelines}.

## Goal Add a `ward-kdl.signoz.guardfile.kdl` (plus its `docs/ward-kdl.signoz.guardfile.md`) so warded agents get a deny-by-default SigNoz ops surface, mirroring the existing spec-dialect guardfiles (`forgejo`, `tailscale`, `open-webui`). SigNoz is an HTTP API, so this is the **spec dialect** (`spec` / `base-url` / `auth` / `can <verb> <resource>`), not the exec dialect. ## Where it lives - Guardfile: `cmd/ward-kdl/ward-kdl.signoz.guardfile.kdl` - Doc: `docs/ward-kdl.signoz.guardfile.md` (every guardfile has a sibling doc; link it from the guardfile header comment) - Vendored spec: `cmd/ward-kdl/signoz.openapi.*` (+ `.lock.json` if the toolchain emits one, like forgejo/tailscale/open-webui) - Register the new `ward-kdl ops signoz` surface wherever the other ops guardfiles are wired in (follow how `forgejo` is mounted). ## SigNoz facts (from coilyco-bridge/deploy) - Runs on ser8: UI/API at `http://ser8:30808` (NodePort). A tailnet service also exists in `infrastructure/deploy/observability/signoz-tailscale-service.yml` - prefer a stable tailnet base-url over the NodePort if one is published; resolve any opaque tailnet FQDN from SSM at runtime, never hardcode. - Charts: `signoz/signoz` 0.128.0, `signoz/k8s-infra` 0.16.0. Org `coilyco`, admin `coilysiren@gmail.com`. - Today `deploy/services/signoz-pipelines/apply.py` drives the API: it logs in via `POST /api/v2/sessions/email_password` (email + password + orgID from SSM `/coilysiren/signoz-ser8/{admin-password,org-id}`) and uses the returned **session token**. Endpoints in use: `GET /api/v1/logs/pipelines/latest`, `POST /api/v1/logs/pipelines`. Queries use `POST /api/v3/query_range`. ## Decisions (from Kai) 1. **Auth: mint a static SigNoz API key.** Do NOT replicate the email/password session exchange. Create a SigNoz PAT/API key (SigNoz settings → API keys), stash it in SSM (suggest `/coilysiren/signoz-ser8/api-token`, SecureString), and use a clean static `auth header-token { header Authorization; ... value ssm "/coilysiren/signoz-ser8/api-token" }` exactly like the forgejo guardfile. Confirm SigNoz's expected header/prefix for API keys (SigNoz typically uses `SIGNOZ-API-KEY: <key>` rather than `Authorization: Bearer` - verify against the running 0.128.0 instance and model the guardfile to match). If the key doesn't exist yet, mint it and add it to SSM + update `agentic-os-kai/SSM.md` in the same change; if minting must be done by a human, file a follow-up and leave a `FILL_ME_IN` note rather than blocking. 2. **Surface: CRU, no D (deny all deletion).** Expose create / read / update across the SigNoz surfaces we use - queries (`query_range`), log pipelines (get latest + apply), dashboards (get/list/create/update), alert rules (get/list/create/update). **Deny every delete/destroy verb** with an explicit `never ... { message ... }` (consistent with the kubectl/ollama deny-destructive precedent and the forgejo `never delete` pattern). No archive/disable toggles that are effectively destructive either - if in doubt, deny and note it. 3. **Spec: research upstream first, fall back to hand-authored.** SigNoz does not publish a clean public OpenAPI spec the way Forgejo/Tailscale do, but some versions ship a Swagger UI. First check whether the running SigNoz 0.128.0 exposes an OpenAPI/Swagger doc that can be vendored (like `forgejo.swagger.lock.json` / `tailscale.openapi.yaml`). If a usable spec exists, vendor it and lock it. If not, hand-author a **minimal** OpenAPI spec covering only the endpoints the guardfile grants (query_range, logs/pipelines, dashboards, alerts) and vendor that. Document which path was taken in the guardfile doc. ## Acceptance - `ward-kdl.signoz.guardfile.kdl` parses and `ward ops signoz describe` (or the repo's equivalent) prints the mounted surface. - CRU verbs present; every delete-class verb is `never`-denied with a message. - Auth is a single static `value ssm` header-token; no email/password exchange in the guardfile. - Sibling `docs/ward-kdl.signoz.guardfile.md` written and cross-linked, matching the depth of the forgejo/kubectl docs (auth provenance, scope rationale, what's intentionally denied). - Run the repo's guardfile validators / `pre-commit run --all-files`; land per the repo's normal flow. - Keep everything public-safe: no opaque ids, tokens, or tailnet FQDNs in tracked files - SSM paths and `<PLACEHOLDER>` only. ## Reference guardfiles to mirror `cmd/ward-kdl/ward-kdl.forgejo.guardfile.kdl` (auth + can/never + actions), `ward-kdl.tailscale.guardfile.kdl` and `ward-kdl.open-webui.guardfile.kdl` (vendored-spec API dialect), `ward-kdl.kubectl.guardfile.kdl` (deny-destructive rationale). Filed from coilyco-bridge/deploy after a scoping pass; SigNoz deploy surface lives in `coilyco-bridge/deploy/services/{ser8-observability,signoz-pipelines}`.
Author
Member

🔒 Reserved by ward agent claude — container ward-ward-issue-241-claude-cd4eb8ad on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T04:07:10Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent claude` — container `ward-ward-issue-241-claude-cd4eb8ad` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T04:07:10Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-241-claude-64ecf0b3 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T06:40:28Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-241-claude-64ecf0b3` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T06:40:28Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-241-claude-75f789f7 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T07:25:44Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-241-claude-75f789f7` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T07:25:44Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-241-claude-faab236c on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T07:28:40Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-241-claude-faab236c` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T07:28:40Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-241-claude-11d4606b on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T07:58:50Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-241-claude-11d4606b` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T07:58:50Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-241-claude-6e0afc52 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T08:20:23Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-241-claude-6e0afc52` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T08:20:23Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/ward#241
No description provided.