{"record":{"id":"9c1747bb47587401","repo":"Tencent/WeKnora","slug":"failed-to-generate-oidc-state-signing-key-v","errorCode":null,"errorMessage":"failed to generate OIDC state signing key: %v","messagePattern":"failed to generate OIDC state signing key: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/utils/oidc_state.go","lineNumber":40,"sourceCode":"\tNonce       string `json:\"nonce\"`\n\tRedirectURI string `json:\"redirect_uri,omitempty\"`\n\tIssuedAt    int64  `json:\"iat\"`\n}\n\nvar (\n\toidcStateSecretOnce sync.Once\n\toidcStateSecret     string\n)\n\nfunc oidcStateSigningKey() string {\n\toidcStateSecretOnce.Do(func() {\n\t\tif envSecret := strings.TrimSpace(os.Getenv(\"JWT_SECRET\")); envSecret != \"\" {\n\t\t\toidcStateSecret = envSecret\n\t\t\treturn\n\t\t}\n\t\trandomBytes := make([]byte, 32)\n\t\tif _, err := rand.Read(randomBytes); err != nil {\n\t\t\tpanic(fmt.Sprintf(\"failed to generate OIDC state signing key: %v\", err))\n\t\t}\n\t\toidcStateSecret = base64.StdEncoding.EncodeToString(randomBytes)\n\t})\n\treturn oidcStateSecret\n}\n\n// SignOIDCState returns a tamper-evident state token: base64url(payload).base64url(hmac).\nfunc SignOIDCState(payload *OIDCStatePayload) (string, error) {\n\tif payload == nil {\n\t\treturn \"\", errors.New(\"oidc state payload is required\")\n\t}\n\tif strings.TrimSpace(payload.Nonce) == \"\" {\n\t\treturn \"\", errors.New(\"oidc state nonce is required\")\n\t}\n\tif strings.TrimSpace(payload.RedirectURI) == \"\" {\n\t\treturn \"\", errors.New(\"oidc state redirect_uri is required\")\n\t}\n\tif payload.IssuedAt == 0 {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/utils/oidc_state.go#L22-L58","documentation":"OIDC state signing key initialization mirrors the JWT secret path: it uses JWT_SECRET if set, otherwise generates 32 random bytes with crypto/rand. If rand.Read fails, the code panics because OIDC state parameters cannot be signed without a key, breaking CSRF protection for the OIDC flow.","triggerScenarios":"First use of the OIDC state singleton when JWT_SECRET is unset and the OS entropy source fails (getrandom syscall blocked by seccomp, missing /dev/urandom, early-boot kernel without random ready).","commonSituations":"Hardened container seccomp profiles blocking getrandom; minimal/embedded runtimes; same root cause as the JWT secret panic — environments where crypto/rand cannot read 32 bytes.","solutions":["Set JWT_SECRET so the env-var branch is taken and rand is never needed","Adjust the sandbox/seccomp policy to permit getrandom(2) or ensure /dev/urandom exists","Restart the process — the failure is often transient during early boot","Provision the key from a file or secret manager instead of generating at runtime"],"exampleFix":"// before\nrandomBytes := make([]byte, 32)\nif _, err := rand.Read(randomBytes); err != nil { panic(...) }\n// after\n# deployment fix\nJWT_SECRET=<base64 32-byte secret>  # set in environment, skipping rand fallback","handlingStrategy":"fallback","validationCode":"if strings.TrimSpace(os.Getenv(\"JWT_SECRET\")) == \"\" {\n    if _, err := rand.Read(make([]byte, 32)); err != nil {\n        return fmt.Errorf(\"cannot obtain entropy for OIDC state key: %w\", err)\n    }\n}","typeGuard":"func oidcStateKeyAvailable() bool {\n    return strings.TrimSpace(os.Getenv(\"JWT_SECRET\")) != \"\"\n}","tryCatchPattern":"func oidcStateSecretSafe() (s string, err error) {\n    defer func() { if r := recover(); r != nil { err = fmt.Errorf(\"oidc state key panicked: %v\", r) } }()\n    return getOIDCStateSecret(), nil\n}","preventionTips":["Set JWT_SECRET wherever OIDC login is enabled","Permit getrandom(2) in container/sandbox policies","Provision signing keys via secret manager for deterministic startup"],"tags":["go","panic","oidc","crypto","entropy","security"],"backgroundTag":"crypto-rand-read-failure","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}