{"record":{"id":"6677f3f66bec3f17","repo":"siyuan-note/siyuan","slug":"oidc-login-requires-at-least-one-claim-rule-when-a","errorCode":null,"errorMessage":"OIDC login requires at least one claim rule when Allow all users is disabled","messagePattern":"OIDC login requires at least one claim rule when Allow all users is disabled","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/oidc.go","lineNumber":480,"sourceCode":"\tif config.Provider == conf.OIDCProviderGitHub && config.ClientSecret == \"\" {\n\t\treturn errors.New(\"GitHub OAuth client secret is required\")\n\t}\n\tif (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && config.IssuerURL == \"\" {\n\t\treturn errors.New(\"OIDC issuer URL is required\")\n\t}\n\tif (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && config.IssuerURL != \"\" {\n\t\tissuer, err := url.Parse(config.IssuerURL)\n\t\tif err != nil || issuer.Host == \"\" || issuer.User != nil || issuer.RawQuery != \"\" || issuer.Fragment != \"\" ||\n\t\t\t(issuer.Scheme != \"https\" && !util.IsLocalHostname(issuer.Hostname())) {\n\t\t\treturn errors.New(\"OIDC issuer URL must use HTTPS unless it is a loopback address\")\n\t\t}\n\t}\n\tif config.Provider != conf.OIDCProviderCustom && config.Provider != conf.OIDCProviderGoogle &&\n\t\tconfig.Provider != conf.OIDCProviderMicrosoft && config.Provider != conf.OIDCProviderGitHub {\n\t\treturn errors.New(\"Unsupported OIDC provider\")\n\t}\n\tif !config.AllowAll && len(config.ClaimRules) == 0 {\n\t\treturn errors.New(\"OIDC login requires at least one claim rule when Allow all users is disabled\")\n\t}\n\tfor _, rule := range config.ClaimRules {\n\t\tif rule == nil || rule.Claim == \"\" || len(rule.Values) == 0 {\n\t\t\treturn errors.New(\"OIDC claim rules must include a claim and at least one value\")\n\t\t}\n\t\tif rule.Operator != conf.OIDCClaimOperatorEquals && rule.Operator != conf.OIDCClaimOperatorContains {\n\t\t\treturn errors.New(\"Unsupported OIDC claim rule operator\")\n\t\t}\n\t\tfor _, value := range rule.Values {\n\t\t\tif value == \"\" {\n\t\t\t\treturn errors.New(\"OIDC claim rule values cannot be empty\")\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc ValidateOIDCMobileConfiguration(config *conf.OIDC) error {","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/oidc.go#L462-L498","documentation":"ValidateOIDCConfiguration enforces an explicit access policy: if the provider is enabled with AllowAll disabled, at least one claim rule must exist to decide who may log in. Without AllowAll or claim rules, no user could ever authenticate, so the configuration is rejected rather than silently locking everyone out.","triggerScenarios":"Calling ValidateOIDCConfiguration (via validateOIDCConfiguration, ValidateOIDCMobileConfiguration, or ValidateOIDCProviderConfiguration) with config.AllowAll == false and len(config.ClaimRules) == 0.","commonSituations":"Admin enables OIDC login but leaves the claim rules table empty while 'allow all users' is unchecked; a config migration or API payload drops the ClaimRules array; a user disables AllowAll thinking claim rules are optional.","solutions":["Add at least one claim rule (e.g. claim 'email' with the allowed value(s)) in the OIDC settings before saving","Alternatively enable 'Allow all users' (AllowAll = true) if unrestricted login is intended","If no login should be permitted via OIDC, disable the OIDC provider entirely (Enabled = false)"],"exampleFix":"// before\nconf.OIDC{Enabled: true, AllowAll: false, ClaimRules: nil}\n// after\nconf.OIDC{Enabled: true, AllowAll: false, ClaimRules: []*conf.OIDCClaimRule{{Claim: \"email\", Values: []string{\"alice@example.com\"}, Operator: conf.OIDCClaimOperatorEquals}}}","handlingStrategy":"validation","validationCode":"function canSaveOIDC(config) {\n  return config.allowAll === true || (Array.isArray(config.claimRules) && config.claimRules.length > 0);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always configure claim rules when AllowAll is off","Test the config with TestValidateOIDCConfigurationRequiresExplicitPolicy-style checks before deploying","Expose the requirement in the settings UI before submission"],"tags":["oidc","validation","config"],"backgroundTag":"missing-required-config","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}