Skip to main content

Module headers_auth

Module headers_auth 

Source
Expand description

The required-headers and authentication gate.

This is the Rust family’s port of two adjacent reference checks, guard_core/core/checks/implementations/required_headers.py and guard_core/core/checks/implementations/authentication.py (with the credential extraction of guard_core/core/checks/helpers.py::extract_credential), evaluated in the reference pipeline’s order: required headers first, then authentication. One call, decide, carries a request’s header values through both:

required headers, first failing rule in configured order:
  header absent or empty:          400 "Missing required header: {name}"
  value != expected (sentinel
  "required" = presence only):     400 "Header '{name}' does not match the required value"
authentication:
  authorization_header_required set: presence-only scheme check on
                                     the authorization header
  auth_required set: scheme check, then the auth verifier decides
  api_key_required set: the api key header must carry a value, then the
                        api key verifier decides
  any auth failure:                401 "Authentication required"

§Details that mirror the reference exactly

  • A required header that is present but empty counts as missing (if not actual in the reference), expected values compare case-sensitively, and the "required" sentinel means presence-only. The block body is the reference’s dynamic default message, which is why it is an owned String here.
  • Credential extraction is extract_credential: the scheme names "bearer" and "basic" (exact, lowercase) require the exact Bearer / Basic prefix and carry the remainder as the credential; any other scheme accepts the whole header value as the credential and fails only when it is empty.
  • The presence check (authorization_header_required) short-circuits: when it is set, auth_required/api_key_required are not consulted, exactly as the reference check returns after it.
  • Verifier resolution: the route’s auth_verifier (or api_key_verifier on the API-key path) wins, the global auth_verifier is the fallback; a required credential with no verifier at all is a failure (“No auth verifier configured”), as in the reference. All failures answer the same body, 401 "Authentication required" (the reasons are observability-only in the reference too).

The header lookup is a closure (name -> Option<&str>, case-insensitive on the name), so adapters feed it from HeaderMap, actix, or Rocket types alike.

§Example

use std::sync::Arc;

use guard_core_engine::headers_auth::{
    decide, HeaderAuthRules, RequiredHeader, RouteVerifiers, REQUIRED_SENTINEL,
};

let rules = HeaderAuthRules {
    required_headers: vec![RequiredHeader {
        name: "X-Request-ID".to_owned(),
        expected: REQUIRED_SENTINEL.to_owned(),
    }],
    auth_required: Some("bearer".to_owned()),
    ..HeaderAuthRules::default()
};
let verifiers = RouteVerifiers {
    auth: Some(Arc::new(|credential| credential == "token-1")),
    api_key: None,
};
let headers = [
    ("X-Request-ID", "abc"),
    ("Authorization", "Bearer token-1"),
];
let lookup = |name: &str| {
    headers
        .iter()
        .find(|(key, _)| key.eq_ignore_ascii_case(name))
        .map(|(_, value)| (*value).to_owned())
};

// Everything present: pass.
assert!(decide(&rules, &verifiers, lookup).is_none());

// A missing required header is the reference's dynamic 400 body.
let block = decide(&rules, &verifiers, |_| None).expect("missing header");
assert_eq!(block.status, 400);
assert_eq!(block.body, "Missing required header: X-Request-ID");

// A bad bearer credential is the fixed 401 shape.
let block = decide(
    &rules,
    &verifiers,
    |name| {
        if name.eq_ignore_ascii_case("Authorization") {
            Some("Bearer wrong".to_owned())
        } else {
            Some("abc".to_owned())
        }
    },
)
.expect("auth failure");
assert_eq!(block.status, 401);
assert_eq!(block.body, "Authentication required");

Structs§

GuardBlock
The block answer of a failed header or authentication rule: the status, the reference default message body (dynamic for the required-header shapes, which is why it is owned), and the violation type.
HeaderAuthRules
The route-level header and authentication rules.
RequiredHeader
One required-header rule, in configured order: name must be present, and its value must equal expected unless expected is REQUIRED_SENTINEL.
RouteVerifiers
The verifiers one route resolves to, after the caller merged the global auth_verifier fallback (route verifier wins).

Enums§

GuardViolation
Which rule failed (the reference’s violation_type values, carried for observability).

Constants§

REQUIRED_SENTINEL
The required-header expected value meaning presence only (required_headers[name] == "required" in the reference).

Functions§

decide
Carry a request’s header values through the required-headers check and then the authentication check, in the reference pipeline’s order.
extract_credential
The reference extract_credential: the credential of an authorization header value under a scheme.

Type Aliases§

AuthVerifier
A credential verifier: credential -> accepted?.