{"record":{"id":"bf6f1bbe6fa94c18","repo":"glanceapp/glance","slug":"secret-key-must-be-set-when-users-are-configured","errorCode":null,"errorMessage":"secret-key must be set when users are configured","messagePattern":"secret-key must be set when users are configured","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/config.go","lineNumber":457,"sourceCode":"\t\tif debounceTimer != nil {\n\t\t\tdebounceTimer.Stop()\n\t\t}\n\n\t\treturn watcher.Close()\n\t}, nil\n}\n\n// TODO: Refactor, we currently validate in two different places, this being\n// one of them, which doesn't modify the data and only checks for logical errors\n// and then again when creating the application which does modify the data and do\n// further validation. Would be better if validation was done in a single place.\nfunc isConfigStateValid(config *config) error {\n\tif len(config.Pages) == 0 {\n\t\treturn fmt.Errorf(\"no pages configured\")\n\t}\n\n\tif len(config.Auth.Users) > 0 && config.Auth.SecretKey == \"\" {\n\t\treturn fmt.Errorf(\"secret-key must be set when users are configured\")\n\t}\n\n\tfor username := range config.Auth.Users {\n\t\tif username == \"\" {\n\t\t\treturn fmt.Errorf(\"user has no name\")\n\t\t}\n\n\t\tif len(username) < 3 {\n\t\t\treturn errors.New(\"usernames must be at least 3 characters\")\n\t\t}\n\n\t\tuser := config.Auth.Users[username]\n\n\t\tif user.Password == \"\" {\n\t\t\tif user.PasswordHashString == \"\" {\n\t\t\t\treturn fmt.Errorf(\"user %s must have a password or a password-hash set\", username)\n\t\t\t}\n\t\t} else if len(user.Password) < 6 {","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/config.go#L439-L475","documentation":"Validation requiring auth.secret-key when any users are configured under auth. Session tokens for HTTP basic/session auth are signed with this key; without it glance cannot securely authenticate the declared users.","triggerScenarios":"Config contains auth.users with at least one entry but auth.secret-key is empty/omitted. secret-key can also be supplied via environment/file variable expansion — the error means that expansion yielded nothing.","commonSituations":"Adding password protection from a tutorial but skipping the key line; setting secret-key via an env var (e.g. ${GLANCE_SECRET_KEY}) that is empty in the deployment environment; moving config to Docker and losing the env var.","solutions":["Add auth.secret-key with a long random string to glance.yml","If using variable expansion like ${SECRET_KEY}, verify the variable is actually set in the environment the process runs in","Generate a key with a password manager or openssl rand -base64 32 and store it outside the repo"],"exampleFix":"# before\nauth:\n  users:\n    - username: alice\n      password: hunter2\n# after\nauth:\n  secret-key: ${GLANCE_SECRET_KEY}\n  users:\n    - username: alice\n      password: ${GLANCE_USER_PASSWORD}","handlingStrategy":"validation","validationCode":"// Fail fast at startup with a clear message:\nif len(cfg.Auth.Users) > 0 && os.Getenv(\"GLANCE_SECRET_KEY\") == \"\" {\n    log.Fatal(\"GLANCE_SECRET_KEY must be set when users are configured\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a startup env checklist in systemd/compose (secret-key present when users exist)","Never commit the secret; inject via environment or env-file"],"tags":["glance","auth","security","configuration"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}