root 01373c0e45 Phase 5: hardening — gRPC, observability, auth, config
- 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>
2026-03-27 06:37:07 -05:00

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);