You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today a change needs a restart, which drops all grants.
Now also needed by #102: the config comes from git through pullgate, with a reload after each applied change (design decided 2026-11-11).
Done when
Reload on SIGHUP; grants for removed clients, secrets or keys end at once; a removed client cannot keep using an open TLS session.
An invalid new config is refused: the broker keeps running with the old one and logs why. A test.
nodkey broker reload sends the signal, waits for the result, and exits 0 only when the new config is loaded (non-zero, with the reason, otherwise). A test for both.
Grants that still match the new config stay open, with the same uses left and the same end. A test.
DESIGN.md, THREAT-MODEL.md and docs/setup.md say how a reload works (and that a restart is no longer needed after a config change).
Now needed by #102 (design decided 2026-11-11: config from git through pullgate, with a reload after each applied change). The reload must also:
refuse an invalid new config, keep running with the old one, and log why;
report the result in a way a script can read: a nodkey broker reload command that sends the signal, waits for the result, and exits 0 only when the new config is loaded. pullgate runs it as root after each change, and rolls back when it fails;
keep the grants that still match the new config. Today every config change ends all grants, and that is what makes config changes painful.
Done in #175, squash merged as f168ce6. CI was green (tests on go.mod and stable Go, lint, vuln, end-to-end test, title check).
Evidence for each "Done when" box:
Reload on SIGHUP; grants for removed clients, secrets or keys end at once; a removed client cannot keep using an open TLS session.
The broker reloads on SIGHUP (cmd/nodkey/broker.go, brokerreload.go). Grants end in approval.Core.Reload, while it holds the core's lock. Tests: TestReloadEndsChangedGrants, TestReloadRemovedClient, TestReloadEndsGrantsOfChangedKeyFile (internal/approval). For open connections: transport.Server.SetClients checks the pin again on each request. TestBrokerReload (cmd/nodkey) shows that a client with a new pin gets 403 on its open connection, and that a new handshake fails. Before and after each fetch or signature, the broker checks the request again (TestStillAllowed, TestBrokerReloadDuringTap).
An invalid new config is refused: the broker keeps running with the old one and logs why. A test. TestBrokerReload: a config that does not parse is sent with SIGHUP. The journal then says "refused the new config; the broker goes on with the config it has", and the old keys are still served. A missing key file and a changed listen are refused too. TestReloadFixed covers every part that needs a restart.
nodkey broker reload sends the signal, waits for the result, and exits 0 only when the new config is loaded. A test for both. TestBrokerReload: exit 0 when the broker loaded the config (the SHA-256 of the file is checked). Exit 1 with the reason when the broker refused it. TestBrokerReloadNoBroker: exit 1 with no broker, with a stale PID and with a symbolic link. TestBrokerReloadUsage: exit 64 on wrong usage.
Grants that still match the new config stay open, with the same uses left and the same end. A test. TestReloadKeepsMatchingGrants: a grant had 5 uses and used 1 before the reload. After the reload it gives exactly 4 more uses, and it ends at the same time. In the same test, a grant for a removed secret ends with cause config_changed.
DESIGN.md, THREAT-MODEL.md and docs/setup.md say how a reload works.
DESIGN.md section 14 "Reload", and section 15 (nodkey broker reload, SIGHUP). Section 9 has the new config_reloaded entry and the config_changed cause. THREAT-MODEL.md has T42. docs/setup.md section 10 has "Change the config without a restart", and the client and key-change steps now say nodkey broker reload instead of a restart.
What a reload can change: [client.*], [secret.*], [key.*] and known_hosts. Any other part, and a new credential file, still needs a restart. The broker refuses such a reload and says so.
Follow-up: #176 asks for three more deny-path tests that the security review suggested.
Activity
groupsky commentedon Nov 11, 2026
Now needed by #102 (design decided 2026-11-11: config from git through pullgate, with a reload after each applied change). The reload must also:
nodkey broker reloadcommand that sends the signal, waits for the result, and exits 0 only when the new config is loaded. pullgate runs it as root after each change, and rolls back when it fails;Added these to "Done when".
groupsky commentedon Nov 11, 2026
Done in #175, squash merged as f168ce6. CI was green (tests on go.mod and stable Go, lint, vuln, end-to-end test, title check).
Evidence for each "Done when" box:
The broker reloads on
SIGHUP(cmd/nodkey/broker.go,brokerreload.go). Grants end inapproval.Core.Reload, while it holds the core's lock. Tests:TestReloadEndsChangedGrants,TestReloadRemovedClient,TestReloadEndsGrantsOfChangedKeyFile(internal/approval). For open connections:transport.Server.SetClientschecks the pin again on each request.TestBrokerReload(cmd/nodkey) shows that a client with a new pin gets 403 on its open connection, and that a new handshake fails. Before and after each fetch or signature, the broker checks the request again (TestStillAllowed,TestBrokerReloadDuringTap).TestBrokerReload: a config that does not parse is sent withSIGHUP. The journal then says "refused the new config; the broker goes on with the config it has", and the old keys are still served. A missing key file and a changedlistenare refused too.TestReloadFixedcovers every part that needs a restart.nodkey broker reloadsends the signal, waits for the result, and exits 0 only when the new config is loaded. A test for both.TestBrokerReload: exit 0 when the broker loaded the config (the SHA-256 of the file is checked). Exit 1 with the reason when the broker refused it.TestBrokerReloadNoBroker: exit 1 with no broker, with a stale PID and with a symbolic link.TestBrokerReloadUsage: exit 64 on wrong usage.TestReloadKeepsMatchingGrants: a grant had 5 uses and used 1 before the reload. After the reload it gives exactly 4 more uses, and it ends at the same time. In the same test, a grant for a removed secret ends with causeconfig_changed.DESIGN.md section 14 "Reload", and section 15 (
nodkey broker reload, SIGHUP). Section 9 has the newconfig_reloadedentry and theconfig_changedcause. THREAT-MODEL.md has T42. docs/setup.md section 10 has "Change the config without a restart", and the client and key-change steps now saynodkey broker reloadinstead of a restart.What a reload can change:
[client.*],[secret.*],[key.*]andknown_hosts. Any other part, and a new credential file, still needs a restart. The broker refuses such a reload and says so.Follow-up: #176 asks for three more deny-path tests that the security review suggested.