grafana-cloud-proxy is a lightweight HTTP proxy that forwards telemetry traffic to Grafana Cloud and can automatically pause forwarding when a configured billing alert is firing.
This proxy implementation was built following Grafana's frontend observability data-proxy guidance:
For broader product and platform concepts, use the main Grafana Cloud documentation as reference:
It uses a hybrid control model:
- Grafana webhook updates for near real-time block/unblock state changes
- Periodic Grafana polling for reconciliation and startup initialization
- Proxies incoming HTTP telemetry requests to
TARGET_URL - Applies CORS rules for DAppNode origins
- Exposes
GET /health - Exposes
POST /webhook/grafanafor Grafana alert notifications - Blocks forwarding with HTTP
503when the configured cost alert is firing
Hexagonal architecture with ports and adapters:
internal/application/domain: domain entitiesinternal/application/ports: app interfacesinternal/application/services: core business logic (poller + proxy decision)internal/adapters/grafana: Grafana API clientinternal/adapters/forwarder: outbound HTTP forwarding adapterinternal/adapters/api: inbound HTTP handlers and middlewarecmd/main.go: dependency wiring and app bootstrap
The app is configured through environment variables.
Copy example values first:
cp .env.example .envRequired variables:
TARGET_URL: upstream telemetry endpoint
Recommended variables:
GRAFANA_API_URL: Grafana stack URL (example:https://your-stack.grafana.net)GRAFANA_API_KEY: Grafana API key used for polling active alertsALERT_NAME: substring match used to identify the cost-control alertPOLL_INTERVAL: reconciliation polling interval (default recommendation:5m)GRAFANA_WEBHOOK_SECRET: shared secret for webhook authenticationPORT: HTTP server port (default8080)
docker compose up --buildThe main compose file loads runtime configuration from .env.
Install air once:
go install github.com/air-verse/air@latestRun with hot reload:
air -c .air.tomlOn every save in cmd or internal, the app rebuilds and restarts automatically.
docker compose -f docker-compose.dev.yml up --buildThis mode mounts the source code into the container and runs air inside it.
Configure a webhook contact point that targets:
POST http://<host>:<port>/webhook/grafana
Authentication:
- Set header
X-Webhook-Secret: <GRAFANA_WEBHOOK_SECRET> - Or use
Authorization: Bearer <GRAFANA_WEBHOOK_SECRET>
Expected payload shape includes an alerts array compatible with Grafana Alertmanager webhook payloads.
GET /health- returns app health and current blocked state
POST /webhook/grafana- accepts webhook payload and updates blocked state immediately
POST /(and other forwarded methods)- proxy endpoint for telemetry forwarding
Run unit tests:
go test ./...Run Grafana integration tests:
GRAFANA_API_URL=https://your-stack.grafana.net \
GRAFANA_API_KEY=glsa_your_key \
go test -tags=integration ./internal/adapters/grafana -v -count=1- Do not commit real API keys in source control
- Keep
.envprivate (already gitignored) - Rotate exposed credentials immediately if they were ever shared
- Use a strong webhook secret in production