services_hardening_credential_resolution.rs (5984B)
1 #![forbid(unsafe_code)] 2 3 use serde_json::json; 4 5 const CONTRACT: &str = 6 include_str!("../contracts/services_hardening/wrapping_credential_resolution.v1.json"); 7 const LIB_SOURCE: &str = include_str!("../src/lib.rs"); 8 const MANIFEST: &str = include_str!("../Cargo.toml"); 9 const CREDENTIAL_SOURCE: &str = include_str!("../src/identity_credential.rs"); 10 const ENVELOPE_SOURCE: &str = include_str!("../src/identity_envelope.rs"); 11 const CONFIG_SCHEMA: &str = include_str!("../contracts/services_hardening/config.v1.schema.json"); 12 const CONFIG_EXAMPLE: &str = include_str!("../contracts/services_hardening/config.v1.example.toml"); 13 const HOST_SOURCE: &str = include_str!("../src/state_host.rs"); 14 15 #[test] 16 fn machine_contract_freezes_the_canonical_read_only_credential_boundary() { 17 let actual: serde_json::Value = serde_json::from_str(CONTRACT).expect("contract JSON"); 18 assert_eq!( 19 actual, 20 json!({ 21 "schema": "radroots.rhi.wrapping-credential-resolution", 22 "schema_version": 1, 23 "contract_version": 1, 24 "artifact_name": { 25 "shared_type": "ServiceCredentialArtifactName", 26 "maximum_utf8_bytes": 128 27 }, 28 "artifact_path": "<canonical_instance_secrets>/<validated_credential_name>", 29 "artifact": { 30 "wire": "raw_32_bytes", 31 "exact_bytes": 32, 32 "symlink_follow": false, 33 "regular_file": true, 34 "single_link": true, 35 "owner_uid": "effective_uid", 36 "read_modes_octal": ["0400", "0600"], 37 "secrets_root_modes_octal": ["0500", "0700"] 38 }, 39 "profiles": { 40 "service_host": "existing_injected_or_mounted", 41 "repo_local": "existing_offline_provisioned", 42 "interactive": "unsupported" 43 }, 44 "resolution": { 45 "read_existing_only": true, 46 "creates_credential": false, 47 "creates_parent": false, 48 "caller_supplies_path": false, 49 "caller_supplies_bytes": false, 50 "ordinary_run_generates": false 51 }, 52 "forbidden_sources": [ 53 "toml_secret", 54 "environment_secret", 55 "process_argument_secret", 56 "adjacent_envelope_sibling", 57 "implicit_fallback" 58 ], 59 "backup_included": false 60 }) 61 ); 62 } 63 64 #[test] 65 fn implementation_derives_only_the_shared_canonical_artifact() { 66 for required in [ 67 "binding.matches_runtime(runtime)", 68 "ServiceCredentialArtifactName::new(reference.as_str())", 69 "service_credential_artifact_path(runtime.context().paths(), &name)", 70 "load_resolved_wrapping_credential(&path)", 71 "RhiBootstrapProfileV1::ServiceHost | RhiBootstrapProfileV1::RepoLocal", 72 "pub fn resolve_rhi_wrapping_credential(", 73 ] { 74 assert!( 75 CREDENTIAL_SOURCE.contains(required), 76 "missing canonical resolution boundary {required}" 77 ); 78 } 79 assert!(LIB_SOURCE.contains("mod identity_credential;")); 80 assert!(!LIB_SOURCE.contains("pub mod identity_credential")); 81 assert!(ENVELOPE_SOURCE.contains("pub(crate) struct RhiCredentialResolutionProof")); 82 assert!(ENVELOPE_SOURCE.contains("pub(crate) fn from_resolution(")); 83 } 84 85 #[test] 86 fn no_configuration_process_sibling_or_creation_fallback_exists() { 87 let production = CREDENTIAL_SOURCE 88 .split("#[cfg(test)]") 89 .next() 90 .expect("production source"); 91 for forbidden in [ 92 "std::env::", 93 "process::Command", 94 "clap::", 95 "create_dir", 96 "create_new", 97 "OpenOptions", 98 "keyring::", 99 "with_extension(\"key\")", 100 "set_var(", 101 "var_os(", 102 ] { 103 assert!( 104 !production.contains(forbidden), 105 "forbidden credential authority {forbidden}" 106 ); 107 } 108 for source in [CONFIG_SCHEMA, CONFIG_EXAMPLE] { 109 for forbidden in [ 110 "wrapping_credential =", 111 "credential_bytes", 112 "credential_hex", 113 ] { 114 assert!(!source.contains(forbidden)); 115 } 116 } 117 } 118 119 #[test] 120 fn state_host_remains_credential_free_and_prototypes_are_removed() { 121 for forbidden in [ 122 "resolve_rhi_wrapping_credential", 123 "RhiWrappingCredential", 124 "identity_credential", 125 "service_wrapping_key", 126 ] { 127 assert!(!HOST_SOURCE.contains(forbidden)); 128 } 129 for forbidden in [ 130 "pub mod host_identity", 131 "pub mod identity_storage", 132 "LEGACY_ENVELOPE_VERSION", 133 "LegacyV1", 134 "encrypt_secret_key_ncryptsec", 135 "secret_key_hex", 136 "rand::random", 137 ] { 138 assert!(!LIB_SOURCE.contains(forbidden)); 139 } 140 let source_root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src"); 141 assert!(!source_root.join("host_identity.rs").exists()); 142 assert!(!source_root.join("identity_storage.rs").exists()); 143 for removed_dependency in [ 144 "radroots_identity =", 145 "rand = { version = \"0.9\"", 146 "features = [\"nip49\"]", 147 ] { 148 assert!(!MANIFEST.contains(removed_dependency)); 149 } 150 } 151 152 #[test] 153 fn public_errors_are_source_path_and_dependency_free() { 154 for required in [ 155 "pub enum RhiCredentialResolutionErrorKind", 156 "pub struct RhiCredentialResolutionError", 157 "impl Error for RhiCredentialResolutionError {}", 158 ] { 159 assert!(CREDENTIAL_SOURCE.contains(required)); 160 } 161 for forbidden in [ 162 "pub path:", 163 "pub source:", 164 "pub credential:", 165 "pub fn credential_path", 166 "pub fn from_resolved_bytes", 167 "pub fn from_resolution", 168 "radroots_runtime_paths::ServiceCredentialArtifactNameError", 169 "rustix::", 170 ] { 171 assert!(!LIB_SOURCE.contains(forbidden)); 172 } 173 }