- proto: lakehouse.proto with CatalogService, QueryService, StorageService, AiService - proto crate: tonic-build codegen from proto definitions - catalogd: gRPC CatalogService implementation - gateway: dual HTTP (:3100) + gRPC (:3101) servers - gateway: OpenTelemetry tracing with stdout exporter - gateway: API key auth middleware (toggleable) - shared: TOML config system with typed structs and defaults - lakehouse.toml config file - ADR-006 and ADR-007 documented Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
37 lines
1011 B
Rust
37 lines
1011 B
Rust
use axum::{
|
|
extract::Request,
|
|
http::StatusCode,
|
|
middleware::Next,
|
|
response::Response,
|
|
};
|
|
|
|
/// API key auth middleware. Checks X-API-Key header against configured key.
|
|
pub async fn api_key_auth(
|
|
request: Request,
|
|
next: Next,
|
|
) -> Result<Response, StatusCode> {
|
|
// Get the expected key from the request extensions (set by the layer)
|
|
let expected_key = request.extensions().get::<ApiKey>().cloned();
|
|
|
|
if let Some(expected) = expected_key {
|
|
let provided = request
|
|
.headers()
|
|
.get("x-api-key")
|
|
.and_then(|v| v.to_str().ok());
|
|
|
|
match provided {
|
|
Some(key) if key == expected.0 => {}
|
|
_ => {
|
|
tracing::warn!("unauthorized request: missing or invalid API key");
|
|
return Err(StatusCode::UNAUTHORIZED);
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(next.run(request).await)
|
|
}
|
|
|
|
/// Wrapper type for the API key, stored in request extensions.
|
|
#[derive(Clone)]
|
|
pub struct ApiKey(pub String);
|