services_hardening_encrypted_envelope.rs (5244B)
1 use serde_json::json; 2 3 const CONTRACT: &str = 4 include_str!("../contracts/services_hardening/encrypted_identity_envelope.v1.json"); 5 const LIB_SOURCE: &str = include_str!("../src/lib.rs"); 6 const ENVELOPE_SOURCE: &str = include_str!("../src/provider_envelope.rs"); 7 const HOST_SOURCE: &str = include_str!("../src/state_host.rs"); 8 const MAINTENANCE_SOURCE: &str = include_str!("../src/state_maintenance.rs"); 9 10 #[test] 11 fn machine_contract_freezes_the_exact_envelope_and_backup_boundary() { 12 let actual: serde_json::Value = serde_json::from_str(CONTRACT).expect("contract JSON"); 13 assert_eq!( 14 actual, 15 json!({ 16 "schema": "radroots.myc.encrypted-identity-envelope", 17 "schema_version": 1, 18 "contract_version": 1, 19 "radroots_secrets_envelope_version": 2, 20 "encoded_max_bytes": 262144, 21 "identity_secret_bytes": 32, 22 "wrapping_credential_bytes": 32, 23 "provisioning_entropy": { 24 "data_key_bytes": 32, 25 "envelope_nonce_bytes": 24, 26 "wrapping_nonce_bytes": 24, 27 "caller_supplied": true 28 }, 29 "authenticated_context": { 30 "purpose": "radroots.myc.encrypted_identity", 31 "subject_type": "provider_identity", 32 "subject_value": "<role>:<expected_public_key>", 33 "payload_schema": "radroots.myc.identity_secret.v1", 34 "credential_reference_bound": true 35 }, 36 "artifact": { 37 "create_new": true, 38 "overwrite": false, 39 "symlink_follow": false, 40 "regular_file": true, 41 "single_link": true, 42 "owner_uid": "effective_uid", 43 "create_mode_octal": "0600", 44 "read_modes_octal": ["0400", "0600"] 45 }, 46 "verification": { 47 "expected_identity_required": true, 48 "derived_public_key_must_match": true, 49 "legacy_envelope_accepted": false, 50 "ordinary_run_provisions": false 51 }, 52 "backup": { 53 "state_backup_includes_envelope": false, 54 "state_backup_includes_wrapping_credential": false, 55 "state_backup_includes_plaintext_identity": false 56 } 57 }) 58 ); 59 } 60 61 #[test] 62 fn implementation_uses_the_shared_envelope_and_keeps_secret_resolution_sealed() { 63 for required in [ 64 "EncryptedEnvelope::seal(", 65 "EncryptedEnvelope::decode(", 66 ".open(&opener, expected_context)", 67 "binding.role().as_str()", 68 "OFlags::CREATE", 69 "OFlags::EXCL", 70 "OFlags::NOFOLLOW", 71 "Mode::RUSR | Mode::WUSR", 72 "derived_public_key_must_match", 73 ] { 74 assert!( 75 ENVELOPE_SOURCE.contains(required) || CONTRACT.contains(required), 76 "missing envelope boundary {required}" 77 ); 78 } 79 for forbidden in [ 80 "pub fn from_resolved_bytes", 81 "pub fn from_bytes", 82 "std::env::", 83 "process::Command", 84 "keyring::", 85 "LEGACY_ENVELOPE_VERSION", 86 "open_legacy_v1", 87 "reseal_legacy_v1", 88 ".key\"", 89 "create_dir_all", 90 ] { 91 assert!( 92 !ENVELOPE_SOURCE.contains(forbidden), 93 "forbidden envelope authority {forbidden}" 94 ); 95 } 96 assert!(LIB_SOURCE.contains("mod provider_envelope;")); 97 assert!(!LIB_SOURCE.contains("pub mod provider_envelope")); 98 } 99 100 #[test] 101 fn service_state_backup_remains_a_single_database_without_provider_material() { 102 assert!(HOST_SOURCE.contains(".capture_online_backup(staging_directory, created_at)")); 103 assert!(MAINTENANCE_SOURCE.contains("verify_backup_bundle(")); 104 for source in [HOST_SOURCE, MAINTENANCE_SOURCE] { 105 for forbidden in [ 106 "provider_envelope", 107 "identity.ncrypt", 108 "MycWrappingCredential", 109 "MycDecryptedIdentity", 110 ] { 111 assert!( 112 !source.contains(forbidden), 113 "state backup must exclude {forbidden}" 114 ); 115 } 116 } 117 } 118 119 #[test] 120 fn public_error_and_protected_types_are_dependency_and_path_free() { 121 for required in [ 122 "pub enum MycEncryptedIdentityEnvelopeErrorKind", 123 "pub struct MycEncryptedIdentityEnvelopeError", 124 "pub struct MycWrappingCredential(", 125 "pub struct MycEncryptedIdentityProvisioningMaterial", 126 "pub struct MycDecryptedIdentity", 127 "formatter.write_str(\"MycWrappingCredential([redacted])\")", 128 "impl Error for MycEncryptedIdentityEnvelopeError {}", 129 ] { 130 assert!( 131 ENVELOPE_SOURCE.contains(required), 132 "missing boundary {required}" 133 ); 134 } 135 for forbidden in [ 136 "pub path:", 137 "pub source:", 138 "pub credential:", 139 "pub secret:", 140 "pub data_key:", 141 "pub envelope_nonce:", 142 "pub wrapping_nonce:", 143 "pub fn expose_secret", 144 "pub fn encrypted_envelope_path", 145 "pub struct MycCredentialResolutionProof", 146 "pub fn from_resolution", 147 ] { 148 assert!(!ENVELOPE_SOURCE.contains(forbidden)); 149 } 150 }