From 23c2085bcfcd5f516ab02916c98394b440fda043 Mon Sep 17 00:00:00 2001 From: Max Malkin Date: Sun, 1 Mar 2026 17:58:14 -0700 Subject: [PATCH 1/2] apply cargo fmt formatting fixes across workspace --- crates/py/src/lib.rs | 5 +- crates/registry/src/handlers/agents.rs | 4 +- crates/registry/src/handlers/grants.rs | 4 +- services/registry/src/main.rs | 2 +- services/registry/src/signing.rs | 2 +- services/verifier/src/handlers.rs | 2 +- services/verifier/src/main.rs | 2 +- tests/compliance/audit_integrity.rs | 38 +++++--------- tests/compliance/behavioral_envelope.rs | 5 +- tests/compliance/capability_boundary.rs | 66 ++++++++++--------------- tests/compliance/dpop_binding.rs | 6 ++- tests/compliance/main.rs | 6 +-- tests/compliance/nonce_replay.rs | 26 ++-------- tests/compliance/token_security.rs | 34 ++++++------- 14 files changed, 78 insertions(+), 124 deletions(-) diff --git a/crates/py/src/lib.rs b/crates/py/src/lib.rs index 1e5273c..3440e53 100644 --- a/crates/py/src/lib.rs +++ b/crates/py/src/lib.rs @@ -410,7 +410,10 @@ impl PyAgentAuthClient { // Convert headers to a HashMap to return to Python let mut result: HashMap = HashMap::new(); for (key, value) in &headers { - result.insert(key.as_str().to_string(), value.to_str().unwrap_or("").to_string()); + result.insert( + key.as_str().to_string(), + value.to_str().unwrap_or("").to_string(), + ); } Ok(result) }) diff --git a/crates/registry/src/handlers/agents.rs b/crates/registry/src/handlers/agents.rs index 97cac60..9d2b8dc 100644 --- a/crates/registry/src/handlers/agents.rs +++ b/crates/registry/src/handlers/agents.rs @@ -152,9 +152,7 @@ pub async fn bootstrap_agent( // Sign the manifest using the registry's signing backend let signature = state .signer - .sign(&auth_core::crypto::manifest_signing_bytes( - &req.manifest, - )) + .sign(&auth_core::crypto::manifest_signing_bytes(&req.manifest)) .await .map_err(|e| RegistryError::Internal(format!("failed to sign manifest: {e}")))?; diff --git a/crates/registry/src/handlers/grants.rs b/crates/registry/src/handlers/grants.rs index afad665..3dff1cb 100644 --- a/crates/registry/src/handlers/grants.rs +++ b/crates/registry/src/handlers/grants.rs @@ -3,9 +3,7 @@ use crate::error::{RegistryError, Result}; use crate::services::{AuditEvent, AuditEventType}; use crate::state::AppState; -use auth_core::{ - AgentId, BehavioralEnvelope, Capability, CapabilityGrant, GrantId, GrantStatus, -}; +use auth_core::{AgentId, BehavioralEnvelope, Capability, CapabilityGrant, GrantId, GrantStatus}; use axum::{ extract::{Path, State}, http::StatusCode, diff --git a/services/registry/src/main.rs b/services/registry/src/main.rs index 4c0a0a0..9239162 100644 --- a/services/registry/src/main.rs +++ b/services/registry/src/main.rs @@ -7,6 +7,7 @@ mod signing; +use axum::middleware; use registry::{ config::RegistryConfig, db::DbPool, @@ -15,7 +16,6 @@ use registry::{ services::{AuditService, CacheService, GrantService, TokenService}, state::{AppState, HealthState}, }; -use axum::middleware; use std::net::SocketAddr; use std::sync::Arc; use tokio::net::TcpListener; diff --git a/services/registry/src/signing.rs b/services/registry/src/signing.rs index 34777fb..e5e6e30 100644 --- a/services/registry/src/signing.rs +++ b/services/registry/src/signing.rs @@ -6,8 +6,8 @@ use auth_core::crypto::{Ed25519PublicKey, Signature, SigningBackend}; use auth_core::error::CryptoError; -use registry::config::KmsBackend; use base64::Engine; +use registry::config::KmsBackend; use reqwest::Client; use serde::{Deserialize, Serialize}; use std::sync::Arc; diff --git a/services/verifier/src/handlers.rs b/services/verifier/src/handlers.rs index acae22c..ae9d4f2 100644 --- a/services/verifier/src/handlers.rs +++ b/services/verifier/src/handlers.rs @@ -2,9 +2,9 @@ use crate::state::VerifierState; use auth_core::TokenId; -use registry::db; use axum::{extract::State, http::StatusCode, response::IntoResponse, Json}; use chrono::Utc; +use registry::db; use serde::{Deserialize, Serialize}; use std::time::Duration; use tracing::{info, warn}; diff --git a/services/verifier/src/main.rs b/services/verifier/src/main.rs index fe758e1..134ce86 100644 --- a/services/verifier/src/main.rs +++ b/services/verifier/src/main.rs @@ -19,12 +19,12 @@ mod state; use crate::config::VerifierConfig; use crate::handlers::{get_keys, liveness, metrics_handler, readiness, startup, verify_token}; use crate::state::{HealthState, VerifierState}; -use registry::services::CacheService; use axum::{ middleware, routing::{get, post}, Router, }; +use registry::services::CacheService; use std::net::SocketAddr; use std::sync::Arc; use tokio::net::TcpListener; diff --git a/tests/compliance/audit_integrity.rs b/tests/compliance/audit_integrity.rs index d5202f8..8e02088 100644 --- a/tests/compliance/audit_integrity.rs +++ b/tests/compliance/audit_integrity.rs @@ -31,7 +31,13 @@ impl AuditEvent { let event_id = Uuid::now_v7(); let timestamp = Utc::now(); - let content = Self::content_bytes(&event_id, &service_provider_id, &agent_id, action, ×tamp); + let content = Self::content_bytes( + &event_id, + &service_provider_id, + &agent_id, + action, + ×tamp, + ); let row_hash = hash_chain_event(&previous_hash, &content); Self { @@ -184,10 +190,7 @@ fn test_tampered_row_hash_detected() { // Tamper with the row hash chain.events[0].row_hash[0] ^= 0xFF; - assert!( - !chain.verify_chain(), - "tampered row_hash MUST be detected" - ); + assert!(!chain.verify_chain(), "tampered row_hash MUST be detected"); } /// COMPLIANCE: Inserted event MUST break the chain. @@ -213,10 +216,7 @@ fn test_inserted_event_breaks_chain() { chain.events.insert(1, fake_event); - assert!( - !chain.verify_chain(), - "inserted event MUST break the chain" - ); + assert!(!chain.verify_chain(), "inserted event MUST break the chain"); } /// COMPLIANCE: Deleted event MUST break the chain. @@ -233,10 +233,7 @@ fn test_deleted_event_breaks_chain() { // Remove the middle event chain.events.remove(1); - assert!( - !chain.verify_chain(), - "deleted event MUST break the chain" - ); + assert!(!chain.verify_chain(), "deleted event MUST break the chain"); } /// COMPLIANCE: Reordered events MUST break the chain. @@ -404,10 +401,7 @@ fn test_hash_chain_deterministic() { let hash1 = hash_chain_event(&previous, content); let hash2 = hash_chain_event(&previous, content); - assert_eq!( - hash1, hash2, - "hash_chain_event MUST be deterministic" - ); + assert_eq!(hash1, hash2, "hash_chain_event MUST be deterministic"); } /// COMPLIANCE: Constant time comparison is used for hashes. @@ -431,10 +425,7 @@ fn test_constant_time_eq_for_hashes() { #[test] fn test_empty_chain_valid() { let chain = AuditChain::new(); - assert!( - chain.verify_chain(), - "empty audit chain MUST be valid" - ); + assert!(chain.verify_chain(), "empty audit chain MUST be valid"); } /// COMPLIANCE: Single event chain is valid. @@ -446,8 +437,5 @@ fn test_single_event_chain_valid() { chain.append(sp_id, agent_id, "single_event"); - assert!( - chain.verify_chain(), - "single event chain MUST be valid" - ); + assert!(chain.verify_chain(), "single event chain MUST be valid"); } diff --git a/tests/compliance/behavioral_envelope.rs b/tests/compliance/behavioral_envelope.rs index 4b9910e..1812874 100644 --- a/tests/compliance/behavioral_envelope.rs +++ b/tests/compliance/behavioral_envelope.rs @@ -159,10 +159,7 @@ fn test_zero_session_duration_rejected() { fn test_valid_envelope_accepted() { let valid = BehavioralEnvelope::default_restrictive(); - assert!( - valid.validate().is_ok(), - "valid envelope MUST be accepted" - ); + assert!(valid.validate().is_ok(), "valid envelope MUST be accepted"); } /// COMPLIANCE: Envelope with requires_human_online MUST block when human offline. diff --git a/tests/compliance/capability_boundary.rs b/tests/compliance/capability_boundary.rs index 90dafa1..163cf8f 100644 --- a/tests/compliance/capability_boundary.rs +++ b/tests/compliance/capability_boundary.rs @@ -3,8 +3,8 @@ //! Verifies that agents cannot request or use capabilities beyond their manifest. use auth_core::types::{ - AgentAccessToken, AgentId, AgentManifest, BehavioralEnvelope, Capability, - HumanPrincipalId, ServiceProviderId, TokenId, + AgentAccessToken, AgentId, AgentManifest, BehavioralEnvelope, Capability, HumanPrincipalId, + ServiceProviderId, TokenId, }; use chrono::Utc; use std::collections::HashMap; @@ -42,34 +42,28 @@ fn create_test_token(capabilities: Vec) -> AgentAccessToken { } /// Checks if requested capabilities are a subset of manifest capabilities. -fn capabilities_within_manifest( - requested: &[Capability], - manifest: &AgentManifest, -) -> bool { +fn capabilities_within_manifest(requested: &[Capability], manifest: &AgentManifest) -> bool { requested.iter().all(|req| { - manifest.capabilities_requested.iter().any(|m| { - req.capability_type() == m.capability_type() && req.resource() == m.resource() - }) + manifest + .capabilities_requested + .iter() + .any(|m| req.capability_type() == m.capability_type() && req.resource() == m.resource()) }) } /// COMPLIANCE: Agent cannot request capabilities beyond manifest. #[test] fn test_cannot_request_beyond_manifest() { - let manifest = create_test_manifest(vec![ - Capability::Read { - resource: "calendar".to_string(), - filter: None, - }, - ]); + let manifest = create_test_manifest(vec![Capability::Read { + resource: "calendar".to_string(), + filter: None, + }]); // Try to request write capability (not in manifest) - let requested = vec![ - Capability::Write { - resource: "calendar".to_string(), - conditions: None, - }, - ]; + let requested = vec![Capability::Write { + resource: "calendar".to_string(), + conditions: None, + }]; assert!( !capabilities_within_manifest(&requested, &manifest), @@ -92,12 +86,10 @@ fn test_can_request_within_manifest() { ]); // Request only read (subset of manifest) - let requested = vec![ - Capability::Read { - resource: "calendar".to_string(), - filter: None, - }, - ]; + let requested = vec![Capability::Read { + resource: "calendar".to_string(), + filter: None, + }]; assert!( capabilities_within_manifest(&requested, &manifest), @@ -108,20 +100,16 @@ fn test_can_request_within_manifest() { /// COMPLIANCE: Agent cannot request capabilities for different resource. #[test] fn test_cannot_request_different_resource() { - let manifest = create_test_manifest(vec![ - Capability::Read { - resource: "calendar".to_string(), - filter: None, - }, - ]); + let manifest = create_test_manifest(vec![Capability::Read { + resource: "calendar".to_string(), + filter: None, + }]); // Try to request same capability type but different resource - let requested = vec![ - Capability::Read { - resource: "email".to_string(), - filter: None, - }, - ]; + let requested = vec![Capability::Read { + resource: "email".to_string(), + filter: None, + }]; assert!( !capabilities_within_manifest(&requested, &manifest), diff --git a/tests/compliance/dpop_binding.rs b/tests/compliance/dpop_binding.rs index 9671c85..b12c1e3 100644 --- a/tests/compliance/dpop_binding.rs +++ b/tests/compliance/dpop_binding.rs @@ -107,7 +107,11 @@ fn test_proof_with_access_token_binding() { let access_token = "eyJhbGciOiJFZDI1NTE5IiwidHlwIjoiSldUIn0.test.signature"; let proof_with_token = generator - .generate("POST", "https://api.example.com/resource", Some(access_token)) + .generate( + "POST", + "https://api.example.com/resource", + Some(access_token), + ) .expect("create proof with ath"); let proof_without_token = generator diff --git a/tests/compliance/main.rs b/tests/compliance/main.rs index dcf2f60..88562a3 100644 --- a/tests/compliance/main.rs +++ b/tests/compliance/main.rs @@ -8,9 +8,9 @@ //! - Capability boundaries are enforced //! - Audit log integrity is maintained -mod token_security; +mod audit_integrity; mod behavioral_envelope; +mod capability_boundary; mod dpop_binding; mod nonce_replay; -mod capability_boundary; -mod audit_integrity; +mod token_security; diff --git a/tests/compliance/nonce_replay.rs b/tests/compliance/nonce_replay.rs index 5bd5e73..b0e8fd3 100644 --- a/tests/compliance/nonce_replay.rs +++ b/tests/compliance/nonce_replay.rs @@ -13,10 +13,7 @@ fn test_nonce_uniqueness() { // Generate 10,000 nonces and verify all are unique for _ in 0..10_000 { let nonce = generate_nonce(); - assert!( - nonces.insert(nonce), - "generated nonces MUST be unique" - ); + assert!(nonces.insert(nonce), "generated nonces MUST be unique"); } } @@ -24,11 +21,7 @@ fn test_nonce_uniqueness() { #[test] fn test_nonce_length() { let nonce = generate_nonce(); - assert_eq!( - nonce.len(), - 32, - "nonce MUST be exactly 32 bytes" - ); + assert_eq!(nonce.len(), 32, "nonce MUST be exactly 32 bytes"); } /// COMPLIANCE: Nonces MUST have sufficient entropy. @@ -38,17 +31,11 @@ fn test_nonce_entropy() { // Check that the nonce is not all zeros let all_zeros = nonce.iter().all(|&b| b == 0); - assert!( - !all_zeros, - "nonce MUST have entropy (not all zeros)" - ); + assert!(!all_zeros, "nonce MUST have entropy (not all zeros)"); // Check that the nonce is not all ones let all_ones = nonce.iter().all(|&b| b == 0xFF); - assert!( - !all_ones, - "nonce MUST have entropy (not all ones)" - ); + assert!(!all_ones, "nonce MUST have entropy (not all ones)"); // Check that we have reasonable byte diversity let unique_bytes: HashSet = nonce.iter().copied().collect(); @@ -101,10 +88,7 @@ fn test_nonce_replay_detection() { "replayed nonce MUST be detected" ); - assert!( - store.is_used(&nonce), - "used nonce MUST be tracked" - ); + assert!(store.is_used(&nonce), "used nonce MUST be tracked"); } /// COMPLIANCE: Different nonces MUST be allowed. diff --git a/tests/compliance/token_security.rs b/tests/compliance/token_security.rs index 7df1ac1..66b965b 100644 --- a/tests/compliance/token_security.rs +++ b/tests/compliance/token_security.rs @@ -4,8 +4,8 @@ use auth_core::crypto::{constant_time_eq, sha256}; use auth_core::types::{ - AgentAccessToken, AgentId, BehavioralEnvelope, Capability, HumanPrincipalId, - ServiceProviderId, TokenId, + AgentAccessToken, AgentId, BehavioralEnvelope, Capability, HumanPrincipalId, ServiceProviderId, + TokenId, }; use chrono::Utc; @@ -119,10 +119,7 @@ fn test_token_canonical_bytes_deterministic() { let bytes1 = token.to_canonical_bytes().expect("serialize 1"); let bytes2 = token.to_canonical_bytes().expect("serialize 2"); - assert_eq!( - bytes1, bytes2, - "canonical bytes MUST be deterministic" - ); + assert_eq!(bytes1, bytes2, "canonical bytes MUST be deterministic"); } /// COMPLIANCE: Token hash changes when any claim is modified. @@ -144,14 +141,20 @@ fn test_token_hash_changes_with_any_modification() { token3.granted_capabilities = vec![]; let bytes3 = token3.to_canonical_bytes().expect("serialize"); let hash3 = sha256(&bytes3); - assert_ne!(hash1, hash3, "changed capabilities MUST produce different hash"); + assert_ne!( + hash1, hash3, + "changed capabilities MUST produce different hash" + ); // Test service_provider_id change let mut token4 = token1.clone(); token4.service_provider_id = ServiceProviderId::new(); let bytes4 = token4.to_canonical_bytes().expect("serialize"); let hash4 = sha256(&bytes4); - assert_ne!(hash1, hash4, "changed service_provider_id MUST produce different hash"); + assert_ne!( + hash1, hash4, + "changed service_provider_id MUST produce different hash" + ); } /// COMPLIANCE: Constant-time comparison is used for hashes. @@ -184,10 +187,7 @@ fn test_expired_token_rejected() { token.issued_at = now - chrono::Duration::hours(1); token.expires_at = now - chrono::Duration::minutes(1); - assert!( - token.validate().is_err(), - "expired token MUST be rejected" - ); + assert!(token.validate().is_err(), "expired token MUST be rejected"); } /// COMPLIANCE: Token validation rejects tokens with empty capabilities. @@ -207,10 +207,7 @@ fn test_empty_capabilities_rejected() { fn test_valid_token_accepted() { let token = create_valid_token(); - assert!( - token.validate().is_ok(), - "valid token MUST be accepted" - ); + assert!(token.validate().is_ok(), "valid token MUST be accepted"); } /// COMPLIANCE: Token JTI (jti) MUST be unique. @@ -219,8 +216,5 @@ fn test_token_jti_unique() { let token1 = create_valid_token(); let token2 = create_valid_token(); - assert_ne!( - token1.jti, token2.jti, - "each token MUST have a unique JTI" - ); + assert_ne!(token1.jti, token2.jti, "each token MUST have a unique JTI"); } From 2e19c385843c2b97e0414021810bea3c84707816 Mon Sep 17 00:00:00 2001 From: Max Malkin Date: Sun, 1 Mar 2026 17:58:38 -0700 Subject: [PATCH 2/2] add license field to compliance-tests crate to pass cargo-deny --- tests/compliance/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/compliance/Cargo.toml b/tests/compliance/Cargo.toml index 0b35f2b..ea0308b 100644 --- a/tests/compliance/Cargo.toml +++ b/tests/compliance/Cargo.toml @@ -2,6 +2,7 @@ name = "compliance-tests" version = "0.1.0" edition = "2021" +license = "MIT OR Apache-2.0" publish = false [[test]]