myc

Self-custodial remote signer for Radroots apps
git clone https://radroots.dev/git/myc.git
Log | Files | Refs | README | LICENSE

services_hardening_credential_resolution.rs (5331B)


      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 CREDENTIAL_SOURCE: &str = include_str!("../src/provider_credential.rs");
      9 const ENVELOPE_SOURCE: &str = include_str!("../src/provider_envelope.rs");
     10 const CONFIG_SCHEMA: &str = include_str!("../contracts/services_hardening/config.v1.schema.json");
     11 const CONFIG_EXAMPLE: &str = include_str!("../contracts/services_hardening/config.v1.example.toml");
     12 const HOST_SOURCE: &str = include_str!("../src/state_host.rs");
     13 const MAINTENANCE_SOURCE: &str = include_str!("../src/state_maintenance.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.myc.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         "ServiceCredentialArtifactName::new(reference.as_str())",
     68         "service_credential_artifact_path(runtime.context().paths(), &name)",
     69         "load_resolved_wrapping_credential(&path)",
     70         "MycBootstrapProfileV1::ServiceHost | MycBootstrapProfileV1::RepoLocal",
     71         "pub fn resolve_myc_wrapping_credential(",
     72     ] {
     73         assert!(
     74             CREDENTIAL_SOURCE.contains(required),
     75             "missing canonical resolution boundary {required}"
     76         );
     77     }
     78     assert!(LIB_SOURCE.contains("mod provider_credential;"));
     79     assert!(!LIB_SOURCE.contains("pub mod provider_credential"));
     80     assert!(ENVELOPE_SOURCE.contains("pub(crate) struct MycCredentialResolutionProof"));
     81     assert!(ENVELOPE_SOURCE.contains("pub(crate) fn from_resolution("));
     82 }
     83 
     84 #[test]
     85 fn no_configuration_process_sibling_or_creation_fallback_exists() {
     86     let production = CREDENTIAL_SOURCE
     87         .split("#[cfg(test)]")
     88         .next()
     89         .expect("production source");
     90     for forbidden in [
     91         "std::env::",
     92         "process::Command",
     93         "clap::",
     94         "create_dir",
     95         "create_new",
     96         "OpenOptions",
     97         "keyring::",
     98         "with_extension(\"key\")",
     99         "set_var(",
    100         "var_os(",
    101     ] {
    102         assert!(
    103             !production.contains(forbidden),
    104             "forbidden credential authority {forbidden}"
    105         );
    106     }
    107     for source in [CONFIG_SCHEMA, CONFIG_EXAMPLE] {
    108         for forbidden in [
    109             "wrapping_credential =",
    110             "credential_bytes",
    111             "credential_hex",
    112         ] {
    113             assert!(!source.contains(forbidden));
    114         }
    115     }
    116 }
    117 
    118 #[test]
    119 fn state_backup_and_runtime_sources_remain_credential_free() {
    120     for source in [HOST_SOURCE, MAINTENANCE_SOURCE] {
    121         for forbidden in [
    122             "resolve_myc_wrapping_credential",
    123             "MycWrappingCredential",
    124             "provider_credential",
    125             "transport_wrapping_key",
    126         ] {
    127             assert!(!source.contains(forbidden));
    128         }
    129     }
    130 }
    131 
    132 #[test]
    133 fn public_errors_are_source_path_and_dependency_free() {
    134     for required in [
    135         "pub enum MycCredentialResolutionErrorKind",
    136         "pub struct MycCredentialResolutionError",
    137         "impl Error for MycCredentialResolutionError {}",
    138     ] {
    139         assert!(CREDENTIAL_SOURCE.contains(required));
    140     }
    141     for forbidden in [
    142         "pub path:",
    143         "pub source:",
    144         "pub credential:",
    145         "pub fn credential_path",
    146         "pub fn from_resolved_bytes",
    147         "pub fn from_resolution",
    148         "radroots_runtime_paths::ServiceCredentialArtifactNameError",
    149         "rustix::",
    150     ] {
    151         assert!(!LIB_SOURCE.contains(forbidden));
    152     }
    153 }