xai-org/grok-build · error · OidcError

OidcError::AlgNotInDiscoverySupportedList

Error message

OidcError::AlgNotInDiscoverySupportedList

What it means

OidcError::AlgNotInDiscoverySupportedList is raised by ensure_alg_allowed when the id_token algorithm passes the hardcoded allow-list but is absent from the provider's discovery document `id_token_signing_alg_values_supported`. The library treats discovery as authoritative about what the provider may issue.

Source

Thrown at crates/codegen/xai-grok-shell/src/auth/oidc/protocol.rs:630

            jsonwebtoken::Algorithm::HS512 => "HS512",
            _ => "unknown",
        },
    }
}
pub(super) fn ensure_alg_allowed(
    alg: jsonwebtoken::Algorithm,
    discovery_supported_algs: Option<&[String]>,
) -> anyhow::Result<()> {
    let alg_name = alg_to_jwa_name(alg);
    if !ALLOWED_ID_TOKEN_ALGS.contains(&alg) {
        return Err(anyhow::Error::new(OidcError::UnsupportedAlg(
            alg_name.to_owned(),
        )));
    }
    if let Some(supported) = discovery_supported_algs
        && !supported.iter().any(|a| a == alg_name)
    {
        return Err(anyhow::Error::new(
            OidcError::AlgNotInDiscoverySupportedList {
                alg: alg_name.to_owned(),
            },
        ));
    }
    Ok(())
}
pub(super) async fn validate_and_extract_user_info(
    token: &str,
    discovery: &Discovery,
    expected_issuer: &str,
    expected_client_id: &str,
    expected_nonce: &str,
) -> anyhow::Result<OidcUserInfo> {
    let header = jsonwebtoken::decode_header(token)?;
    let kid = header
        .kid
        .ok_or_else(|| anyhow::Error::new(OidcError::IdTokenMissingKid))?;

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Fix the IdP discovery document to include the algorithm it actually signs with (provider-side config)
  2. Verify the id_token's alg matches one of the algs advertised by the issuer's well-known document
  3. Refresh/re-fetch discovery (restart the flow) if the provider rotated algorithms and metadata is stale

Example fix

// before (IdP discovery doc)
"id_token_signing_alg_values_supported": ["RS256"]  // token signed ES256
// after
"id_token_signing_alg_values_supported": ["RS256", "ES256"]
Defensive patterns

Strategy: validation

Validate before calling

// compare the token's alg against discovery's advertised list before validation
fn alg_in_discovery(alg_name: &str, discovery_algs: Option<&[String]>) -> bool {
    match discovery_algs {
        None => true, // unchecked when discovery omits the field
        Some(list) => list.iter().any(|a| a == alg_name),
    }
}

Try / catch

match res {
    Err(e) if matches!(e.downcast_ref::<OidcError>(), Some(OidcError::AlgNotInDiscoverySupportedList { alg })) => {
        eprintln!("IdP signs with {alg} but does not advertise it; fix the provider's discovery metadata");
    }
    other => other?,
}

Prevention

When it happens

Trigger: validate_and_extract_user_info -> ensure_alg_allowed is passed discovery_supported_algs; if Some(list) and no entry equals the token's JWA alg name, AlgNotInDiscoverySupportedList { alg } is returned.

Common situations: IdP signs with an algorithm not advertised in its own discovery metadata (provider misconfiguration), or discovery metadata is stale/cached after an IdP algorithm rotation.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/d9e2a5f58e049141. Report an issue: GitHub.