286 lines
9.8 KiB
Markdown
286 lines
9.8 KiB
Markdown
# Phase 1 Plan
|
|
|
|
Goal: make log monitoring useful in production without enabling dangerous automation.
|
|
|
|
Phase 1 targets a production Portainer deployment of Log Guardian. Loki will likely run on a separate server and use an object-storage backend, probably MinIO backed by NAS storage. Log Guardian must remain safe-by-default: authenticated UI, real alert delivery, incident cooldowns, Loki validation tooling, dry-run remediation evidence, and local-only AI analysis.
|
|
|
|
## Decisions made
|
|
|
|
- Deployment target: production Portainer.
|
|
- Loki location: separate server from Log Guardian.
|
|
- Loki storage direction: object storage via MinIO, with MinIO data on NAS-backed storage.
|
|
- UI auth: single admin user using basic auth.
|
|
- Health endpoint: `/healthz` remains unauthenticated.
|
|
- First alert channel: self-hosted ntfy.
|
|
- Additional alert channel types should be supported/configurable from UI, not ntfy-only.
|
|
- Incident cooldown: per rule, default `1h`.
|
|
- AI: local-only Ollama is approved; no external/cloud AI providers.
|
|
- Remediation: Phase 1 should implement permission modeling and dry-run evidence, not dangerous automatic actions.
|
|
- Phase 1 completion requires Docker build and real alert delivery validation.
|
|
|
|
## 1. Production deployment architecture
|
|
|
|
### Log Guardian
|
|
|
|
Run Log Guardian as a Portainer-managed service/container.
|
|
|
|
Required mounts/config:
|
|
|
|
- Persistent local config/data file mount for `LOG_GUARDIAN_DATA_PATH`.
|
|
- Environment configuration for Loki endpoint, auth, alert defaults, and optional Ollama endpoint.
|
|
- Network path to the remote Loki server.
|
|
- Optional network path to self-hosted ntfy, Gotify, SMTP relay, webhook targets, and Ollama.
|
|
|
|
### Loki
|
|
|
|
Loki will run on a different server. Recommended production direction:
|
|
|
|
- Loki single-binary or simple scalable deployment depending on expected volume.
|
|
- Object storage backend: S3-compatible MinIO.
|
|
- MinIO data stored on NAS-backed storage.
|
|
- Retention configured explicitly.
|
|
- Promtail or Grafana Alloy deployed on every Docker/Portainer host that needs logs collected.
|
|
|
|
Recommended initial storage sizing:
|
|
|
|
- Start with 50 GB usable object storage for modest private infrastructure.
|
|
- Use 14-day retention initially.
|
|
- Monitor ingestion and object growth for 7 days before increasing retention.
|
|
- Increase to 100-250 GB+ if services are noisy or retention must be longer.
|
|
|
|
Planning assumptions to validate:
|
|
|
|
- NAS latency is acceptable for MinIO/Loki workload.
|
|
- MinIO has backups/snapshots appropriate for desired retention.
|
|
- Loki retention deletes old chunks/index data correctly.
|
|
- Log Guardian can reach Loki over a private network/VPN only.
|
|
|
|
## 2. Loki ingestion, label discovery, and validation
|
|
|
|
Because actual labels are not known yet, Phase 1 must include label discovery and query testing.
|
|
|
|
### Collection strategy
|
|
|
|
Use Promtail or Grafana Alloy on Docker/Portainer hosts. Target labels should include stable, low-cardinality dimensions such as:
|
|
|
|
- `host`
|
|
- `container`
|
|
- `service`
|
|
- `stack`
|
|
- `stream`
|
|
- `compose_project` or equivalent
|
|
- `compose_service` or equivalent
|
|
|
|
Avoid high-cardinality labels, including request IDs, user IDs, IP addresses, paths, error messages, or raw log content.
|
|
|
|
### Log Guardian Loki diagnostics
|
|
|
|
Add authenticated UI/API support for:
|
|
|
|
- Loki readiness/status check.
|
|
- List labels from `/loki/api/v1/labels`.
|
|
- List values for a selected label from `/loki/api/v1/label/{name}/values`.
|
|
- Test a LogQL query before saving a rule.
|
|
- Show count and sanitized sample lines for a test query.
|
|
|
|
Implementation notes:
|
|
|
|
- Limit query time range and result count.
|
|
- Do not log raw sample payloads by default.
|
|
- Redact obvious secrets from displayed query samples where practical.
|
|
- Handle Loki tenant ID and basic auth from existing Loki config.
|
|
|
|
## 3. UI authentication
|
|
|
|
Add single-admin basic auth.
|
|
|
|
Configuration:
|
|
|
|
- `LOG_GUARDIAN_AUTH_USERNAME`
|
|
- `LOG_GUARDIAN_AUTH_PASSWORD`
|
|
|
|
Rules:
|
|
|
|
- `/healthz` is unauthenticated.
|
|
- All other UI/API routes require auth.
|
|
- Use constant-time comparison for credentials.
|
|
- Do not log usernames/passwords or auth headers.
|
|
- If credentials are unset, fail closed in production or clearly mark auth as disabled only for local development. Prefer fail closed for Portainer deployment.
|
|
|
|
## 4. Alert channels
|
|
|
|
Alert channels must be configurable from the UI and stored in local configuration. Secrets need careful handling.
|
|
|
|
### Required first channel: self-hosted ntfy
|
|
|
|
Support fields:
|
|
|
|
- Name
|
|
- Enabled
|
|
- Server URL
|
|
- Topic
|
|
- Optional bearer token or token file reference
|
|
- Priority
|
|
- Tags
|
|
|
|
Validation:
|
|
|
|
- Send a test notification from the UI.
|
|
- Record delivery result without logging token values.
|
|
|
|
### Additional Phase 1 channel types
|
|
|
|
Implement the data model and UI so multiple channel types are possible. Preferred Phase 1 support order:
|
|
|
|
1. `ntfy` - implement real delivery first.
|
|
2. `gotify` - real delivery if time allows; token-based API is straightforward.
|
|
3. `generic_webhook` - useful but must avoid leaking secrets; support explicit headers carefully.
|
|
4. `smtp` - useful, but can be deferred if it complicates TLS/auth validation.
|
|
|
|
Minimum acceptable Phase 1 scope:
|
|
|
|
- UI can create/edit/delete alert channels.
|
|
- UI can attach channels to rules.
|
|
- ntfy real delivery works.
|
|
- Other channel types may be present as disabled/scaffolded if not implemented, but the UI should clearly show unsupported status.
|
|
|
|
Secret handling:
|
|
|
|
- Do not print secrets in logs.
|
|
- Do not render stored secret values back into forms; show only `configured`/`not configured`.
|
|
- Prefer environment variable or mounted file references for sensitive channel tokens when possible.
|
|
- If secrets are stored in local JSON, the file must be written with `0600` permissions and documented as sensitive.
|
|
|
|
## 5. Rule evaluation and incident cooldown
|
|
|
|
Add per-rule cooldown.
|
|
|
|
Rule field:
|
|
|
|
```json
|
|
"cooldown": "1h"
|
|
```
|
|
|
|
Default behavior:
|
|
|
|
- If unset, cooldown is `1h`.
|
|
- If a rule fires outside cooldown:
|
|
- create incident;
|
|
- send configured alert channels;
|
|
- record dry-run remediation evidence if actions are configured.
|
|
- If a rule fires during cooldown:
|
|
- update rule last checked/matched/count fields;
|
|
- do not create a duplicate incident;
|
|
- do not send another alert;
|
|
- increment or record suppressed count if implemented.
|
|
|
|
## 6. Remediation/action model
|
|
|
|
Phase 1 should not execute destructive remediation. Implement guardrails and dry-run evidence.
|
|
|
|
Recommended Phase 1 action types:
|
|
|
|
- `generic_webhook`: dry-run by default; real execution can be deferred or restricted.
|
|
- `portainer_restart`: dry-run only in Phase 1.
|
|
- `allowlisted_command`: dry-run only in Phase 1; command IDs only, never arbitrary shell from UI/AI.
|
|
- `record_recommendation`: safe action that stores an advisory recommendation on the incident.
|
|
|
|
Guardrails:
|
|
|
|
- Global dry-run defaults true.
|
|
- Per-rule action must be enabled.
|
|
- Per-action dry-run should be explicit or inherited from global dry-run.
|
|
- AI may recommend actions but cannot execute them.
|
|
- No arbitrary command execution.
|
|
- No Portainer write API calls in Phase 1 unless separately approved.
|
|
|
|
Validation evidence:
|
|
|
|
- At least one rule with a configured dry-run action.
|
|
- Incident shows what would have happened.
|
|
- Logs do not expose secrets or raw full log payloads.
|
|
|
|
## 7. Local-only AI analysis
|
|
|
|
Local-only Ollama is approved for Phase 1. External/cloud AI providers are not approved.
|
|
|
|
Configuration:
|
|
|
|
- `LOG_GUARDIAN_ANALYSIS_PROVIDER=none|ollama`
|
|
- `LOG_GUARDIAN_OLLAMA_URL=http://ollama:11434`
|
|
- `LOG_GUARDIAN_OLLAMA_MODEL=<model>`
|
|
|
|
Default:
|
|
|
|
- `LOG_GUARDIAN_ANALYSIS_PROVIDER=none`
|
|
|
|
Rules:
|
|
|
|
- AI analysis remains opt-in per rule.
|
|
- AI findings are advisory only.
|
|
- Limit number of log lines sent to Ollama.
|
|
- Redact obvious secrets before prompt construction.
|
|
- Do not log prompts or raw log payloads by default.
|
|
- Store only concise summaries/recommendations in incidents.
|
|
|
|
Prompt/redaction design must be documented before enabling Ollama in production.
|
|
|
|
## 8. UI scope
|
|
|
|
Add UI support for:
|
|
|
|
- Login-protected dashboard.
|
|
- Rule create/edit with cooldown and alert channel selection.
|
|
- Alert channel create/edit/test.
|
|
- Loki status/label discovery/query test.
|
|
- Incident list showing alert delivery state and remediation dry-run evidence where available.
|
|
|
|
Keep the UI served by Go. Do not add a server-side JavaScript runtime.
|
|
|
|
## 9. Tests and validation
|
|
|
|
Required implementation tests:
|
|
|
|
- Auth middleware unit tests.
|
|
- Store tests for alert channels, cooldown fields, and secret-preserving updates.
|
|
- Loki client tests using `httptest` fixtures for labels, label values, and query range.
|
|
- Alert dispatcher tests for ntfy using `httptest`.
|
|
- Rule engine tests for cooldown suppression.
|
|
- Remediation dry-run tests.
|
|
- Optional Ollama provider tests using `httptest` only; no live AI dependency in unit tests.
|
|
|
|
Required validation before Phase 1 completion:
|
|
|
|
```sh
|
|
gofmt -w cmd internal
|
|
go test ./...
|
|
make validate-structure
|
|
make docker-build
|
|
```
|
|
|
|
Additional required evidence:
|
|
|
|
- Loki connectivity/query validation against the remote Loki server.
|
|
- Label discovery output documented without secrets.
|
|
- Self-hosted ntfy test alert received.
|
|
- A rule-generated ntfy alert received.
|
|
- Remediation dry-run evidence captured.
|
|
- Security/privacy review covering logs, prompts, secrets, alert tokens, and action permissions.
|
|
|
|
## 10. Required Phase 1 artifacts
|
|
|
|
Create/update these before declaring Phase 1 complete:
|
|
|
|
- `project-docs/status/phase-1-summary.md`
|
|
- `project-docs/status/phase-1-test-results.md`
|
|
- `project-docs/status/phase-1-open-issues.md`
|
|
|
|
## 11. Open planning items
|
|
|
|
- Final Loki topology: single-binary vs simple scalable.
|
|
- Final MinIO/NAS capacity and retention target after observing ingestion.
|
|
- Whether Gotify, generic webhook, or SMTP are implemented fully in Phase 1 or scaffolded after ntfy.
|
|
- Whether alert channel secrets are stored directly in local JSON or referenced via env/file paths.
|
|
- Exact Ollama model to use once Ollama is stable.
|
|
- Whether Log Guardian reaches Loki/ntfy/Ollama over LAN, VPN, or Docker overlay network.
|