Skip to main content

Crate huskarl_pingora

Crate huskarl_pingora 

Source
Expand description

Pingora integration for huskarl.

This crate provides two independent feature-gated modules:

Both features are enabled by default.

§Resource server example

A minimal JWT-protected reverse proxy using an RFC 9068 validator:

use std::sync::Arc;

use async_trait::async_trait;
use huskarl_pingora::{
    resource::{AuthCtx, AuthProxy, Guard, Rule},
    resource_server::{
        core::{jwk::JwksSource, server_metadata::AuthorizationServerMetadata},
        validator::rfc9068::Rfc9068Validator,
    },
};
use huskarl_reqwest::ReqwestClient;
use pingora_core::upstreams::peer::HttpPeer;
use pingora_error::Result;
use pingora_proxy::{ProxyHttp, Session};

type Claims = huskarl_pingora::resource_server::validator::rfc9068::Rfc9068AccessTokenClaims;

struct MyProxy;

#[async_trait]
impl ProxyHttp for MyProxy {
    type CTX = AuthCtx<(), Claims>;
    fn new_ctx(&self) -> Self::CTX {
        AuthCtx::new(())
    }

    async fn upstream_peer(
        &self,
        _session: &mut Session,
        _ctx: &mut Self::CTX,
    ) -> Result<Box<HttpPeer>> {
        let peer = HttpPeer::new("127.0.0.1:3000", false, String::new());
        Ok(Box::new(peer))
    }
}

#[tokio::main]
async fn main() {
    // 1. Create an HTTP client for fetching metadata and JWKS.
    let http_client = ReqwestClient::builder()
        .mtls(huskarl_reqwest::mtls::NoMtls)
        .build()
        .await
        .expect("HTTP client");

    // 2. Discover the authorization server's metadata (issuer, jwks_uri, …).
    let metadata = AuthorizationServerMetadata::fetch()
        .http_client(&http_client)
        .issuer("https://auth.example.com")
        .call()
        .await
        .expect("AS metadata");

    // 3. Build an RFC 9068 JWT validator.
    let jwks = Arc::new(JwksSource::builder().http_client(http_client).build());
    let validator = Rfc9068Validator::builder_from_metadata(&metadata)
        .audience("my-api")
        .jws_verifier_factory(jwks)
        .build()
        .await
        .expect("validator");

    // 4. Wrap your proxy with the auth guard.
    let guard = Guard::builder()
        .validator(validator)
        .route("/health", Rule::public())
        .build()
        .expect("guard");

    let proxy = AuthProxy::new(MyProxy, guard);
    // pass `proxy` to pingora — it implements ProxyHttp
}

Re-exports§

pub use huskarl_resource_server as resource_server;

Modules§

login
OAuth 2.0 Authorization Code Grant login layer for Pingora.
resource
OAuth 2.0 resource server (bearer token) protection for Pingora.