Skip to content

Commit bcfc332

Browse files
fix(deploy): harden nkey generation (#6)
Signed-off-by: Frank Spitulski <fspitulski@nvidia.com>
1 parent 6d3e67a commit bcfc332

8 files changed

Lines changed: 281 additions & 145 deletions

File tree

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
.PHONY: add-license-headers check check-license-headers help test test-e2e test-helm third-party-licenses
4+
.PHONY: add-license-headers check check-license-headers clean-e2e help test test-e2e test-helm third-party-licenses
55

66
COPYRIGHT_HOLDER := NVIDIA CORPORATION & AFFILIATES. All rights reserved.
77
COPYRIGHT_YEAR := 2026
@@ -24,6 +24,9 @@ check-license-headers: ## Verify SPDX license headers across repository sources
2424

2525
check: check-license-headers test test-helm ## Run all local validation checks
2626

27+
clean-e2e: ## Delete local Kind clusters and generated e2e artifacts
28+
$(MAKE) -C local clean-e2e
29+
2730
test: ## Run unit tests that do not require the local Kind environment
2831
$(MAKE) -C auth-callout test
2932
cd auth-callout/tests && go test -short ./...

deploy/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ Chart.lock
3232
*.backup
3333
*~
3434

35+
secrets/

deploy/README.md

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -158,36 +158,43 @@ An example script is provided to generate all required secrets to local files:
158158

159159
```bash
160160
# Generate secrets for a cluster
161-
./scripts/generate-nkeys.sh [OPTIONS] [cpc-ids...]
161+
./scripts/generate-nkeys.sh [OPTIONS] -c CLUSTER [cpc-ids...]
162162

163163
# Options:
164-
# -c, --cluster CLUSTER Cluster name: csc or cpc-{id} (default: csc)
165-
# -o, --output DIR Output directory (default: ./secrets/{cluster})
164+
# -c, --cluster CLUSTER Cluster name: csc or cpc-{id}
165+
# -o, --output DIR Output directory (default: deploy/secrets/{cluster})
166+
# --force Overwrite an existing non-empty output directory
166167
# -h, --help Show help message
167168

168169
# Examples:
169-
./scripts/generate-nkeys.sh -c csc # Generate for CSC, output to ./secrets/csc
170+
./scripts/generate-nkeys.sh -c csc 1 2 3 # Generate for CSC, output to deploy/secrets/csc
170171
./scripts/generate-nkeys.sh -c cpc-1 -o ./my-secrets # Generate for CPC-1, custom output directory
171-
./scripts/generate-nkeys.sh -c csc 1 2 3 # Generate for CSC with CPC IDs 1, 2, 3
172172
```
173173

174174
The script generates all required NKey secrets (operator, accounts, users, XKey).
175+
It refuses to overwrite an existing non-empty output directory. Use `--force`
176+
only when intentionally rotating all generated NKeys for that cluster. Rotating
177+
these keys invalidates existing leaf, auth-callout, NACK, mTLS, and surveyor
178+
credentials created from the previous output.
179+
180+
Generated secret files are written with mode `0600`, and generated secret
181+
directories are written with mode `0700`. Treat the full output directory as
182+
sensitive material.
175183

176184
Output structure:
177185
```
178-
secrets/{cluster}/
179-
└── nkeys/ # NKey secrets (one directory per secret)
180-
├── nats-auth-signing/
181-
├── nats-xkey/
182-
├── nats-authx-user/
183-
├── nats-nack-user/
184-
├── nats-mtls-leaf/
185-
├── nats-mtls-authx-leaf/
186-
├── nats-mtls-sys-leaf/
187-
├── nats-surveyor/
188-
├── auth-callout-keys/
189-
├── nats-leaf-cpc-{id}/ # CSC only (when CPC IDs provided)
190-
└── xkey.nk
186+
deploy/secrets/{cluster}/
187+
└── nkeys/
188+
├── nats-auth-signing/{seed,pubkey}
189+
├── nats-xkey/{seed,pubkey}
190+
├── nats-authx-user/{seed,pubkey}
191+
├── nats-nack-user/{seed,pubkey,nack-user.nk}
192+
├── nats-mtls-leaf/{seed,pubkey}
193+
├── nats-mtls-authx-leaf/{seed,pubkey}
194+
├── nats-mtls-sys-leaf/{seed,pubkey}
195+
├── nats-surveyor/{seed,pubkey}
196+
├── auth-callout-keys/{nkey-seed,issuer-seed,xkey-seed}
197+
└── nats-leaf-cpc-{id}/{seed,pubkey} # CSC only (when CPC IDs provided)
191198
```
192199

193200
## Chart Dependencies
@@ -777,7 +784,8 @@ eventBus:
777784
account: "CSC"
778785

779786
# CSC needs CPC leaf user pubkeys to authorize incoming leaf connections.
780-
# Add one entry per CPC cluster, matching the IDs in cpcIds.
787+
# This block is mandatory when eventBus.cpcIds is non-empty. Add one
788+
# entry per CPC cluster, matching the IDs in cpcIds.
781789
auth-callout:
782790
extraEnvs:
783791
NKEY_LEAF_CPC_1_PUBKEY:
@@ -792,6 +800,9 @@ auth-callout:
792800
key: pubkey
793801
```
794802
803+
The chart validates that every `eventBus.cpcIds` entry has a matching
804+
`NKEY_LEAF_CPC_{N}_PUBKEY` entry under `auth-callout.extraEnvs`.
805+
795806
### CPC Cluster
796807

797808
```yaml
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
{{/*
5+
Validation template for nats-event-bus values.
6+
This template emits no resources; it fails rendering on unsafe combinations.
7+
*/}}
8+
{{- $authCallout := index .Values "auth-callout" | default dict -}}
9+
{{- $extraEnvs := get $authCallout "extraEnvs" | default dict -}}
10+
{{- if and (eq .Values.eventBus.clusterType "csc") (gt (len .Values.eventBus.cpcIds) 0) -}}
11+
{{- range .Values.eventBus.cpcIds }}
12+
{{- $cpcId := toString . -}}
13+
{{- $envName := printf "NKEY_LEAF_CPC_%s_PUBKEY" $cpcId -}}
14+
{{- if not (hasKey $extraEnvs $envName) -}}
15+
{{- fail (printf "eventBus.cpcIds includes %q, but auth-callout.extraEnvs.%s is missing. Add a secretKeyRef to nats-leaf-cpc-%s key pubkey so CSC can authorize the CPC leaf connection." $cpcId $envName $cpcId) -}}
16+
{{- end -}}
17+
{{- end -}}
18+
{{- end -}}

deploy/nats-event-bus/values.yaml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -582,10 +582,13 @@ auth-callout:
582582
# Use external ConfigMap generated by nats-event-bus chart
583583
permissionsConfigMap: "auth-callout-permissions"
584584

585-
# Common auth-callout env vars
586-
# CSC clusters must add NKEY_LEAF_CPC_{N}_PUBKEY entries for each CPC
587-
# that will connect as a leaf node. The {N} corresponds to cpcIds values.
588-
# Example: cpcIds: ["1", "2"] requires NKEY_LEAF_CPC_1_PUBKEY and NKEY_LEAF_CPC_2_PUBKEY
585+
# Common auth-callout env vars.
586+
# CSC clusters with eventBus.cpcIds must also provide one
587+
# NKEY_LEAF_CPC_{N}_PUBKEY entry per CPC in auth-callout.extraEnvs.
588+
# Example: cpcIds: ["1", "2"] requires NKEY_LEAF_CPC_1_PUBKEY
589+
# and NKEY_LEAF_CPC_2_PUBKEY.
590+
# The chart validates this so leaf federation fails at render time instead
591+
# of failing later with NATS Authorization Violation.
589592
extraEnvs:
590593
AUTH_CALLOUT_NATS_NKEY_SEED: *authCalloutNkeySeed
591594
AUTH_CALLOUT_NATS_ISSUER_SEED: *authCalloutIssuerSeed

0 commit comments

Comments
 (0)