xai-org/grok-build · error · OidcError

OidcError::UnsupportedAlg

Error message

OidcError::UnsupportedAlg

What it means

OidcError::UnsupportedAlg is raised by ensure_alg_allowed when the id_token's JOSE header algorithm is not in the shell's hardcoded ALLOWED_ID_TOKEN_ALGS (RS256/384/512, PS256/384/512, ES256/384, EdDSA). The error carries the JWA algorithm name. This is a deliberate security rejection of algorithms the library refuses to verify.

Source

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

        jsonwebtoken::Algorithm::PS512 => "PS512",
        jsonwebtoken::Algorithm::ES256 => "ES256",
        jsonwebtoken::Algorithm::ES384 => "ES384",
        jsonwebtoken::Algorithm::EdDSA => "EdDSA",
        other => match other {
            jsonwebtoken::Algorithm::HS256 => "HS256",
            jsonwebtoken::Algorithm::HS384 => "HS384",
            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,

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Reconfigure the IdP to sign id_tokens with RS256 (or another supported asymmetric alg)
  2. Check the id_token header (alg claim) to confirm which algorithm the provider uses
  3. If the provider cannot change algs, you cannot use it with this shell's OIDC flow

Example fix

// before (IdP client config)
"id_token_signed_response_alg": "HS256"
// after
"id_token_signed_response_alg": "RS256"
Defensive patterns

Strategy: validation

Validate before calling

// decode the unverified header to see which alg the IdP will use, before the full flow
fn id_token_alg(token: &str) -> Option<String> {
    jsonwebtoken::decode_header(token).ok().map(|h| format!("{:?}", h.alg))
}

Type guard

fn alg_supported(h: &jsonwebtoken::Header) -> bool {
    matches!(h.alg,
        jsonwebtoken::Algorithm::RS256 | jsonwebtoken::Algorithm::RS384 | jsonwebtoken::Algorithm::RS512 |
        jsonwebtoken::Algorithm::PS256 | jsonwebtoken::Algorithm::PS384 | jsonwebtoken::Algorithm::PS512 |
        jsonwebtoken::Algorithm::ES256 | jsonwebtoken::Algorithm::ES384 | jsonwebtoken::Algorithm::EdDSA)
}

Try / catch

match res {
    Err(e) if matches!(e.downcast_ref::<OidcError>(), Some(OidcError::UnsupportedAlg(a))) => {
        eprintln!("IdP signs id_tokens with {a}; reconfigure the provider to RS256");
    }
    other => other?,
}

Prevention

When it happens

Trigger: validate_and_extract_user_info -> ensure_alg_allowed inspects jsonwebtoken::decode_header(token).alg; if ALLOWED_ID_TOKEN_ALGS does not contain it, UnsupportedAlg(alg_name) is returned.

Common situations: A provider issues id_tokens signed with HS256 (client-secret symmetric signing) or another non-asymmetric alg; the IdP was configured with an unusual default signing algorithm.

Related errors


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