OpenNHP/opennhp · error
JWT signing key is not initialized
Error message
JWT signing key is not initialized
What it means
generateJWT signs the KBS token with a package-level jwtSigningKey that must be initialized first (typically during startup, e.g. from ParseTeePubkey/generateJWT setup). If it is still nil when Attest() asks for a token, JWT creation is refused instead of panicking on a nil signing method.
Solutions
- Ensure the JWT signing key is generated/loaded during service init before Attest() is reachable
- Check init logs for a failed key-load step and fix its root cause
- Add the signing key setup to test fixtures when testing generateJWT
- Guard startup so the KBS HTTP endpoints only register after key init succeeds
Example fix
// before (test) token, _ := generateJWT() // after jwtSigningKey = mustGenerateSigningKey() token, _ := generateJWT()
Defensive patterns
Strategy: validation
Validate before calling
if jwtSigningKey == nil {
return errors.New("generateJWT called before signing key init")
}
token, err := generateJWT() Type guard
func jwtReady() bool { return jwtSigningKey != nil } Try / catch
token, err := generateJWT()
if err != nil {
if err.Error() == "JWT signing key is not initialized" {
return fmt.Errorf("KBS not ready: %w", err) // surface as 503 to callers
}
return err
} Prevention
- Initialize the signing key in a single startup path before serving requests
- Expose a readiness endpoint that reports jwtReady()
- Add a unit test asserting generateJWT works after init
When it happens
Trigger: Attest() -> generateJWT runs before the key initialization step executed, or initialization failed silently earlier (e.g. key load error swallowed, wrong init order in tests or partial server startup).
Common situations: Unit tests calling generateJWT directly without setting jwtSigningKey; server started with a broken attestation config so init skipped; race where attestation request arrives during startup.
Related errors
- unsupported key type, expect RSA
- TEE public key is not found for specified token
- invalid n
- invalid e
- invalid public key length: got
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/2b83fe6eea768ea5.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/server/kbs/attest/attest.go:129
eBytes, err := base64.RawURLEncoding.DecodeString(pubkey.E)
if err != nil {
return nil, fmt.Errorf("invalid e: %w", err)
}
e := 0
for _, b := range eBytes {
e = e<<8 | int(b)
}
return &rsa.PublicKey{
N: new(big.Int).SetBytes(nBytes),
E: e,
}, nil
}
func generateJWT() (string, error) {
if jwtSigningKey == nil {
return "", errors.New("JWT signing key is not initialized")
}
claims := CustomClaims{
CosignAuthorized: true,
RegisteredClaims: jwt.RegisteredClaims{
IssuedAt: jwt.NewNumericDate(time.Now()),
ExpiresAt: jwt.NewNumericDate(time.Now().Add(5 * time.Minute)),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
publicKey := jwtSigningKey.PublicKey
token.Header["jwk"] = map[string]any{
"alg": "ES256",
"crv": "P-256",
"kty": "EC",
"x": base64.RawURLEncoding.EncodeToString(publicKey.X.Bytes()),View on GitHub (pinned to 6e04ca5ff0)