{"record":{"id":"0362c793d57a68f7","repo":"JuliusBrussee/caveman","slug":"secretbox-production-refuses-plaintext-s-use-s","errorCode":null,"errorMessage":"secretbox: production refuses plaintext %s; use %s","messagePattern":"secretbox: production refuses plaintext (.+?); use (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/secretbox/secretbox.go","lineNumber":171,"sourceCode":"\t\treturn plaintext, nil\n\t}\n\treturn Decrypt(envelope)\n}\n\nfunc useKMS() bool {\n\treturn strings.EqualFold(strings.TrimSpace(os.Getenv(\"CAVE_KMS_PROVIDER\")), kms.ProviderScaleway)\n}\n\n// ResolveEnvironmentSecret loads a boot-time secret. In production plaintext\n// environment variables are rejected: operators must provide a base64-encoded\n// secretbox/KMS envelope in ciphertextEnv. Local development may continue using\n// plaintextEnv. An entirely absent optional secret returns an empty string.\nfunc ResolveEnvironmentSecret(plaintextEnv, ciphertextEnv string) (string, error) {\n\tplain := strings.TrimSpace(os.Getenv(plaintextEnv))\n\tencoded := strings.TrimSpace(os.Getenv(ciphertextEnv))\n\tproduction := runtimeenv.IsProduction()\n\tif production && plain != \"\" {\n\t\treturn \"\", fmt.Errorf(\"secretbox: production refuses plaintext %s; use %s\", plaintextEnv, ciphertextEnv)\n\t}\n\tif encoded == \"\" {\n\t\treturn plain, nil\n\t}\n\twrapped, err := base64.StdEncoding.DecodeString(encoded)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"secretbox: %s is not valid base64\", ciphertextEnv)\n\t}\n\tdecrypted, err := Decrypt(wrapped)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"secretbox: decrypt %s: %w\", ciphertextEnv, err)\n\t}\n\tif len(decrypted) == 0 {\n\t\treturn \"\", fmt.Errorf(\"secretbox: %s decrypted to an empty secret\", ciphertextEnv)\n\t}\n\treturn string(decrypted), nil\n}\n","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/766dce6b1394ebb56a3090748d5a0240a5aefb36/shared/platform/secretbox/secretbox.go#L153-L189","documentation":"ResolveEnvironmentSecret is running in production and found the plaintext environment variable set. Production must receive secrets as ciphertext envelopes, so the plaintext is refused outright; the message names both the offending plaintext variable and the ciphertext variable to use instead.","triggerScenarios":"Thrown at shared/platform/secretbox/secretbox.go:171 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Encrypt the secret into a secretbox/KMS envelope, base64-encode it, and set the ciphertextEnv variable instead","Remove the plaintext variable from the production environment entirely to prevent accidental use","Update deployment manifests/templates so they only ever populate the ciphertext form","For local development nothing changes — plaintextEnv remains accepted outside production"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"766dce6b1394ebb56a3090748d5a0240a5aefb36","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}