Skip to content

Commit ff1674b

Browse files
authored
feat(auth): add mTLS support for authenticated proxy (#1156)
* feat(auth): add mTLS support for authenticated proxy - Add TLS envelope encryption for secure key storage - Implement dual HTTP/HTTPS listener with mTLS support - Add client certificate identity extraction and validation - Implement certificate issuance API for short-lived client certs - Add TLS assets management and encrypted storage - Extend service models with TLS profile configuration - Add comprehensive mTLS flow tests - Update proxy to handle both clear-text and TLS connections - Add documentation for mTLS implementation plan * lint: fix fmt * feat(auth): add rcgen and time dependencies for mTLS certificate generation * feat(auth): add certificate authority module for mTLS certificate generation * feat(auth): export certificate authority module and add certificate error type * refactor(auth): add TlsCertMetadataConfig struct for certificate metadata creation * feat(auth): integrate certificate authority into proxy for mTLS profile management * refactor(auth): update TLS components for mTLS certificate handling * feat(auth): update main.rs for mTLS certificate authority initialization * test(auth): update tests for mTLS certificate authority functionality * feat: implement certificate authority for mTLS - Add CertificateAuthority struct for managing per-service CAs - Implement client certificate generation with TTL and SAN support - Add certificate validation and serialization utilities - Include CA persistence and restoration from encrypted storage * feat: implement TLS listener with dual socket support - Add TlsListener for handling both HTTP and HTTPS/mTLS connections - Implement client certificate extraction from TLS connections - Add TLS acceptor configuration with client authentication - Support per-service server configurations * feat: integrate mTLS support into authenticated proxy - Add TLS profile management endpoint (/v1/admin/services/{service_id}/tls-profile) - Implement certificate issuance API (/v1/auth/certificates) - Add gRPC proxy with mTLS support for both HTTP and HTTPS upstreams - Integrate client certificate identity extraction and header injection - Support dual transport (HTTP/1.1 and HTTP/2) with TLS termination * test: add comprehensive mTLS flow tests - Test admin TLS profile configuration and certificate issuance - Test certificate TTL validation and rejection of invalid requests - Test plaintext gRPC rejection when mTLS is required - Test successful gRPC requests with client certificates - Include test harness for mTLS scenarios with backend simulation * docs: add mTLS implementation plan and design documentation - Document mTLS support goals and design overview - Detail TLS profile administration API - Describe inbound/outbound transport changes - Include data model updates and operational considerations - Add test plan and implementation steps * refactor: update macros with minor formatting improvements * style: improve string formatting and code style - Use format string interpolation instead of format! with {} - Simplify closure syntax where possible - Rename variable for clarity - Fix doc comment spacing * feat: add once_cell and x509-parser dependencies to workspace * feat(auth): implement TLS runtime management and service-specific configurations - Add once_cell and x509-parser dependencies - Refactor TLS listener with per-service TLS configs - Integrate TLS runtime into authenticated proxy - Add optional fields to TLS profile response - Update mTLS flow tests - Remove auth-mtls-plan.md documentation * refactor(auth): remove deprecated proxy functions and improve TLS SNI handling - Remove grpc_proxy and reverse_proxy functions in favor of unified_proxy - Improve SNI fallback logic in TlsListenerManager::get_tls_config - Simplify certificate store loading error handling - Fix certificate timestamp handling for pre-1970 dates * docs(macros): fix comment formatting in load_abi documentation * feat: add TLS profile fields and validation logic - Add subject_alt_name_template and allowed_dns_names fields to TlsProfile - Implement certificate request validation against allowed DNS names - Add HashSet import for efficient DNS name validation * feat: update proxy TLS profile handling and certificate issuance - Preserve existing TLS profile fields when updating profiles - Add subject_alt_name_template and allowed_dns_names to TLS profile creation - Update TLS profile response to include allowed DNS names - Improve TLS profile initialization with proper defaults * feat: improve client certificate header injection with error handling - Add try_insert_header helper function for safe header insertion - Handle header value parsing errors gracefully with warnings - Use HeaderValue::from_static for known safe headers - Prevent header injection failures from breaking request processing * fix: correct macro documentation whitespace Remove trailing whitespace from macro documentation comment * feat: complete TLS profile handling improvements - Improve DNS names handling with proper fallbacks - Refactor conditional logic for cleaner code structure - Ensure consistent behavior when updating existing TLS profiles * fix: remove unnecessary mut keyword from server_dns_names variable * docs: fix documentation formatting in debug_job macro * feat(bridge): add TLS profile protobuf definitions Add TlsProfileConfig message to bridge.proto with fields for: - Server certificate and private key (encrypted) - Client CA bundle for mTLS (encrypted) - Upstream TLS configuration (encrypted) - SNI hostname and subjectAltName templates - Client certificate TTL and allowed DNS names Add UpdateBlueprintServiceTlsProfileRequest message and corresponding RPC for runtime TLS configuration updates. Extend RegisterBlueprintServiceProxyRequest with optional tls_profile field. * feat(auth): add TLS profile models and conversions Add TlsProfile struct to blueprint_auth::models with comprehensive TLS fields: - tls_enabled flag and require_client_mtls flag - Encrypted server cert/key, client CA bundle, upstream TLS assets - SNI, subject alt name templates, allowed DNS names - Client certificate TTL configuration Add bidirectional conversion implementations between TlsProfile and TlsProfileConfig for seamless protobuf serialization/deserialization. Add TLS-related methods to ServiceModel for profile management. * feat(bridge): update client API with TLS profile support Extend Bridge::register_blueprint_service_proxy to accept optional TlsProfile parameter. Add conversion from TlsProfile to TlsProfileConfig protobuf message. Update request construction to include TLS profile when provided. Add new update_blueprint_service_tls_profile method for runtime TLS configuration updates. Method accepts service_id and optional TlsProfile, allowing TLS enable/disable operations. Maintain full backward compatibility - existing clients without TLS continue to work unchanged. * feat(bridge): add TLS validation and update RPC to server Update register_blueprint_service_proxy to handle optional TLS profile conversion. Add comprehensive TLS validation: - Server cert/key required when TLS enabled - Client CA bundle required when mTLS enabled - Proper error messages with gRPC status codes Implement update_blueprint_service_tls_profile RPC for runtime TLS updates. Load existing service, validate new TLS profile, persist changes. Support TLS disable by passing None profile. Add extensive unit tests covering: - Valid TLS/mTLS registration scenarios - Invalid configuration rejection - TLS profile updates and disable operations - Edge cases and error conditions * feat(runner): add TLS configuration options to BlueprintEnvironment Add comprehensive TLS configuration fields to BlueprintSettings: - tls_enabled: Enable/disable TLS for service registration - tls_server_cert_path, tls_server_key_path: Server certificate files - tls_client_ca_path: Client CA bundle for mTLS validation - tls_require_client_mtls: Enforce mutual TLS authentication - tls_upstream_*: Upstream TLS configuration for proxy connections - tls_client_cert_ttl_hours: Certificate lifetime configuration - tls_sni, tls_subject_alt_name_template: Certificate validation settings - tls_allowed_dns_names: Permitted DNS names for certificates Add create_tls_profile function to load and encrypt TLS assets using envelope encryption. Add TLS envelope key loading from environment or filesystem. Integrate TLS profile creation into BlueprintEnvironment loading. Add BlueprintEnvironment.tls_profile field for runtime TLS configuration access. * feat(bridge): update dependencies for TLS envelope encryption Add blueprint-tls-envelope dependency to bridge crate for secure TLS asset encryption. Update workspace Cargo.lock with new dependency versions. Ensure TLS envelope encryption is available for bridge TLS profile handling. * docs(bridge): add gRPC mTLS implementation plan and documentation Add comprehensive implementation plan document covering: - Workstream breakdown (protobuf, client API, server logic, testing, docs) - Technical specifications and API usage examples - Migration guidance and backward compatibility notes - Security considerations and validation requirements - Release notes and completion status Document TLS configuration workflow from Blueprint to Manager pipeline. Include examples for server-only TLS and mutual TLS scenarios. Document certificate rotation and runtime TLS profile updates. * feat(runner): integrate TLS support into blueprint runner Add TLS feature flag to runner Cargo.toml enabling blueprint-auth dependency. Add TLS-related error variants to ConfigError enum for missing TLS configuration. Add TLS profile resolution and bridge update logic to runner startup. Integrate TLS profile loading and service registration in FinalizedBlueprintRunner. Add tls_profile module to bridge lib.rs for TLS profile conversions. * refactor: remove TlsAssetManager dependency from proxy and client managers * feat: improve error handling in expired certificate cleanup with detailed logging * chore: remove GRPC MTLS plan document * fix: return Result from resolve_service_id * refactor: distinguish invalid TLS config errors * fix: enforce TLS client CA bundle on profile updates * chore: simplify tls client service lookup * style: reorder imports in runner config * style: format service ID resolution in runner * fix: make client CA bundle optional when mTLS is disabled Only require client CA bundle when require_client_mtls is true, allowing TLS without mutual authentication. * Address Tjemmmic feedback: own CA PEM strings * Address Tjemmmic feedback: avoid parsing full CA bundle * Address Tjemmmic feedback: extract CA parameter builder * Address Tjemmmic feedback: factor server certificate params * Address Tjemmmic feedback: factor client certificate params * Address Tjemmmic feedback: unbiased serial generation * Address Tjemmmic feedback: organize CA types into module * Address Tjemmmic feedback: add constructors for auth models * Address Tjemmmic feedback: implement TLS chain validation * Address Tjemmmic feedback: load custom CA bundles * Address Tjemmmic feedback: wire client mTLS configuration * fix(auth): update TLS certificate handling and imports * docs: remove empty comment line in load_abi macro
1 parent 4b2e55f commit ff1674b

33 files changed

+5607
-73
lines changed

Cargo.lock

Lines changed: 52 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ futures-core = { version = "0.3.31", default-features = false }
158158
tokio = { version = "^1", default-features = false }
159159
tokio-util = { version = "^0.7", default-features = false }
160160
tokio-cron-scheduler = { version = "0.13.0", default-features = false }
161+
once_cell = { version = "1.19.0", default-features = false, features = ["std"] }
162+
x509-parser = { version = "0.18.0" }
161163
tokio-stream = { version = "0.1.15", default-features = false, features = ["net"] }
162164
pin-project-lite = "0.2.7"
163165
tower = { version = "0.5.2", default-features = false }
@@ -174,6 +176,7 @@ dotenv = { version = "0.15", default-features = false }
174176

175177
# Cryptography & Blockchain
176178
bip39 = { version = "2.2.0", default-features = false }
179+
chacha20poly1305 = { version = "0.10.1", default-features = false }
177180
ed25519-zebra = { version = "4", default-features = false }
178181
hex = { version = "0.4.3", default-features = false }
179182
k256 = { version = "0.13.3", default-features = false }
@@ -232,7 +235,11 @@ axum = { version = "0.8", default-features = false }
232235
openssl-sys = { version = "0.9.109", default-features = false }
233236
rtnetlink = { version = "0.16.0", default-features = false }
234237
ipnet = { version = "2.11.0", default-features = false }
235-
rustls = { version = "0.23", default-features = false }
238+
rustls = { version = "0.23.31", default-features = false, features = ["std"] }
239+
tokio-rustls = { version = "0.26.2", default-features = false, features = ["tls12"] }
240+
rustls-pemfile = { version = "2.2.0", default-features = false }
241+
rcgen = { version = "0.14.3", default-features = false, features = ["pem"] }
242+
hyper-rustls = { version = "0.27.7", default-features = false, features = ["http2", "ring"] }
236243
local-ip-address = "0.6.5"
237244

238245
# System & OS
@@ -277,7 +284,7 @@ num_cpus = { version = "1.17", default-features = false }
277284
libc = { version = "0.2.175", default-features = false }
278285

279286
# gRPC & Protocol Buffers
280-
tonic = { version = "0.13.1", default-features = false }
287+
tonic = { version = "0.13.1", default-features = false, features = ["tls-webpki-roots"] }
281288
prost = { version = "0.13", default-features = false }
282289
tonic-build = { version = "0.13.1", default-features = false }
283290

@@ -337,6 +344,7 @@ num-bigint = { version = "0.4.6", default-features = false }
337344
num-traits = { version = "0.2.19", default-features = false }
338345
rayon = { version = "1", default-features = false }
339346
zeroize = { version = "1.8.1", default-features = false }
347+
zerocopy = { version = "0.8", default-features = false }
340348

341349
# Eigenlayer
342350
eigensdk = { version = "0.5.0", default-features = false }

crates/auth/Cargo.toml

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,26 @@ pasetors = { workspace = true, default-features = false, features = ["v4", "serd
3131
uuid = { workspace = true, features = ["v4", "serde"] }
3232
jsonwebtoken = { workspace = true, default-features = false }
3333
pem = { workspace = true, default-features = false }
34+
chacha20poly1305 = { workspace = true, features = ["alloc", "getrandom"] }
35+
time = { workspace = true }
3436

35-
axum = { workspace = true, default-features = false, features = ["json", "form"] }
36-
hyper-util = { workspace = true, features = ["client", "client-legacy", "tokio", "http2"] }
37+
axum = { workspace = true, default-features = false, features = ["json", "form", "http1", "http2", "tokio"] }
38+
hyper-util = { workspace = true, features = ["client", "client-legacy", "tokio", "http2", "server"] }
39+
hyper = { workspace = true, features = ["full"] }
40+
hyper-rustls = { workspace = true }
41+
tokio = { workspace = true, features = ["full"] }
42+
tokio-rustls = { workspace = true, features = ["default"] }
43+
rustls = { workspace = true, features = ["default"] }
44+
rustls-pemfile = { workspace = true, features = ["std"] }
45+
rcgen = { workspace = true, features = ["crypto", "ring", "pem", "x509-parser"] }
46+
once_cell = { workspace = true }
47+
x509-parser = { workspace = true }
3748

3849
# Database
3950
rocksdb = { workspace = true, features = ["lz4"] }
4051
prost = { workspace = true, features = ["derive"] }
4152

4253
# Standalone Binary
43-
tokio = { workspace = true, features = ["full"], optional = true }
4454
tempfile = { workspace = true, optional = true }
4555

4656

@@ -59,14 +69,19 @@ tracing-subscriber = { workspace = true, features = ["fmt", "env-filter", "regis
5969
openssl = { version = "0.10", features = ["vendored"] }
6070
tokio-stream = { workspace = true }
6171
tonic = { workspace = true, features = ["codegen", "prost", "transport"] }
72+
tokio-rustls = { workspace = true }
73+
rustls = { workspace = true }
74+
rustls-pemfile = { workspace = true }
75+
rcgen = { workspace = true }
76+
hyper-rustls = { workspace = true }
6277

6378
[build-dependencies]
6479
tonic-build = { workspace = true, features = ["prost"] }
6580

6681
[features]
6782
default = ["std", "tracing"]
6883
std = ["blueprint-std/std", "crc32fast/std", "k256/std", "schnorrkel/std", "base64/std", "prost/std"]
69-
standalone = ["tokio", "tempfile", "axum/http1", "axum/http2", "axum/tokio"]
84+
standalone = ["tempfile", "axum/http1", "axum/http2", "axum/tokio"]
7085
tracing = []
7186

7287
[[bin]]

0 commit comments

Comments
 (0)