diff --git a/README.md b/README.md index 24d2c1e..f06423d 100644 --- a/README.md +++ b/README.md @@ -256,6 +256,139 @@ nk -gen user -pubout Configure appropriate publish/subscribe permissions in your NATS server for each credential type. +## NATS Subject Structure + +The deployment system uses the following NATS subject hierarchy: + +### Deploy Subjects + +| Subject Pattern | Purpose | +|-----------------|---------| +| `deploy..` | Deploy to a specific host | +| `deploy..all` | Deploy to all hosts in a tier | +| `deploy..role.` | Deploy to hosts with a specific role in a tier | + +**Tier values:** `test`, `prod` + +**Examples:** +- `deploy.test.myhost` - Deploy to myhost in test tier +- `deploy.prod.all` - Deploy to all production hosts +- `deploy.prod.role.dns` - Deploy to all DNS servers in production + +### Response Subjects + +| Subject Pattern | Purpose | +|-----------------|---------| +| `deploy.responses.` | Unique reply subject for each deployment request | + +Deployers create a unique response subject for each request and include it in the `reply_to` field. Listeners publish status updates to this subject. + +### Discovery Subject + +| Subject Pattern | Purpose | +|-----------------|---------| +| `deploy.discover` | Host discovery requests and responses | + +Used by the `list_hosts` MCP tool and for discovering available deployment targets. + +## Example NATS Configuration + +Below is an example NATS server configuration implementing tiered authentication. This setup provides: + +- **Listeners** - Each host has credentials to subscribe to its own subjects and publish responses +- **Test deployer** - Can deploy to test tier only (suitable for MCP without admin access) +- **Admin deployer** - Can deploy to all tiers (for CLI or MCP with admin access) + +```conf +authorization { + users = [ + # Listener for a test-tier host + { + nkey: "UTEST_HOST1_PUBLIC_KEY_HERE" + permissions: { + subscribe: [ + "deploy.test.testhost1" + "deploy.test.all" + "deploy.test.role.>" + "deploy.discover" + ] + publish: [ + "deploy.responses.>" + "deploy.discover" + ] + } + } + + # Listener for a prod-tier host with 'dns' role + { + nkey: "UPROD_DNS1_PUBLIC_KEY_HERE" + permissions: { + subscribe: [ + "deploy.prod.dns1" + "deploy.prod.all" + "deploy.prod.role.dns" + "deploy.discover" + ] + publish: [ + "deploy.responses.>" + "deploy.discover" + ] + } + } + + # Test-tier deployer (MCP without admin) + { + nkey: "UTEST_DEPLOYER_PUBLIC_KEY_HERE" + permissions: { + publish: [ + "deploy.test.>" + "deploy.discover" + ] + subscribe: [ + "deploy.responses.>" + "deploy.discover" + ] + } + } + + # Admin deployer (full access to all tiers) + { + nkey: "UADMIN_DEPLOYER_PUBLIC_KEY_HERE" + permissions: { + publish: [ + "deploy.>" + ] + subscribe: [ + "deploy.>" + ] + } + } + ] +} +``` + +### Key Permission Patterns + +| Credential Type | Publish | Subscribe | +|-----------------|---------|-----------| +| Listener | `deploy.responses.>`, `deploy.discover` | Own subjects, `deploy.discover` | +| Test deployer | `deploy.test.>`, `deploy.discover` | `deploy.responses.>`, `deploy.discover` | +| Admin deployer | `deploy.>` | `deploy.>` | + +### Generating NKeys + +```bash +# Generate a keypair (outputs public key, saves seed to file) +nk -gen user -pubout > mykey.pub +# The seed (private key) is printed to stderr - save it securely + +# Or generate and save seed directly +nk -gen user > mykey.seed +nk -inkey mykey.seed -pubout # Get public key from seed +``` + +The public key (starting with `U`) goes in the NATS server config. The seed file (starting with `SU`) is used by homelab-deploy via `--nkey-file`. + ## License MIT