From f060c09668d51c5c65a5c34e0c204ddb31c56549 Mon Sep 17 00:00:00 2001 From: Ivan Godwin Date: Mon, 29 Jun 2026 14:19:56 -0700 Subject: [PATCH] docs(notifier): refresh API reference and fix env/registry examples Document the previously-missing endpoints (GET /api/v1/notifiers and the /api/v1/admin/keys management routes), mark the gRPC API and API-key auth as implemented, and add an Authentication section plus links to the docs guides. Fix incorrect examples: the env prefix is NOTIFIER_ (so NOTIFIER_SERVER_MODE, not SERVER_MODE) and the multi-arch build var is REGISTRY (not DOCKER_REGISTRY). Co-Authored-By: Claude Opus 4.8 --- README.md | 122 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 100 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index dc4c74d..8b5ef69 100644 --- a/README.md +++ b/README.md @@ -56,9 +56,9 @@ Server starts with: **Run in different modes:** ```bash -./bin/server # Both REST and gRPC (default) -SERVER_MODE=rest ./bin/server # REST only -SERVER_MODE=grpc ./bin/server # gRPC only +./bin/server # Both REST and gRPC (default) +NOTIFIER_SERVER_MODE=rest ./bin/server # REST only +NOTIFIER_SERVER_MODE=grpc ./bin/server # gRPC only ``` ### 2. Send Your First Notification @@ -284,15 +284,32 @@ Format: `NOTIFIER_
_` (use `_` for nested keys) | Method | Endpoint | Description | |--------|----------|-------------| -| `GET` | `/health` | Health check | -| `POST` | `/api/v1/notifications` | Send single notification | -| `POST` | `/api/v1/notifications/batch` | Send multiple notifications | +| `GET` | `/health` | Health check (always unauthenticated) | +| `POST` | `/api/v1/notifications` | Send single notification (returns `202 Accepted`) | +| `POST` | `/api/v1/notifications/batch` | Send multiple notifications (returns `202 Accepted`) | | `GET` | `/api/v1/notifications` | List notifications (with filters) | | `GET` | `/api/v1/notifications/{id}` | Get notification by ID | | `DELETE` | `/api/v1/notifications/{id}` | Cancel pending notification | | `POST` | `/api/v1/notifications/{id}/retry` | Retry failed notification | +| `GET` | `/api/v1/notifiers` | List configured notifier types and accounts | | `GET` | `/api/v1/stats` | Get service statistics | +When `auth.enabled` is set, all `/api/v1` routes require an API key (see +[Authentication](#authentication)); `/health` is always open. + +#### Admin — API Key Management + +Registered only when authentication **and** a key store are configured. See +[docs/KEY_MANAGEMENT.md](docs/KEY_MANAGEMENT.md) for the full workflow. + +| Method | Endpoint | Description | +|--------|----------|-------------| +| `POST` | `/api/v1/admin/keys` | Create an API key | +| `GET` | `/api/v1/admin/keys` | List API keys | +| `DELETE` | `/api/v1/admin/keys/{name}` | Revoke an API key | +| `POST` | `/api/v1/admin/keys/{name}/rotate` | Rotate an API key | +| `GET` | `/api/v1/admin/keys/{name}/audit` | Get a key's audit log | + ### Request Format ```json @@ -352,9 +369,30 @@ curl "http://localhost:8080/api/v1/notifications?type=email&status=sent&limit=10 curl "http://localhost:8080/api/v1/notifications?status=failed&limit=20" ``` +Supported query parameters: `type` and `status` (both repeatable), +`recipient` (repeatable), `limit`, and `offset`. + ## gRPC API -The gRPC service mirrors the REST API with full feature parity. See [api/grpc/notifier.proto](api/grpc/notifier.proto) for definitions. +The gRPC service mirrors the REST API with full feature parity. The service is +`notifier.v1.NotifierService` (RPCs: `SendNotification`, `SendBatchNotifications`, +`GetNotification`, `ListNotifications`, `CancelNotification`, `RetryNotification`, +`GetStats`, `GetNotifiers`, `HealthCheck`). See +[api/grpc/notifier.proto](api/grpc/notifier.proto) for the full definitions. + +Server [reflection](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md) +is enabled, so tools like `grpcurl` work without a local copy of the proto: + +```bash +# List methods +grpcurl -plaintext localhost:50051 list notifier.v1.NotifierService + +# Call GetNotifiers +grpcurl -plaintext localhost:50051 notifier.v1.NotifierService/GetNotifiers +``` + +When `auth.enabled` is set, pass the API key as metadata +(`-H "authorization: Bearer "`); see [docs/AUTH.md](docs/AUTH.md). **Generate Go code:** ```bash @@ -363,7 +401,33 @@ make proto-gen protoc --go_out=. --go-grpc_out=. api/grpc/notifier.proto ``` -**Note:** gRPC server is running but handler implementation is pending. Protobuf definitions are complete. +## Authentication + +Authentication is **disabled by default** (`auth.enabled: false`). When enabled, +the service uses API keys with optional role-based access control (RBAC) over +both the REST and gRPC APIs: + +```yaml +auth: + enabled: true + default_rate_limit: 100 # requests per minute per key + bootstrap: + enabled: true # mint an admin key on first start + print_to_stdout: false + kubernetes_secret_name: notifier-admin-key + kubernetes_secret_key: admin-key +``` + +- **REST:** send `Authorization: Bearer ` (or `X-API-Key: `). +- **gRPC:** send an `authorization: Bearer ` metadata header. +- Keys can be managed at runtime via the [admin endpoints](#admin--api-key-management). +- An admin key can be bootstrapped to stdout, a file, or a Kubernetes Secret. + +See the guides for details: +- [docs/AUTH_QUICK_START.md](docs/AUTH_QUICK_START.md) — 5-minute setup +- [docs/AUTH.md](docs/AUTH.md) — full authentication & client examples +- [docs/KEY_MANAGEMENT.md](docs/KEY_MANAGEMENT.md) — key lifecycle (create/rotate/revoke/audit) +- [docs/RBAC.md](docs/RBAC.md) — role-based access to notifier accounts ## Deployment @@ -402,10 +466,10 @@ docker run -d \ docker run -d -p 8080:8080 -p 50051:50051 notifier:latest # REST only -docker run -d -p 8080:8080 -e SERVER_MODE=rest notifier:latest +docker run -d -p 8080:8080 -e NOTIFIER_SERVER_MODE=rest notifier:latest # gRPC only -docker run -d -p 50051:50051 -e SERVER_MODE=grpc notifier:latest +docker run -d -p 50051:50051 -e NOTIFIER_SERVER_MODE=grpc notifier:latest ``` **Docker Compose:** @@ -497,17 +561,20 @@ notifier/ │ │ └── notifier.proto # gRPC service definition │ └── rest/ │ ├── handlers.go # HTTP handlers +│ ├── keys.go # API key management handlers │ ├── router.go # Route configuration │ └── types.go # Request/response types ├── cmd/ │ └── server/main.go # Unified server (configurable mode) ├── internal/ +│ ├── auth/ # API key auth, RBAC, key store, bootstrap │ ├── config/ │ │ └── config.go # Configuration management │ ├── domain/ │ │ ├── notification.go # Core types │ │ ├── notifier.go # Notifier interface │ │ └── queue.go # Queue interface +│ ├── logging/ # Structured logger │ ├── notifier/ │ │ ├── notifier.go # Factory & base │ │ ├── smtp.go # Email notifier @@ -525,8 +592,7 @@ notifier/ │ ├── ingress.yaml │ ├── hpa.yaml │ └── kustomization.yaml -├── docs/ -│ └── NTFY_GUIDE.md # Ntfy integration guide +├── docs/ # Guides & references (see docs/INDEX.md) ├── config.yaml # Default configuration ├── docker-compose.yaml ├── Dockerfile @@ -553,7 +619,7 @@ make lint # Run golangci-lint make check # Run fmt-check + vet + mod verify make qa # Run all quality checks make proto-gen # Generate protobuf code -make docker-build # Build Docker image (multi-arch + push when DOCKER_REGISTRY is set) +make docker-build # Build Docker image (multi-arch + push when REGISTRY is set) make clean # Clean build artifacts make help # Show all available targets ``` @@ -585,9 +651,17 @@ See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed guide. - [QUICKSTART.md](QUICKSTART.md) - Quick start guide with examples - [ARCHITECTURE.md](ARCHITECTURE.md) - Architecture and design details -- [docs/NTFY_GUIDE.md](docs/NTFY_GUIDE.md) - Ntfy integration guide +- [docs/INDEX.md](docs/INDEX.md) - Full documentation index - [api/grpc/notifier.proto](api/grpc/notifier.proto) - gRPC API definition +**Guides:** +- [docs/AUTH.md](docs/AUTH.md) / [docs/AUTH_QUICK_START.md](docs/AUTH_QUICK_START.md) - Authentication & RBAC +- [docs/KEY_MANAGEMENT.md](docs/KEY_MANAGEMENT.md) - API key lifecycle +- [docs/EMAIL_GUIDE.md](docs/EMAIL_GUIDE.md) - Email/SMTP setup +- [docs/NTFY_GUIDE.md](docs/NTFY_GUIDE.md) - Ntfy integration +- [docs/TLS_SECURITY.md](docs/TLS_SECURITY.md) - TLS configuration +- [docs/CORS_KUBERNETES_GUIDE.md](docs/CORS_KUBERNETES_GUIDE.md) - CORS in Kubernetes + ## Testing ```bash @@ -601,7 +675,9 @@ go test -cover ./... go test ./internal/notifier/... ``` -**Current Status:** Core implementation complete, tests pending. +**Current Status:** Core implementation complete with unit tests across the +config, service, notifier, and auth packages. Run `make test` (race detector +enabled) or `make test-coverage` for an HTML report. ## Monitoring & Operations @@ -659,27 +735,29 @@ The server handles `SIGINT` and `SIGTERM` gracefully: ### Completed ✅ - [x] Core notification system - [x] REST API (fully functional) -- [x] gRPC API (protobuf defined) +- [x] gRPC API (fully functional, with reflection) - [x] Local queue with workers - [x] Multiple notifiers (SMTP, Slack, Ntfy, Stdout) - [x] Priority and retry logic - [x] Batch operations +- [x] API key authentication with RBAC and runtime key management +- [x] CORS support +- [x] Notification retention/cleanup - [x] Docker support - [x] Kubernetes manifests with HPA - [x] Health checks and stats - [x] Configuration management +- [x] Unit test suite (race detector) ### Planned 🚧 -- [ ] gRPC handler implementation - [ ] Kafka queue adapter -- [ ] Database persistence (PostgreSQL) +- [ ] Database-backed notification persistence (PostgreSQL) - [ ] Notification templates - [ ] Webhook callbacks -- [ ] Authentication/Authorization (API keys, OAuth) -- [ ] Rate limiting (per client, per notifier) -- [ ] Prometheus metrics +- [ ] OAuth authentication +- [ ] Per-notifier rate limiting +- [ ] Prometheus metrics endpoint - [ ] OpenTelemetry tracing -- [ ] Comprehensive test suite - [ ] Circuit breakers for notifiers - [ ] Dead letter queue - [ ] Admin dashboard