feat: hot-reload SSH manual CA private key#376
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #376 +/- ##
==========================================
+ Coverage 86.06% 86.32% +0.25%
==========================================
Files 40 41 +1
Lines 2828 2896 +68
==========================================
+ Hits 2434 2500 +66
- Misses 269 271 +2
Partials 125 125
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
e29f3ad to
68df914
Compare
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SACLEGn4b97yMUTEws2MyU
68df914 to
14c2065
Compare
7e752bf to
b15889d
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds hot-reload support for the manual SSH CA private key used by the SSH proxy, enabling on-disk CA key rotation without restarting the gateway and triggering immediate re-signing of the gateway’s SSH host certificate.
Changes:
- Introduces a
keyReloaderthat watches the manual CA private key file and reloads the in-memory CA signer on changes. - Updates the embedded CA implementation to fetch the signer via a getter so it can be swapped at runtime.
- Extends
autoRenewingCertSignerto accept an optional renewal signal channel to re-sign immediately on CA key rotation, with accompanying tests.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/sshhandler/key_reloader.go | Adds filesystem watcher + reload signaling for manual CA private key rotation. |
| internal/sshhandler/key_reloader_test.go | Adds tests for key reload behavior across writes, atomic replace, Kubernetes secret updates, and error recovery. |
| internal/sshhandler/config.go | Wires CA key reload signal into host cert auto-renew signer. |
| internal/sshhandler/cert.go | Adds renewCh support to re-sign certificates immediately on CA key rotation. |
| internal/sshhandler/cert_test.go | Adds coverage for re-signing behavior on CA key rotation. |
| internal/sshhandler/ca.go | Switches embedded CA to signer getter and adds background key reload start for manual CA. |
| internal/sshhandler/ca_test.go | Updates embedded CA tests and adds manual CA reload test. |
| CLAUDE.md | Documents manual CA hot-reload behavior in the SSH handler overview. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // update sequence for a projected secret volume: | ||
| // | ||
| // mount/ca -> ..data/ca, ..data -> ..timestamp1, update swaps ..data to ..timestamp2 and removes ..timestamp1 | ||
| func TestKeyReloaderReloadWhenKubernetesSecretUpdated(t *testing.T) { |
There was a problem hiding this comment.
Based on the atomic write algorithm described here
| return nil | ||
| } | ||
|
|
||
| func (kr *keyReloader) watch(ctx context.Context) error { |
There was a problem hiding this comment.
This logic is similar to the watch function in cert_reloader.go. I'm keeping them separated for now, if there's a third reloader, we could create a common reloader package and reuse them
Related Tickets
Closes #375
Changes
🤖 Generated with Claude Code