siyuan-note/siyuan · error

OIDC login requires at least one claim rule when Allow all…

Error message

OIDC login requires at least one claim rule when Allow all users is disabled

What it means

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.

Solutions

  1. Add at least one claim rule (e.g. claim 'email' with the allowed value(s)) in the OIDC settings before saving
  2. Alternatively enable 'Allow all users' (AllowAll = true) if unrestricted login is intended
  3. If no login should be permitted via OIDC, disable the OIDC provider entirely (Enabled = false)

Example fix

// before
conf.OIDC{Enabled: true, AllowAll: false, ClaimRules: nil}
// after
conf.OIDC{Enabled: true, AllowAll: false, ClaimRules: []*conf.OIDCClaimRule{{Claim: "email", Values: []string{"alice@example.com"}, Operator: conf.OIDCClaimOperatorEquals}}}
Defensive patterns

Strategy: validation

Validate before calling

function canSaveOIDC(config) {
  return config.allowAll === true || (Array.isArray(config.claimRules) && config.claimRules.length > 0);
}

Prevention

When it happens

Trigger: Calling ValidateOIDCConfiguration (via validateOIDCConfiguration, ValidateOIDCMobileConfiguration, or ValidateOIDCProviderConfiguration) with config.AllowAll == false and len(config.ClaimRules) == 0.

Common situations: 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.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/6677f3f66bec3f17. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/oidc.go:480

	if config.Provider == conf.OIDCProviderGitHub && config.ClientSecret == "" {
		return errors.New("GitHub OAuth client secret is required")
	}
	if (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && config.IssuerURL == "" {
		return errors.New("OIDC issuer URL is required")
	}
	if (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && config.IssuerURL != "" {
		issuer, err := url.Parse(config.IssuerURL)
		if err != nil || issuer.Host == "" || issuer.User != nil || issuer.RawQuery != "" || issuer.Fragment != "" ||
			(issuer.Scheme != "https" && !util.IsLocalHostname(issuer.Hostname())) {
			return errors.New("OIDC issuer URL must use HTTPS unless it is a loopback address")
		}
	}
	if config.Provider != conf.OIDCProviderCustom && config.Provider != conf.OIDCProviderGoogle &&
		config.Provider != conf.OIDCProviderMicrosoft && config.Provider != conf.OIDCProviderGitHub {
		return errors.New("Unsupported OIDC provider")
	}
	if !config.AllowAll && len(config.ClaimRules) == 0 {
		return errors.New("OIDC login requires at least one claim rule when Allow all users is disabled")
	}
	for _, rule := range config.ClaimRules {
		if rule == nil || rule.Claim == "" || len(rule.Values) == 0 {
			return errors.New("OIDC claim rules must include a claim and at least one value")
		}
		if rule.Operator != conf.OIDCClaimOperatorEquals && rule.Operator != conf.OIDCClaimOperatorContains {
			return errors.New("Unsupported OIDC claim rule operator")
		}
		for _, value := range rule.Values {
			if value == "" {
				return errors.New("OIDC claim rule values cannot be empty")
			}
		}
	}
	return nil
}

func ValidateOIDCMobileConfiguration(config *conf.OIDC) error {

View on GitHub (pinned to 9f775e8a12)