zeroclaw-labs/zeroclaw · error · anyhow::Error
xAI OAuth discovery returned non-HTTPS {label}
Error message
xAI OAuth discovery returned non-HTTPS {label} What it means
require_trusted_endpoint enforces that every endpoint xAI's OAuth discovery document advertises (authorization_endpoint, token_endpoint, device_authorization_endpoint) uses HTTPS. It fires when the endpoint URL parses but its scheme is http:, which would send authorization codes, tokens, and client secrets in cleartext. This is a deliberate security guard, not a connectivity problem.
Source
Thrown at crates/zeroclaw-providers/src/auth/xai_oauth.rs:558
}
fn decode_jwt_payload(token: &str) -> Option<serde_json::Value> {
let payload = token.split('.').nth(1)?;
let bytes = base64::engine::general_purpose::URL_SAFE_NO_PAD
.decode(payload)
.ok()
.or_else(|| {
base64::engine::general_purpose::URL_SAFE
.decode(payload)
.ok()
})?;
serde_json::from_slice(&bytes).ok()
}
fn require_trusted_endpoint(endpoint: &str, label: &str) -> Result<String> {
let url = reqwest::Url::parse(endpoint).with_context(|| format!("Invalid xAI {label}"))?;
if url.scheme() != "https" {
anyhow::bail!("xAI OAuth discovery returned non-HTTPS {label}");
}
let host = url.host_str().unwrap_or_default();
if host == "x.ai" || host.ends_with(".x.ai") {
return Ok(endpoint.to_string());
}
anyhow::bail!("xAI OAuth discovery returned untrusted {label}: {endpoint}")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn authorize_url_contains_xai_oauth_params() {
let pkce = PkceState {
code_verifier: "verifier".into(),
code_challenge: "challenge".into(),
state: "state".into(),View on GitHub (pinned to 88bb9c8533)
Solutions
- Remove any local override of xAI discovery/authorization/token endpoints and use the official https endpoints on x.ai
- Check for corporate proxies or SSL-inspection middleboxes rewriting x.ai responses and bypass them for x.ai
- Verify the discovery document actually returns https endpoints: curl the xAI well-known URL and inspect the endpoint fields
- For local testing use an https mock with a trusted certificate; never downgrade to http with real xAI credentials
Defensive patterns
Strategy: try-catch
Validate before calling
// If you feed endpoints into the flow, reject http early on your side too
if let Some(endpoint) = overridden_endpoint {
let url = reqwest::Url::parse(endpoint)?;
if url.scheme() != "https" {
anyhow::bail!("refusing non-HTTPS xAI endpoint: {endpoint}");
}
} Try / catch
match start_device_code_flow(&ctx).await {
Ok(flow) => { /* show user_code */ }
Err(e) if e.to_string().contains("non-HTTPS") => {
// security guard tripped: surface loudly, never auto-retry,
// audit proxies/DNS before the next attempt
}
Err(e) => return Err(e),
} Prevention
- Never override xAI OAuth endpoints with http URLs, even for local tests
- Use https mocks with trusted certificates when testing the flow locally
- Watch for SSL-inspection proxies rewriting x.ai discovery responses
- Treat this error as a security signal, not a transient failure - do not blind-retry
When it happens
Trigger: Any xAI OAuth flow step that consumes discovery (fetch_oauth_discovery, fetch_device_code_discovery, exchange_code_for_tokens, start_device_code_flow, poll_device_code_tokens) hits an endpoint whose URL starts with http:// instead of https://, whether from the fetched discovery JSON or a local override.
Common situations: Debugging against a local http mock of xAI auth; a proxy or captive portal rewriting the discovery response; a tampered or attacker-controlled discovery document; manual endpoint override to an http URL.
Related errors
- xAI OAuth discovery returned untrusted {label}: {endpoint}
- xAI auth profile is not OAuth-based: {profile_id}
- xAI auth profile is missing token set: {profile_id}
- xAI token refresh is in backoff for {remaining}s due to prev
- xAI OAuth discovery failed ({status}): {body}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/59ece6b471d2b67c.
Report an issue: GitHub.