fix: generate strong unique JWT key#1071
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1071 +/- ##
==========================================
+ Coverage 43.39% 43.50% +0.10%
==========================================
Files 141 141
Lines 13397 13447 +50
==========================================
+ Hits 5814 5850 +36
- Misses 7022 7031 +9
- Partials 561 566 +5 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR aims to improve JWT signing-key safety by generating a strong unique key on first-run (when creating a new config), warning when the configured key appears weak, and adding a controller-side key-length validation plus related test updates.
Changes:
- Generate and persist a random JWT signing key when initializing a brand-new
config.yml(unlessAUTH_JWT_KEYis set). - Add a startup warning when
auth.jwtKeylooks too short. - Add HS256 key-length validation in the v1 devices redirection JWT endpoint and extend test coverage around key length validation.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| internal/controller/httpapi/v1/devices.go | Adds HS256 key-length validation before signing redirection JWTs. |
| internal/controller/httpapi/v1/devices_test.go | Updates test JWT key and adds unit tests for HS256 key-length validation helper. |
| config/config.go | Generates a random JWT key for new configs and warns if key is weak. |
| config/config_test.go | Adds tests for JWT key generation/persistence, env override behavior, and warning logging. |
f10976a to
a246d8a
Compare
| if _, isSetByEnv := os.LookupEnv("AUTH_JWT_KEY"); isSetByEnv { | ||
| return nil | ||
| } |
|
|
||
| var pathErr *os.PathError | ||
| if errors.As(err, &pathErr) { | ||
| if _, isSetByEnv := os.LookupEnv("AUTH_JWT_KEY"); !isSetByEnv { |
| # AUTH_ADMIN_PASSWORD: If not set, a random password is generated | ||
| AUTH_ADMIN_PASSWORD= | ||
| AUTH_JWT_KEY=your_secret_jwt_key | ||
| # AUTH_JWT_KEY: If not set, a strong key is generated and saved on first run |
|
|
||
| func TestReadOrInitConfig_DoesNotMutateExistingNonEmptyJWTKey(t *testing.T) { | ||
| t.Parallel() | ||
|
|
||
| tmpDir := t.TempDir() | ||
| configPath := filepath.Join(tmpDir, "config.yml") |
| return nil, err | ||
| } | ||
|
|
||
| warnIfWeakJWTKey(ConsoleConfig) |
There was a problem hiding this comment.
Should we not exit if the key length is < 32 than instead of logging a warning.
For a customer or developer they would hardly notice the warning in the log and see the console coming up successfuly
4c0be18 to
c3c4411
Compare
- Auto-generate a 32-byte random hex key on first run when jwtKey is empty in config and AUTH_JWT_KEY is not set - Persist generated key to config.yml without touching other fields - Fail startup when AUTH_JWT_KEY is set but empty (ErrEmptyJWTKeyEnv) - Warn at startup when effective key is under 32 bytes (any source) - Remove hardcoded placeholder jwtKey from config defaults and templates - Parameterise docker-compose credentials via env variables - Add tests for all key-handling paths
| func warnIfWeakJWTKey(cfg *Config) { | ||
| keyLen := len([]byte(cfg.JWTKey)) | ||
| if keyLen < hs256RecommendedMinKeyBytes { | ||
| log.Printf("WARNING: auth.jwtKey looks too short (%d bytes). Please use at least %d bytes for a strong key.", keyLen, hs256RecommendedMinKeyBytes) |
There was a problem hiding this comment.
use log.Errorf or log.Faralf() to exit.
another way is possible warn and replace smaller key with 32 or more secure jwt key.
JWT key generation and persistence
config.yml.jwtKey: auto-generate and persist without touching other fields.jwtKey: leave untouched.Environment variable semantics (
AUTH_JWT_KEY)ErrEmptyJWTKeyEnvWeak key warning