{"record":{"id":"ec49581686e3e249","repo":"zeroclaw-labs/zeroclaw","slug":"nevis-token-validation-is-local-but-no-jwks-url","errorCode":null,"errorMessage":"Nevis token_validation is 'local' but no jwks_url is configured. Either set jwks_url or use token_validation = 'remote'.","messagePattern":"Nevis token_validation is 'local' but no jwks_url is configured\\. Either set jwks_url or use token_validation = 'remote'\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-runtime/src/security/nevis.rs","lineNumber":109,"sourceCode":"};\n\nimpl NevisAuthProvider {\n    /// Create a new Nevis auth model_provider from config values.\n    /// `client_secret` should already be decrypted by the config loader.\n    pub fn new(\n        instance_url: String,\n        realm: String,\n        client_id: String,\n        client_secret: Option<String>,\n        token_validation: &str,\n        jwks_url: Option<String>,\n        require_mfa: bool,\n        session_timeout_secs: u64,\n    ) -> Result<Self> {\n        let validation_mode = TokenValidationMode::from_str_config(token_validation)?;\n\n        if validation_mode == TokenValidationMode::Local && jwks_url.is_none() {\n            bail!(\n                \"Nevis token_validation is 'local' but no jwks_url is configured. \\\n                 Either set jwks_url or use token_validation = 'remote'.\"\n            );\n        }\n\n        let http_client = reqwest::Client::builder()\n            .timeout(Duration::from_secs(30))\n            .build()\n            .context(\"Failed to create HTTP client for Nevis\")?;\n\n        Ok(Self {\n            instance_url,\n            realm,\n            client_id,\n            client_secret,\n            validation_mode,\n            jwks_url,\n            require_mfa,","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/security/nevis.rs#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set jwks_url, typically https://<nevis-host>/auth/realms/<realm>/protocol/openid-connect/certs.","Or switch to token_validation = 'remote' to validate via the introspection endpoint (no JWKS needed).","Add a config schema/lint that requires jwks_url whenever token_validation is local.","Verify the URL responds: curl <jwks_url> should return a JSON key set."],"exampleFix":"# before\ntoken_validation = \"local\"\n# (no jwks_url)\n\n# after\ntoken_validation = \"local\"\njwks_url = \"https://nevis.example.com/auth/realms/main/protocol/openid-connect/certs\"","handlingStrategy":"validation","validationCode":"let mode = token_validation.trim().to_ascii_lowercase();\nif mode == \"local\" && jwks_url.as_deref().map(str::trim).unwrap_or(\"\").is_empty() {\n    anyhow::bail!(\"token_validation='local' requires a non-empty jwks_url\");\n}","typeGuard":null,"tryCatchPattern":"Err(e) if e.to_string().contains(\"no jwks_url is configured\") => {\n    // either populate jwks_url or switch token_validation to 'remote'; block startup until fixed\n}","preventionTips":["Add a config lint: jwks_url is required iff token_validation == 'local'.","Smoke-test the JWKS endpoint (curl) in deployment checks so the URL is verified reachable.","Keep example configs paired: local mode always shown together with a jwks_url line."],"tags":["nevis","auth","config","jwks","oauth2"],"backgroundTag":"missing-config-value","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}