This repository runs a semi-real Sauron environment outside the Sauron source tree.
It consumes /Users/victorbona/Daedalus/Sauron as source, builds the Grafana plugin and runtime image, copies only the built plugin artifact into this sandbox, and starts:
- Grafana
12.4.0 - Sauron app plugin plus nested panels
- Sauron runtime container
- Postgres runtime persistence
- Prometheus demo datasource
- Loki logs data source
- Tempo traces data source
- Kind Kubernetes cluster with demo workloads and read-only Sauron RBAC
- Docker running
- Node/npm, Go, and Mage prerequisites already working in the Sauron repo
kindkubectljqrsync
cd /Users/victorbona/Daedalus/sauron-sandbox
cp .env.example .env
make upOpen:
http://localhost:3000/a/guaracloud-sauron-app
Useful URLs:
Grafana: http://localhost:3000
Sauron app: http://localhost:3000/a/guaracloud-sauron-app
Sauron panels dashboard: http://localhost:3000/d/sauron-sandbox/sauron-sandbox
Sauron runtime health: http://localhost:8080/health
Prometheus: http://localhost:9090
Loki: http://localhost:3100
Tempo: http://localhost:3200
Default local credentials:
admin / admin
- Builds Sauron frontend with the repo webpack config.
- Builds Sauron backend with Mage.
- Builds the
sauron-runtime:localDocker image. - Copies Sauron
dist/into.artifacts/grafana-plugins/guaracloud-sauron-app. - Creates or updates the
sauron-sandboxKind cluster. - Applies demo Kubernetes workloads and read-only Sauron RBAC.
- Starts Docker Compose.
- Provisions Grafana plugin settings through the Grafana API.
make smoke-alertsIt validates synthetic alerting behavior via the runtime webhook path:
- opted-in Grafana alert creates one investigation
- repeated firing with the same fingerprint reuses the same investigation
- resolved status appends context to the existing investigation
- non-opted alert is ignored
make smokeThe smoke test calls Sauron through the real Grafana app plugin resource path:
/api/plugins/guaracloud-sauron-app/resources/api/v1/*
It verifies:
- Grafana is reachable.
- Sauron plugin config is complete.
- Grafana backend can reach the runtime.
- Provider config is accepted.
- Investigations can be created.
- Messages can be appended.
- Approval-gated safe writes require approval and execute once approved.
- Audit events are produced.
- Kubernetes status and read-only tool contracts are reachable.
After make up, use Grafana:
- Open
http://localhost:3000/a/guaracloud-sauron-app. - Confirm
Overviewloads and reports configured runtime/model settings. - Open
Investigations. - Create a new investigation.
- Send a message.
- Open
Approvals. - Use
make smokeor the runtime API to create a pending safe write, then approve/deny it in the UI. - Open
http://localhost:3000/d/sauron-sandbox/sauron-sandboxand confirm the nested Sauron panels render.
The Kind cluster contains namespaces and demo workloads:
kubectl --context kind-sauron-sandbox get pods -A
kubectl --context kind-sauron-sandbox get deploy -n tenant-alphaValidate the Sauron runtime RBAC contract:
make rbacExpected:
- can
get/list/watchpods, events, nodes, deployments, replicasets - cannot read secrets
- cannot delete workloads
- cannot use
pods/exec
The current Sauron runtime Kubernetes endpoint is intentionally read-only and contract-level. The sandbox still creates a real cluster and verifies the RBAC that future live Kubernetes execution must use.
make build
docker compose restart grafana sauron-runtime
make configureGrafana must be restarted after plugin manifest changes.
make resetThis removes Docker Compose volumes and deletes the Kind cluster unless KEEP_KIND=1 is set.
KEEP_KIND=1 make resetCopy .env.example to .env and edit:
SAURON_REPO=/Users/victorbona/Daedalus/Sauron
SAURON_RUNTIME_SECRET=dev-runtime-secret
GRAFANA_URL=http://localhost:3000
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=adminModel provider configuration is real-provider only. Set it in the Grafana Sauron app configuration page, or provide it
through sandbox environment variables before running make up:
SAURON_MODEL_BASE_URL=https://api.openai.com/v1
SAURON_MODEL_API_KEY=...
SAURON_MODEL_NAME=gpt-5.1
SAURON_MODEL_API_MODE=responses