fix(providers): correct dynamic grant CI checks

Use if-let for a grant result whose error payload is deliberately ignored,
and name the empty query map type in the regression fixture. Preserve grant
acquisition, failure redaction and request atomicity. Update the token-exchange
failure test to require the sanitized error instead of raw issuer text.

Signed-off-by: Shiju <shiju@nvidia.com>
This commit is contained in:
Shiju
2026-10-01 16:09:34 +05:30
parent 0673e36c90
commit decdfcb848
3 changed files with 35 additions and 38 deletions
@@ -115,41 +115,38 @@ pub async fn inject_if_needed(req: L7Request, ctx: &L7EvalContext) -> Result<L7R
.as_ref()
.ok_or_else(|| miette!("selected credential has no token grant"))?;
let request = token_grant_request(provider_key, token_grant)?;
match resolver.obtain(request).await {
Ok(access_token) => {
crate::token_grant::validate_access_token(&access_token)?;
headers.push(token_grant_header(cred, &access_token)?);
}
Err(_) => {
// An issuer may echo credentials in its error description. Only the
// binding identity is safe to include in diagnostics or relay errors.
let provider_key = ocsf_message_field(provider_key);
warn!(
host = %ctx.host,
port = ctx.port,
provider = %provider_key,
"Token grant failed"
);
ocsf_emit!(
HttpActivityBuilder::new(ocsf_ctx())
.activity(ActivityId::Fail)
.action(ActionId::Denied)
.disposition(DispositionId::Blocked)
.severity(SeverityId::Medium)
.status(StatusId::Failure)
.http_request(HttpRequest::new(
&req.action,
OcsfUrl::new("http", &ctx.host, request_path, ctx.port),
))
.dst_endpoint(Endpoint::from_domain(&ctx.host, ctx.port))
.message(format!(
"Token grant failed for {} to {}:{}",
provider_key, ctx.host, ctx.port
))
.build()
);
return Err(miette!("Token grant failed"));
}
if let Ok(access_token) = resolver.obtain(request).await {
crate::token_grant::validate_access_token(&access_token)?;
headers.push(token_grant_header(cred, &access_token)?);
} else {
// An issuer may echo credentials in its error description. Only the
// binding identity is safe to include in diagnostics or relay errors.
let provider_key = ocsf_message_field(provider_key);
warn!(
host = %ctx.host,
port = ctx.port,
provider = %provider_key,
"Token grant failed"
);
ocsf_emit!(
HttpActivityBuilder::new(ocsf_ctx())
.activity(ActivityId::Fail)
.action(ActionId::Denied)
.disposition(DispositionId::Blocked)
.severity(SeverityId::Medium)
.status(StatusId::Failure)
.http_request(HttpRequest::new(
&req.action,
OcsfUrl::new("http", &ctx.host, request_path, ctx.port),
))
.dst_endpoint(Endpoint::from_domain(&ctx.host, ctx.port))
.message(format!(
"Token grant failed for {} to {}:{}",
provider_key, ctx.host, ctx.port
))
.build()
);
return Err(miette!("Token grant failed"));
}
}
@@ -4,6 +4,7 @@
use super::test_support::TokenGrantTestFixture;
use super::*;
use crate::l7::provider::BodyLength;
use std::collections::HashMap;
use std::sync::Mutex;
use tracing::instrument::WithSubscriber;
use tracing_subscriber::layer::SubscriberExt;
@@ -15,7 +16,7 @@ fn request() -> L7Request {
L7Request {
action: "POST".into(),
target: "/v1/projects?view=full".into(),
query_params: Default::default(),
query_params: HashMap::default(),
raw_header: b"POST /v1/projects?view=full HTTP/1.1\r\nHost: api.example.com\r\nAuthorization: Bearer agent-token\r\nauthorization : duplicate\r\nX-Workload-Jwt: agent-identity\r\nx-workload-jwt: duplicate\r\nX-Static: openshell:placeholder\r\nContent-Length: 4\r\n\r\nbody".to_vec(),
body_length: BodyLength::ContentLength(4),
}
@@ -12818,8 +12818,7 @@ network_policies:
.await
.expect_err("forward token exchange failure should stop request rewriting");
assert!(err.to_string().contains("Token grant failed"));
assert!(err.to_string().contains("oauth unavailable"));
assert_eq!(err.to_string(), "Token grant failed");
fixture.assert_one_token_exchange_request(
"api.example.test\t8080\t/v1/**\tprovider:access_token",
);