zeroclaw-labs/zeroclaw · error

Nevis token_validation is 'local' but no jwks_url is configu

Error message

Nevis token_validation is 'local' but no jwks_url is configured. Either set jwks_url or use token_validation = 'remote'.

What it means

NevisAuthProvider::new was configured with token_validation = 'local' but no jwks_url. Local validation means verifying JWT signatures against the provider's published keys, which requires the JWKS endpoint URL; without it the provider cannot validate anything, so construction fails fast instead of silently accepting or rejecting tokens.

Source

Thrown at crates/zeroclaw-runtime/src/security/nevis.rs:109

};

impl NevisAuthProvider {
    /// Create a new Nevis auth model_provider from config values.
    /// `client_secret` should already be decrypted by the config loader.
    pub fn new(
        instance_url: String,
        realm: String,
        client_id: String,
        client_secret: Option<String>,
        token_validation: &str,
        jwks_url: Option<String>,
        require_mfa: bool,
        session_timeout_secs: u64,
    ) -> Result<Self> {
        let validation_mode = TokenValidationMode::from_str_config(token_validation)?;

        if validation_mode == TokenValidationMode::Local && jwks_url.is_none() {
            bail!(
                "Nevis token_validation is 'local' but no jwks_url is configured. \
                 Either set jwks_url or use token_validation = 'remote'."
            );
        }

        let http_client = reqwest::Client::builder()
            .timeout(Duration::from_secs(30))
            .build()
            .context("Failed to create HTTP client for Nevis")?;

        Ok(Self {
            instance_url,
            realm,
            client_id,
            client_secret,
            validation_mode,
            jwks_url,
            require_mfa,

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Set jwks_url, typically https://<nevis-host>/auth/realms/<realm>/protocol/openid-connect/certs.
  2. Or switch to token_validation = 'remote' to validate via the introspection endpoint (no JWKS needed).
  3. Add a config schema/lint that requires jwks_url whenever token_validation is local.
  4. Verify the URL responds: curl <jwks_url> should return a JSON key set.

Example fix

# before
token_validation = "local"
# (no jwks_url)

# after
token_validation = "local"
jwks_url = "https://nevis.example.com/auth/realms/main/protocol/openid-connect/certs"
Defensive patterns

Strategy: validation

Validate before calling

let mode = token_validation.trim().to_ascii_lowercase();
if mode == "local" && jwks_url.as_deref().map(str::trim).unwrap_or("").is_empty() {
    anyhow::bail!("token_validation='local' requires a non-empty jwks_url");
}

Try / catch

Err(e) if e.to_string().contains("no jwks_url is configured") => {
    // either populate jwks_url or switch token_validation to 'remote'; block startup until fixed
}

Prevention

When it happens

Trigger: Enabling local validation without providing jwks_url; jwks_url dropped during config refactor (renamed key, misspelled, commented out); migrating from remote to local validation and forgetting the new required field.

Common situations: Copying a minimal auth config from examples that omit JWKS; key name mismatches like jwksUrl vs jwks_url in templated config; switching modes to reduce introspection load without adding the endpoint.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/ec49581686e3e249. Report an issue: GitHub.