Repository: mozilla/cargo-vet
Pull request #382 (2023-01-20 20:03:05)

Replace dependency-criteria on audits with policy criteria
This patch removes dependency-criteria from the UI as something which can be added to audits and exemptions. Instead, we now support adding dependency-criteria to policy entries for third-party crates.

This will enable large simplifications to the core resolver in the future, however those have not been implemented in this patch, nor have potential improvements around the reliability of suggestions. This patch just support for the feature, and adds support for policy entries.

Before the next release, we should require that policy entries for third-party crates be versioned, however that has not yet been implemented in this patch.


Patch:
diff --git a/src/cli.rs b/src/cli.rs
index 00ef30b..fdb7c07 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -458,11 +458,6 @@ pub struct CertifyArgs {
     /// If not provided, we will prompt you for this information.
     #[clap(long, action)]
     pub criteria: Vec<CriteriaName>,
-    /// The dependency-criteria to require for this audit to be valid
-    ///
-    /// If not provided, we will still implicitly require dependencies to satisfy `criteria`.
-    #[clap(long, action)]
-    pub dependency_criteria: Vec<DependencyCriteriaArg>,
     /// Who to name as the auditor
     ///
     /// If not provided, we will collect this information from the local git.
@@ -530,11 +525,6 @@ pub struct AddExemptionArgs {
     /// If not provided, we will prompt you for this information.
     #[clap(long, action)]
     pub criteria: Vec<CriteriaName>,
-    /// The dependency-criteria to require for this exemption to be valid
-    ///
-    /// If not provided, we will still implicitly require dependencies to satisfy `criteria`.
-    #[clap(long, action)]
-    pub dependency_criteria: Vec<DependencyCriteriaArg>,
     /// A free-form string to include with the new forbid entry
     ///
     /// If not provided, there will be no notes.
diff --git a/src/format.rs b/src/format.rs
index 1bb60e6..354e326 100644
--- a/src/format.rs
+++ b/src/format.rs
@@ -279,30 +279,11 @@ impl cmp::Ord for AuditEntry {
 
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
 pub enum AuditKind {
-    Full {
-        version: VetVersion,
-        dependency_criteria: DependencyCriteria,
-    },
-    Delta {
-        from: VetVersion,
-        to: VetVersion,
-        dependency_criteria: DependencyCriteria,
-    },
-    Violation {
-        violation: VersionReq,
-    },
+    Full { version: VetVersion },
+    Delta { from: VetVersion, to: VetVersion },
+    Violation { violation: VersionReq },
 }
 
-/// A list of criteria that transitive dependencies must satisfy for this
-/// audit to continue to be considered valid.
-///
-/// Example:
-///
-/// ```toml
-/// dependency_criteria = { hmac: ['secure', 'crypto_reviewed'] }
-/// ```
-pub type DependencyCriteria = SortedMap<PackageName, Vec<Spanned<CriteriaName>>>;
-
 /// A "VERSION" or "VERSION -> VERSION"
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Delta {
@@ -476,6 +457,16 @@ pub struct PolicyEntry {
     pub notes: Option<String>,
 }
 
+/// A list of criteria that transitive dependencies must satisfy for this
+/// policy to be satisfied.
+///
+/// Example:
+///
+/// ```toml
+/// dependency_criteria = { hmac = ['secure', 'crypto_reviewed'] }
+/// ```
+pub type DependencyCriteria = SortedMap<PackageName, Vec<Spanned<CriteriaName>>>;
+
 pub static DEFAULT_POLICY_CRITERIA: CriteriaStr = SAFE_TO_DEPLOY;
 pub static DEFAULT_POLICY_DEV_CRITERIA: CriteriaStr = SAFE_TO_RUN;
 
@@ -521,14 +512,6 @@ pub struct ExemptedDependency {
     #[serde(default = "get_default_exemptions_suggest")]
     #[serde(skip_serializing_if = "is_default_exemptions_suggest")]
     pub suggest: bool,
-    /// Custom criteria for an exempted crate's dependencies.
-    ///
-    /// Any dependency edge that isn't explicitly specified defaults to `criteria`.
-    #[serde(rename = "dependency-criteria")]
-    #[serde(skip_serializing_if = "DependencyCriteria::is_empty")]
-    #[serde(with = "serialization::dependency_criteria")]
-    #[serde(default)]
-    pub dependency_criteria: DependencyCriteria,
     /// Freeform notes, put whatever you want here. Just more stable/reliable than comments.
     pub notes: Option<String>,
 }
diff --git a/src/main.rs b/src/main.rs
index 4e07368..143287c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -36,9 +36,8 @@ use crate::errors::{
     SourceFile,
 };
 use crate::format::{
-    AuditEntry, AuditKind, AuditsFile, ConfigFile, CriteriaEntry, DependencyCriteria,
-    ExemptedDependency, FetchCommand, ImportsFile, MetaConfig, MetaConfigInstance, PackageStr,
-    SortedMap, StoreInfo, VetVersion,
+    AuditEntry, AuditKind, AuditsFile, ConfigFile, CriteriaEntry, ExemptedDependency, FetchCommand,
+    ImportsFile, MetaConfig, MetaConfigInstance, PackageStr, SortedMap, StoreInfo, VetVersion,
 };
 use crate::git_tool::Pager;
 use crate::out::{indeterminate_spinner, Out, StderrLogWriter, MULTIPROGRESS};
@@ -522,7 +521,6 @@ pub fn init_files(
             let item = ExemptedDependency {
                 version: package.version.clone(),
                 criteria,
-                dependency_criteria: DependencyCriteria::new(),
                 notes: None,
                 suggest: true,
             };
@@ -696,20 +694,6 @@ fn do_cmd_certify(
         return Err(CertifyError::NotAPackage(package));
     }
 
-    let dependency_criteria = if sub_args.dependency_criteria.is_empty() {
-        // TODO: look at the current audits to infer this? prompt?
-        DependencyCriteria::new()
-    } else {
-        let mut dep_criteria = DependencyCriteria::new();
-        for arg in &sub_args.dependency_criteria {
-            dep_criteria
-                .entry(arg.dependency.clone())
-                .or_insert_with(Vec::new)
-                .push(arg.criteria.clone().into());
-        }
-        dep_criteria
-    };
-
     let kind = if let Some(v1) = &sub_args.version1 {
         // If explicit versions were provided, use those
         if let Some(v2) = &sub_args.version2 {
@@ -717,28 +701,22 @@ fn do_cmd_certify(
             AuditKind::Delta {
                 from: v1.clone(),
                 to: v2.clone(),
-                dependency_criteria,
             }
         } else {
             // This is a full audit
             AuditKind::Full {
                 version: v1.clone(),
-                dependency_criteria,
             }
         }
     } else if let Some(fetch) = last_fetch.filter(|f| f.package() == package) {
         // Otherwise, is we just fetched this package, use the version(s) we fetched
         match fetch {
-            FetchCommand::Inspect { version, .. } => AuditKind::Full {
-                version,
-                dependency_criteria,
-            },
+            FetchCommand::Inspect { version, .. } => AuditKind::Full { version },
             FetchCommand::Diff {
                 version1, version2, ..
             } => AuditKind::Delta {
                 from: version1,
                 to: version2,
-                dependency_criteria,
             },
         }
     } else {
@@ -1224,20 +1202,6 @@ fn cmd_add_exemption(
     // Add an exemption entry
     let mut store = Store::acquire_offline(cfg)?;
 
-    let dependency_criteria = if sub_args.dependency_criteria.is_empty() {
-        // TODO: look at the current audits to infer this? prompt?
-        DependencyCriteria::new()
-    } else {
-        let mut dep_criteria = DependencyCriteria::new();
-        for arg in &sub_args.dependency_criteria {
-            dep_criteria
-                .entry(arg.dependency.clone())
-                .or_insert_with(Vec::new)
-                .push(arg.criteria.clone().into());
-        }
-        dep_criteria
-    };
-
     let notes = sub_args.notes.clone();
 
     let criteria = if sub_args.criteria.is_empty() {
@@ -1272,7 +1236,6 @@ fn cmd_add_exemption(
         criteria,
         notes,
         version: sub_args.version.clone(),
-        dependency_criteria,
         suggest,
     };
 
diff --git a/src/resolver.rs b/src/resolver.rs
index c94154d..b2d8f9d 100644
--- a/src/resolver.rs
+++ b/src/resolver.rs
@@ -74,11 +74,11 @@ use tracing::{error, trace, trace_span};
 
 use crate::errors::{RegenerateExemptionsError, SuggestError};
 use crate::format::{
-    self, AuditKind, AuditsFile, CriteriaName, CriteriaStr, Delta, DependencyCriteria, DiffStat,
-    ExemptedDependency, ImportName, JsonPackage, JsonReport, JsonReportConclusion,
-    JsonReportFailForVet, JsonReportFailForViolationConflict, JsonReportSuccess, JsonSuggest,
-    JsonSuggestItem, JsonVetFailure, PackageName, PackageStr, PolicyEntry, RemoteImport,
-    VetVersion, SAFE_TO_DEPLOY, SAFE_TO_RUN,
+    self, AuditKind, AuditsFile, CriteriaName, CriteriaStr, Delta, DiffStat, ExemptedDependency,
+    ImportName, JsonPackage, JsonReport, JsonReportConclusion, JsonReportFailForVet,
+    JsonReportFailForViolationConflict, JsonReportSuccess, JsonSuggest, JsonSuggestItem,
+    JsonVetFailure, PackageName, PackageStr, PolicyEntry, RemoteImport, VetVersion, SAFE_TO_DEPLOY,
+    SAFE_TO_RUN,
 };
 use crate::format::{FastMap, FastSet, SortedMap, SortedSet};
 use crate::network::Network;
@@ -418,9 +418,6 @@ pub struct DeltaEdge<'a> {
     version: Option<&'a VetVersion>,
     /// The criteria that this edge is valid for.
     criteria: CriteriaSet,
-    /// Requirements that dependencies must satisfy for the edge to be valid.
-    /// If a dependency isn't mentioned, then it defaults to `criteria`.
-    dependency_criteria: FastMap<PackageStr<'a>, CriteriaSet>,
     /// The origin of this edge. See `DeltaEdgeOrigin`'s documentation for more
     /// details.
     origin: DeltaEdgeOrigin,
@@ -1560,6 +1557,22 @@ fn resolve_third_party(
     let package = &graph.nodes[pkgidx];
     let exemptions = store.config.exemptions.get(package.name);
 
+    // Get custom policies for our dependencies
+    let dep_criteria = store
+        .config
+        .policy
+        .get(package.name)
+        .map(|policy| {
+            policy
+                .dependency_criteria
+                .iter()
+                .map(|(dep_name, criteria)| {
+                    (&**dep_name, criteria_mapper.criteria_from_list(criteria))
+                })
+                .collect::<FastMap<_, _>>()
+        })
+        .unwrap_or_default();
+
     // Pre-build the namespaces for each audit so that we can take a reference
     // to each one as-needed rather than cloning the name each time.
     let foreign_namespaces: Vec<CriteriaNamespace> = store
@@ -1601,19 +1614,12 @@ fn resolve_third_party(
     let mut backward_audits = AuditGraph::new();
     let mut violation_nodes = Vec::new();
 
-    // Collect up all the deltas, their criteria, and dependency_criteria
+    // Collect up all the deltas, and their criteria
     for (namespace, entry) in all_audits.clone() {
         // For uniformity, model a Full Audit as `None -> x.y.z`
-        let (from_ver, to_ver, dependency_criteria) = match &entry.kind {
-            AuditKind::Full {
-                version,
-                dependency_criteria,
-            } => (None, version, dependency_criteria),
-            AuditKind::Delta {
-                from,
-                to,
-                dependency_criteria,
-            } => (Some(from), to, dependency_criteria),
+        let (from_ver, to_ver) = match &entry.kind {
+            AuditKind::Full { version } => (None, version),
+            AuditKind::Delta { from, to } => (Some(from), to),
             AuditKind::Violation { .. } => {
                 violation_nodes.push((namespace.clone(), entry));
                 continue;
@@ -1621,16 +1627,6 @@ fn resolve_third_party(
         };
 
         let criteria = criteria_mapper.criteria_from_namespaced_entry(namespace, entry);
-        // Convert all the custom criteria to CriteriaSets
-        let dependency_criteria: FastMap<_, _> = dependency_criteria
-            .iter()
-            .map(|(pkg_name, criteria)| {
-                (
-                    &**pkg_name,
-                    criteria_mapper.criteria_from_namespaced_list(namespace, criteria),
-                )
-            })
-            .collect();
 
         let origin = if entry.is_fresh_import {
             DeltaEdgeOrigin::FreshImportedAudit
@@ -1641,7 +1637,6 @@ fn resolve_third_party(
         forward_audits.entry(from_ver).or_default().push(DeltaEdge {
             version: Some(to_ver),
             criteria: criteria.clone(),
-            dependency_criteria: dependency_criteria.clone(),
             origin,
         });
         backward_audits
@@ -1650,7 +1645,6 @@ fn resolve_third_party(
             .push(DeltaEdge {
                 version: from_ver,
                 criteria,
-                dependency_criteria,
                 origin,
             });
     }
@@ -1783,25 +1777,16 @@ fn resolve_third_party(
             let from_ver = None;
             let to_ver = Some(&allowed.version);
             let criteria = criteria_mapper.criteria_from_list(&allowed.criteria);
-            let dependency_criteria: FastMap<_, _> = allowed
-                .dependency_criteria
-                .iter()
-                .map(|(pkg_name, criteria)| {
-                    (&**pkg_name, criteria_mapper.criteria_from_list(criteria))
-                })
-                .collect();
 
             // For simplicity, turn 'exemptions' entries into deltas from None.
             forward_audits.entry(from_ver).or_default().push(DeltaEdge {
                 version: to_ver,
                 criteria: criteria.clone(),
-                dependency_criteria: dependency_criteria.clone(),
                 origin: DeltaEdgeOrigin::Exemption,
             });
             backward_audits.entry(to_ver).or_default().push(DeltaEdge {
                 version: from_ver,
                 criteria,
-                dependency_criteria,
                 origin: DeltaEdgeOrigin::Exemption,
             });
         }
@@ -1820,6 +1805,7 @@ fn resolve_third_party(
             results,
             pkgidx,
             &package.normal_and_build_deps,
+            &dep_criteria,
         );
         match result {
             SearchResult::Connected { caveats } => {
@@ -1848,6 +1834,7 @@ fn resolve_third_party(
                     results,
                     pkgidx,
                     &package.normal_and_build_deps,
+                    &dep_criteria,
                 );
                 if let SearchResult::Disconnected {
                     reachable_from_root: reachable_from_target,
@@ -1949,6 +1936,7 @@ fn search_for_path(
     results: &[ResolveResult],
     pkgidx: PackageIdx,
     dependencies: &[PackageIdx],
+    dependency_criteria: &FastMap<PackageStr<'_>, CriteriaSet>,
 ) -> SearchResult {
     // Search for any path through the graph with edges that satisfy
     // cur_criteria.  Finding any path validates that we satisfy that criteria.
@@ -2064,7 +2052,7 @@ fn search_for_path(
                 results,
                 dependencies,
                 cur_criteria,
-                &edge.dependency_criteria,
+                dependency_criteria,
                 &mut edge_caveats,
                 &mut edge_failed_deps,
             );
@@ -3283,7 +3271,6 @@ pub fn regenerate_exemptions(
         max_criteria: CriteriaSet,
         useful_criteria: CriteriaSet,
         suggest: bool,
-        dependency_criteria: &'a DependencyCriteria,
         notes: &'a Option<String>,
     }
 
@@ -3292,11 +3279,10 @@ pub fn regenerate_exemptions(
         /// or has `dependency_criteria`). We avoid removing special exemptions
         /// if they could be applicable.
         fn is_special(&self) -> bool {
-            !self.suggest || !self.dependency_criteria.is_empty()
+            !self.suggest
         }
     }
 
-    let no_dependency_criteria = DependencyCriteria::new();
     let mut potential_exemptions = SortedMap::<PackageStr<'_>, Vec<PotentialExemption<'_>>>::new();
 
     loop {
@@ -3361,15 +3347,13 @@ pub fn regenerate_exemptions(
                                 max_criteria: criteria_mapper.all_criteria(),
                                 useful_criteria: criteria_mapper.no_criteria(),
                                 suggest: exemption.suggest,
-                                dependency_criteria: &exemption.dependency_criteria,
                                 notes: &exemption.notes,
                             };
                             // We don't allow special exemptions (criteria with
-                            // `suggest = false` or `dependency_criteria`) to
-                            // expand the allowed criteria, so record the
-                            // existing criteria as our maximum.
-                            // We also don't allow expanding criteria if we
-                            // aren't allowing new exemptions.
+                            // `suggest = false`) to expand the allowed
+                            // criteria, so record the existing criteria as our
+                            // maximum.  We also don't allow expanding criteria
+                            // if we aren't allowing new exemptions.
                             if potential.is_special() || !allow_new_exemptions {
                                 potential.max_criteria = criteria_mapper
                                     .criteria_from_namespaced_list(
@@ -3383,19 +3367,17 @@ pub fn regenerate_exemptions(
                     // The existing exemptions are the only potential exemptions
                     // unless we're allowing adding new exemptions.
                     if allow_new_exemptions {
-                        // Next, for criteria with `suggest = false` (but without
-                        // `dependency_criteria`), we'll consider adding a
-                        // suggestable expanded exemption at the same version
-                        // without criteria limitations, to try to pin exemptions at
-                        // specific past versions.
+                        // Next, for criteria with `suggest = false`, we'll
+                        // consider adding a suggestable expanded exemption at
+                        // the same version without criteria limitations, to try
+                        // to pin exemptions at specific past versions.
                         for exemption in existing_exemptions {
-                            if !exemption.suggest && exemption.dependency_criteria.is_empty() {
+                            if !exemption.suggest {
                                 potentials.push(PotentialExemption {
                                     version: &exemption.version,
                                     max_criteria: criteria_mapper.all_criteria(),
                                     useful_criteria: criteria_mapper.no_criteria(),
                                     suggest: true,
-                                    dependency_criteria: &no_dependency_criteria,
                                     notes: &exemption.notes,
                                 })
                             }
@@ -3412,7 +3394,6 @@ pub fn regenerate_exemptions(
                                     max_criteria: criteria_mapper.all_criteria(),
                                     useful_criteria: criteria_mapper.no_criteria(),
                                     suggest: true,
-                                    dependency_criteria: &no_dependency_criteria,
                                     notes: &None,
                                 }),
                         );
@@ -3427,7 +3408,7 @@ pub fn regenerate_exemptions(
 
                 // In the first pass, try to satisfy as many implied criteria as
                 // possible using "special" potential exemptions (i.e. those
-                // with `suggest = false` or `dependency_criteria`).
+                // with `suggest = false`).
                 //
                 // We always want to prioritize marking all "special" exemptions
                 // which may be applicable as "used", as they may have different
@@ -3529,7 +3510,6 @@ pub fn regenerate_exemptions(
                                 .map(|criteria| criteria.to_owned().into())
                                 .collect(),
                             suggest: potential.suggest,
-                            dependency_criteria: potential.dependency_criteria.clone(),
                             notes: potential.notes.clone(),
                         })
                         .collect();
diff --git a/src/serialization.rs b/src/serialization.rs
index 2ed7a62..b0ed6c6 100644
--- a/src/serialization.rs
+++ b/src/serialization.rs
@@ -184,9 +184,7 @@ pub mod dependency_criteria {
 pub mod audit {
     use super::*;
 
-    use crate::format::{
-        AuditEntry, AuditKind, CriteriaName, Delta, DependencyCriteria, VersionReq, VetVersion,
-    };
+    use crate::format::{AuditEntry, AuditKind, CriteriaName, Delta, VersionReq, VetVersion};
 
     #[derive(Serialize, Deserialize)]
     pub struct AuditEntryAll {
@@ -200,11 +198,6 @@ pub mod audit {
         version: Option<VetVersion>,
         delta: Option<Delta>,
         violation: Option<VersionReq>,
-        #[serde(rename = "dependency-criteria")]
-        #[serde(skip_serializing_if = "DependencyCriteria::is_empty")]
-        #[serde(with = "dependency_criteria")]
-        #[serde(default)]
-        dependency_criteria: DependencyCriteria,
         notes: Option<String>,
         #[serde(rename = "aggregated-from")]
         #[serde(skip_serializing_if = "Vec::is_empty")]
@@ -217,28 +210,15 @@ pub mod audit {
         type Error = String;
         fn try_from(val: AuditEntryAll) -> Result<AuditEntry, Self::Error> {
             let kind = match (val.version, val.delta, val.violation) {
-                (Some(version), None, None) => Ok(AuditKind::Full {
-                    version,
-                    dependency_criteria: val.dependency_criteria,
-                }),
+                (Some(version), None, None) => Ok(AuditKind::Full { version }),
                 (None, Some(delta), None) => {
                     if let Some(from) = delta.from {
-                        Ok(AuditKind::Delta {
-                            from,
-                            to: delta.to,
-                            dependency_criteria: val.dependency_criteria,
-                        })
+                        Ok(AuditKind::Delta { from, to: delta.to })
                     } else {
                         Err("'delta' must be a delta of the form 'VERSION -> VERSION'".to_string())
                     }
                 }
-                (None, None, Some(violation)) => {
-                    if val.dependency_criteria.is_empty() {
-                        Ok(AuditKind::Violation { violation })
-                    } else {
-                        Err("'violation' can't have dependency_criteria".to_string())
-                    }
-                }
+                (None, None, Some(violation)) => Ok(AuditKind::Violation { violation }),
                 _ => Err(
                     "audit entires must have exactly one of 'version', 'delta', and 'violation'"
                         .to_string(),
@@ -259,27 +239,17 @@ pub mod audit {
 
     impl From<AuditEntry> for AuditEntryAll {
         fn from(val: AuditEntry) -> AuditEntryAll {
-            let (version, delta, violation, dependency_criteria) = match val.kind {
-                AuditKind::Full {
-                    version,
-                    dependency_criteria,
-                } => (Some(version), None, None, dependency_criteria),
-                AuditKind::Delta {
-                    from,
-                    to,
-                    dependency_criteria,
-                } => (
+            let (version, delta, violation) = match val.kind {
+                AuditKind::Full { version } => (Some(version), None, None),
+                AuditKind::Delta { from, to } => (
                     None,
                     Some(Delta {
                         from: Some(from),
                         to,
                     }),
                     None,
-                    dependency_criteria,
                 ),
-                AuditKind::Violation { violation } => {
-                    (None, None, Some(violation), DependencyCriteria::new())
-                }
+                AuditKind::Violation { violation } => (None, None, Some(violation)),
             };
             AuditEntryAll {
                 who: val.who,
@@ -288,7 +258,6 @@ pub mod audit {
                 version,
                 delta,
                 violation,
-                dependency_criteria,
                 aggregated_from: val.aggregated_from,
             }
         }
@@ -655,38 +624,33 @@ mod test {
             vec!["criteria-one".to_owned().into()],
         );
 
-        let mut audits = SortedMap::new();
-        audits.insert(
-            "test".to_owned(),
-            vec![
-                AuditEntry {
-                    who: vec![],
-                    criteria: vec!["long-criteria".to_owned().into()],
-                    kind: AuditKind::Full {
-                        version: "1.0.0".parse().unwrap(),
-                        dependency_criteria: dc_long,
-                    },
-                    notes: Some("notes go here!".to_owned()),
-                    aggregated_from: vec![],
-                    is_fresh_import: false, // ignored
-                },
-                AuditEntry {
-                    who: vec![],
-                    criteria: vec!["short-criteria".to_owned().into()],
-                    kind: AuditKind::Full {
-                        version: "1.0.0".parse().unwrap(),
-                        dependency_criteria: dc_short,
-                    },
-                    notes: Some("notes go here!".to_owned()),
-                    aggregated_from: vec![],
-                    is_fresh_import: true, // ignored
-                },
-            ],
+        let mut policy = SortedMap::new();
+        policy.insert(
+            "long-criteria".to_owned(),
+            PolicyEntry {
+                audit_as_crates_io: None,
+                criteria: Some(vec!["long-criteria".to_owned().into()]),
+                dev_criteria: None,
+                dependency_criteria: dc_long,
+                notes: Some("notes go here!".to_owned()),
+            },
+        );
+        policy.insert(
+            "short-criteria".to_owned(),
+            PolicyEntry {
+                audit_as_crates_io: None,
+                criteria: Some(vec!["short-criteria".to_owned().into()]),
+                dev_criteria: None,
+                dependency_criteria: dc_short,
+                notes: Some("notes go here!".to_owned()),
+            },
         );
 
-        let formatted = super::to_formatted_toml(AuditsFile {
-            criteria: SortedMap::new(),
-            audits,
+        let formatted = super::to_formatted_toml(ConfigFile {
+            default_criteria: get_default_criteria(),
+            imports: SortedMap::new(),
+            policy,
+            exemptions: SortedMap::new(),
         })
         .unwrap()
         .to_string();
diff --git a/src/storage.rs b/src/storage.rs
index 0f5a13e..065751d 100644
--- a/src/storage.rs
+++ b/src/storage.rs
@@ -453,14 +453,6 @@ impl Store {
                     &mut invalid_criteria_errors,
                     &entry.criteria,
                 );
-                for (_dep_package, dep_criteria) in &entry.dependency_criteria {
-                    check_criteria(
-                        &self.config_src,
-                        &valid_criteria,
-                        &mut invalid_criteria_errors,
-                        dep_criteria,
-                    );
-                }
             }
         }
         for (_package, policy) in &self.config.policy {
@@ -503,35 +495,6 @@ impl Store {
                     &mut invalid_criteria_errors,
                     &entry.criteria,
                 );
-                match &entry.kind {
-                    crate::format::AuditKind::Full {
-                        dependency_criteria,
-                        ..
-                    } => {
-                        for (_dep_package, dep_criteria) in dependency_criteria {
-                            check_criteria(
-                                &self.audits_src,
-                                &valid_criteria,
-                                &mut invalid_criteria_errors,
-                                dep_criteria,
-                            );
-                        }
-                    }
-                    crate::format::AuditKind::Delta {
-                        dependency_criteria,
-                        ..
-                    } => {
-                        for (_dep_package, dep_criteria) in dependency_criteria {
-                            check_criteria(
-                                &self.audits_src,
-                                &valid_criteria,
-                                &mut invalid_criteria_errors,
-                                dep_criteria,
-                            );
-                        }
-                    }
-                    crate::format::AuditKind::Violation { .. } => {}
-                }
             }
         }
 
@@ -1025,26 +988,6 @@ fn parse_imported_audit(valid_criteria: &[CriteriaName], value: toml::Value) ->
         return None;
     }
 
-    // If any dependency criteria name an unknown criteria, ignore the audit.
-    match &audit.kind {
-        AuditKind::Delta {
-            dependency_criteria,
-            ..
-        }
-        | AuditKind::Full {
-            dependency_criteria,
-            ..
-        } => {
-            for criteria_name in dependency_criteria.values().flatten() {
-                if !is_known_criteria(valid_criteria, criteria_name) {
-                    info!("imported audit parsing failed due to unknown dependency criteria: {criteria_name}");
-                    return None;
-                }
-            }
-        }
-        _ => {}
-    }
-
     Some(audit)
 }
 


Test patch:
diff --git a/src/snapshots/cargo_vet__serialization__test__formatted_toml_long_inline.snap b/src/snapshots/cargo_vet__serialization__test__formatted_toml_long_inline.snap
index 9234d2e..02490a1 100644
--- a/src/snapshots/cargo_vet__serialization__test__formatted_toml_long_inline.snap
+++ b/src/snapshots/cargo_vet__serialization__test__formatted_toml_long_inline.snap
@@ -3,12 +3,11 @@ source: src/serialization.rs
 expression: formatted
 ---
 
-[[audits.test]]
+[policy.long-criteria]
 criteria = "long-criteria"
-version = "1.0.0"
 notes = "notes go here!"
 
-[audits.test.dependency-criteria]
+[policy.long-criteria.dependency-criteria]
 example-crate-1 = ["criteria-one-very-long", "criteria-two-very-long"]
 example-crate-2 = ["criteria-one-✨✨✨✨✨✨✨✨✨✨", "criteria-two-✨✨✨✨✨✨✨✨✨✨"]
 example-crate-3 = [
@@ -17,9 +16,8 @@ example-crate-3 = [
     "criteria-three-extremely-long-this-array-should-wrap",
 ]
 
-[[audits.test]]
+[policy.short-criteria]
 criteria = "short-criteria"
-version = "1.0.0"
 dependency-criteria = { example-crate-1 = "criteria-one" }
 notes = "notes go here!"
 
diff --git a/src/tests/import.rs b/src/tests/import.rs
index 4f9f874..044b5bb 100644
--- a/src/tests/import.rs
+++ b/src/tests/import.rs
@@ -920,24 +920,6 @@ fn foreign_audit_file_to_local() {
                         version = "10.0.0"
                         notes = "will be removed"
                     },
-                    toml::toml! {
-                        criteria = "safe-to-deploy"
-                        version = "10.0.0"
-                        dependency-criteria = { foo = "unknown-criteria" }
-                        notes = "will be removed"
-                    },
-                    toml::toml! {
-                        criteria = "safe-to-deploy"
-                        version = "10.0.0"
-                        dependency-criteria = { foo = ["example", "unknown-criteria"] }
-                        notes = "will be removed"
-                    },
-                    toml::toml! {
-                        criteria = "safe-to-deploy"
-                        version = "10.0.0"
-                        dependency-criteria = { foo = "example" }
-                        notes = "should parse correctly"
-                    },
                     toml::toml! {
                         criteria = "safe-to-deploy"
                         violation = "invalid"
@@ -990,7 +972,7 @@ fn foreign_audit_file_to_local() {
     assert_eq!(result.ignored_criteria, &["will-not-parse"]);
     assert_eq!(
         result.ignored_audits,
-        &["crate-a", "crate-a", "crate-a", "crate-a", "crate-a", "crate-a", "crate-b"]
+        &["crate-a", "crate-a", "crate-a", "crate-a", "crate-b"]
     );
 
     insta::assert_snapshot!(
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
index b6d132c..f1c9e84 100644
--- a/src/tests/mod.rs
+++ b/src/tests/mod.rs
@@ -287,7 +287,6 @@ fn default_exemptions(version: VetVersion, config: &ConfigFile) -> ExemptedDepen
     ExemptedDependency {
         version,
         criteria: vec![config.default_criteria.clone().into()],
-        dependency_criteria: DependencyCriteria::new(),
         notes: None,
         suggest: true,
     }
@@ -296,83 +295,17 @@ fn exemptions(version: VetVersion, criteria: CriteriaStr) -> ExemptedDependency
     ExemptedDependency {
         version,
         criteria: vec![criteria.to_string().into()],
-        dependency_criteria: DependencyCriteria::new(),
         notes: None,
         suggest: true,
     }
 }
 
-fn exemptions_dep(
-    version: VetVersion,
-    criteria: CriteriaStr,
-    dependency_criteria: impl IntoIterator<
-        Item = (
-            impl Into<PackageName>,
-            impl IntoIterator<Item = impl Into<CriteriaName>>,
-        ),
-    >,
-) -> ExemptedDependency {
-    ExemptedDependency {
-        version,
-        criteria: vec![criteria.to_string().into()],
-        notes: None,
-        suggest: true,
-        dependency_criteria: dependency_criteria
-            .into_iter()
-            .map(|(k, v)| {
-                (
-                    k.into(),
-                    v.into_iter().map(|s| s.into().into()).collect::<Vec<_>>(),
-                )
-            })
-            .collect(),
-    }
-}
-
 fn delta_audit(from: VetVersion, to: VetVersion, criteria: CriteriaStr) -> AuditEntry {
     AuditEntry {
         who: vec![],
         notes: None,
         criteria: vec![criteria.to_string().into()],
-        kind: AuditKind::Delta {
-            from,
-            to,
-            dependency_criteria: DependencyCriteria::default(),
-        },
-        aggregated_from: vec![],
-        is_fresh_import: false,
-    }
-}
-
-#[allow(dead_code)]
-fn delta_audit_dep(
-    from: VetVersion,
-    to: VetVersion,
-    criteria: CriteriaStr,
-    dependency_criteria: impl IntoIterator<
-        Item = (
-            impl Into<PackageName>,
-            impl IntoIterator<Item = impl Into<CriteriaName>>,
-        ),
-    >,
-) -> AuditEntry {
-    AuditEntry {
-        who: vec![],
-        notes: None,
-        criteria: vec![criteria.to_string().into()],
-        kind: AuditKind::Delta {
-            from,
-            to,
-            dependency_criteria: dependency_criteria
-                .into_iter()
-                .map(|(k, v)| {
-                    (
-                        k.into(),
-                        v.into_iter().map(|s| s.into().into()).collect::<Vec<_>>(),
-                    )
-                })
-                .collect(),
-        },
+        kind: AuditKind::Delta { from, to },
         aggregated_from: vec![],
         is_fresh_import: false,
     }
@@ -383,10 +316,7 @@ fn full_audit(version: VetVersion, criteria: CriteriaStr) -> AuditEntry {
         who: vec![],
         notes: None,
         criteria: vec![criteria.to_string().into()],
-        kind: AuditKind::Full {
-            version,
-            dependency_criteria: DependencyCriteria::default(),
-        },
+        kind: AuditKind::Full { version },
         aggregated_from: vec![],
         is_fresh_import: false,
     }
@@ -400,41 +330,7 @@ fn full_audit_m(
         who: vec![],
         notes: None,
         criteria: criteria.into_iter().map(|s| s.into().into()).collect(),
-        kind: AuditKind::Full {
-            version,
-            dependency_criteria: DependencyCriteria::default(),
-        },
-        aggregated_from: vec![],
-        is_fresh_import: false,
-    }
-}
-
-fn full_audit_dep(
-    version: VetVersion,
-    criteria: CriteriaStr,
-    dependency_criteria: impl IntoIterator<
-        Item = (
-            impl Into<PackageName>,
-            impl IntoIterator<Item = impl Into<CriteriaName>>,
-        ),
-    >,
-) -> AuditEntry {
-    AuditEntry {
-        who: vec![],
-        notes: None,
-        criteria: vec![criteria.to_string().into()],
-        kind: AuditKind::Full {
-            version,
-            dependency_criteria: dependency_criteria
-                .into_iter()
-                .map(|(k, v)| {
-                    (
-                        k.into(),
-                        v.into_iter().map(|s| s.into().into()).collect::<Vec<_>>(),
-                    )
-                })
-                .collect(),
-        },
+        kind: AuditKind::Full { version },
         aggregated_from: vec![],
         is_fresh_import: false,
     }
diff --git a/src/tests/regenerate_unaudited.rs b/src/tests/regenerate_unaudited.rs
index ba848b5..cac51ca 100644
--- a/src/tests/regenerate_unaudited.rs
+++ b/src/tests/regenerate_unaudited.rs
@@ -333,18 +333,8 @@ fn builtin_simple_exemptions_nested_weaker_req_regenerate() {
     audits.audits.insert(
         "third-party1".to_string(),
         vec![
-            delta_audit_dep(
-                ver(3),
-                ver(6),
-                SAFE_TO_DEPLOY,
-                [("transitive-third-party1", [SAFE_TO_RUN])],
-            ),
-            delta_audit_dep(
-                ver(6),
-                ver(DEFAULT_VER),
-                SAFE_TO_DEPLOY,
-                [("transitive-third-party1", [SAFE_TO_RUN])],
-            ),
+            delta_audit(ver(3), ver(6), SAFE_TO_DEPLOY),
+            delta_audit(ver(6), ver(DEFAULT_VER), SAFE_TO_DEPLOY),
         ],
     );
     audits.audits.insert(
@@ -355,13 +345,14 @@ fn builtin_simple_exemptions_nested_weaker_req_regenerate() {
         ],
     );
 
+    config.policy.insert(
+        "third-party1".to_string(),
+        dep_policy([("transitive-third-party1", [SAFE_TO_RUN])]),
+    );
+
     config.exemptions.insert(
         "third-party1".to_string(),
-        vec![exemptions_dep(
-            ver(3),
-            SAFE_TO_DEPLOY,
-            [("transitive-third-party1", [SAFE_TO_RUN])],
-        )],
+        vec![exemptions(ver(3), SAFE_TO_DEPLOY)],
     );
 
     config.exemptions.insert(
@@ -398,18 +389,8 @@ fn builtin_simple_exemptions_nested_stronger_req_regenerate() {
     audits.audits.insert(
         "third-party1".to_string(),
         vec![
-            delta_audit_dep(
-                ver(3),
-                ver(6),
-                SAFE_TO_RUN,
-                [("transitive-third-party1", [SAFE_TO_DEPLOY])],
-            ),
-            delta_audit_dep(
-                ver(6),
-                ver(DEFAULT_VER),
-                SAFE_TO_RUN,
-                [("transitive-third-party1", [SAFE_TO_DEPLOY])],
-            ),
+            delta_audit(ver(3), ver(6), SAFE_TO_RUN),
+            delta_audit(ver(6), ver(DEFAULT_VER), SAFE_TO_RUN),
         ],
     );
     audits.audits.insert(
@@ -420,6 +401,11 @@ fn builtin_simple_exemptions_nested_stronger_req_regenerate() {
         ],
     );
 
+    config.policy.insert(
+        "third-party1".to_string(),
+        dep_policy([("transitive-third-party1", [SAFE_TO_DEPLOY])]),
+    );
+
     config.exemptions.insert(
         "third-party1".to_string(),
         vec![exemptions(ver(3), SAFE_TO_RUN)],
@@ -609,11 +595,7 @@ fn builtin_simple_exemptions_regenerate_merge() {
 
     audits.audits.insert(
         "third-party1".to_owned(),
-        vec![full_audit_dep(
-            ver(DEFAULT_VER),
-            SAFE_TO_DEPLOY,
-            [("transitive-third-party1", ["criteria1", "criteria2"])],
-        )],
+        vec![full_audit(ver(DEFAULT_VER), SAFE_TO_DEPLOY)],
     );
 
     audits.audits.insert(
@@ -623,6 +605,12 @@ fn builtin_simple_exemptions_regenerate_merge() {
             delta_audit(ver(5), ver(DEFAULT_VER), "criteria2"),
         ],
     );
+
+    config.policy.insert(
+        "third-party1".to_string(),
+        dep_policy([("transitive-third-party1", ["criteria1", "criteria2"])]),
+    );
+
     config.exemptions.insert(
         "transitive-third-party1".to_owned(),
         vec![
@@ -660,11 +648,7 @@ fn builtin_simple_exemptions_regenerate_merge_nonew() {
 
     audits.audits.insert(
         "third-party1".to_owned(),
-        vec![full_audit_dep(
-            ver(DEFAULT_VER),
-            SAFE_TO_DEPLOY,
-            [("transitive-third-party1", ["criteria1", "criteria2"])],
-        )],
+        vec![full_audit(ver(DEFAULT_VER), SAFE_TO_DEPLOY)],
     );
 
     audits.audits.insert(
@@ -674,6 +658,12 @@ fn builtin_simple_exemptions_regenerate_merge_nonew() {
             delta_audit(ver(5), ver(DEFAULT_VER), "criteria2"),
         ],
     );
+
+    config.policy.insert(
+        "third-party1".to_string(),
+        dep_policy([("transitive-third-party1", ["criteria1", "criteria2"])]),
+    );
+
     config.exemptions.insert(
         "transitive-third-party1".to_owned(),
         vec![
diff --git a/src/tests/snapshots/cargo_vet__tests__import__foreign_audit_file_to_local.snap b/src/tests/snapshots/cargo_vet__tests__import__foreign_audit_file_to_local.snap
index e477811..41b0d2d 100644
--- a/src/tests/snapshots/cargo_vet__tests__import__foreign_audit_file_to_local.snap
+++ b/src/tests/snapshots/cargo_vet__tests__import__foreign_audit_file_to_local.snap
@@ -18,12 +18,6 @@ criteria = "safe-to-deploy"
 version = "10.0.0"
 notes = "should parse correctly"
 
-[[audits.crate-a]]
-criteria = "safe-to-deploy"
-version = "10.0.0"
-dependency-criteria = { foo = "example" }
-notes = "should parse correctly"
-
 [[audits.crate-c]]
 criteria = "example2"
 version = "10.0.0"
diff --git a/src/tests/snapshots/cargo_vet__tests__regenerate_unaudited__builtin-simple-unaudited-nested-weaker-req-regenerate.snap b/src/tests/snapshots/cargo_vet__tests__regenerate_unaudited__builtin-simple-unaudited-nested-weaker-req-regenerate.snap
index e20ef90..c36e6d9 100644
--- a/src/tests/snapshots/cargo_vet__tests__regenerate_unaudited__builtin-simple-unaudited-nested-weaker-req-regenerate.snap
+++ b/src/tests/snapshots/cargo_vet__tests__regenerate_unaudited__builtin-simple-unaudited-nested-weaker-req-regenerate.snap
@@ -6,9 +6,6 @@ expression: exemptions
 version = "3.0.0"
 criteria = "safe-to-deploy"
 
-[third-party1.dependency-criteria]
-transitive-third-party1 = "safe-to-run"
-
 [[transitive-third-party1]]
 version = "4.0.0"
 criteria = "safe-to-run"
diff --git a/src/tests/snapshots/cargo_vet__tests__store_parsing__many_bad_audits.snap b/src/tests/snapshots/cargo_vet__tests__store_parsing__many_bad_audits.snap
index 7000975..67fe224 100644
--- a/src/tests/snapshots/cargo_vet__tests__store_parsing__many_bad_audits.snap
+++ b/src/tests/snapshots/cargo_vet__tests__store_parsing__many_bad_audits.snap
@@ -23,85 +23,40 @@ Error:
  10 │ version = "1.0.0"
     ╰────
   help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
-Error: 
-  × 'bad1' is not a valid criteria name
-    ╭─[audits.toml:10:1]
- 10 │ version = "1.0.0"
- 11 │ dependency-criteria = { serde_derive = ["bad1", "good", "bad2"], toml = "bad-dep" }
-    ·                                         ──────
- 12 │ 
-    ╰────
-  help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
-Error: 
-  × 'bad2' is not a valid criteria name
-    ╭─[audits.toml:10:1]
- 10 │ version = "1.0.0"
- 11 │ dependency-criteria = { serde_derive = ["bad1", "good", "bad2"], toml = "bad-dep" }
-    ·                                                         ──────
- 12 │ 
-    ╰────
-  help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
-Error: 
-  × 'bad-dep' is not a valid criteria name
-    ╭─[audits.toml:10:1]
- 10 │ version = "1.0.0"
- 11 │ dependency-criteria = { serde_derive = ["bad1", "good", "bad2"], toml = "bad-dep" }
-    ·                                                                         ─────────
- 12 │ 
-    ╰────
-  help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
 Error: 
   × 'safe-to-jog' is not a valid criteria name
-    ╭─[audits.toml:13:1]
- 13 │ [[audits.serde]]
- 14 │ criteria = "safe-to-jog"
+    ╭─[audits.toml:12:1]
+ 12 │ [[audits.serde]]
+ 13 │ criteria = "safe-to-jog"
     ·            ─────────────
- 15 │ version = "2.0.0"
-    ╰────
-  help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
-Error: 
-  × 'unsafe-to-destroy' is not a valid criteria name
-    ╭─[audits.toml:15:1]
- 15 │ version = "2.0.0"
- 16 │ dependency-criteria = { toml = "unsafe-to-destroy" }
-    ·                                ───────────────────
- 17 │ 
-    ╰────
-  help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
-Error: 
-  × 'dang' is not a valid criteria name
-    ╭─[audits.toml:18:1]
- 18 │ [[audits.serde]]
- 19 │ criteria = ["safe-to-run", "dang"]
-    ·                            ──────
- 20 │ delta = "1.0.0 -> 1.1.0"
+ 14 │ version = "2.0.0"
     ╰────
   help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
 Error: 
   × 'oops' is not a valid criteria name
-    ╭─[audits.toml:22:1]
- 22 │ [[audits.serde]]
- 23 │ criteria = "oops"
+    ╭─[audits.toml:16:1]
+ 16 │ [[audits.serde]]
+ 17 │ criteria = "oops"
     ·            ──────
- 24 │ delta = "1.0.0 -> 1.1.0"
+ 18 │ delta = "1.0.0 -> 1.1.0"
     ╰────
   help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
 Error: 
-  × 'nah' is not a valid criteria name
-    ╭─[audits.toml:24:1]
- 24 │ delta = "1.0.0 -> 1.1.0"
- 25 │ dependency-criteria = { nope = "nah" }
-    ·                                ─────
- 26 │ 
+  × 'dang' is not a valid criteria name
+    ╭─[audits.toml:20:1]
+ 20 │ [[audits.serde]]
+ 21 │ criteria = ["safe-to-run", "dang"]
+    ·                            ──────
+ 22 │ delta = "1.0.0 -> 1.1.0"
     ╰────
   help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
 Error: 
   × 'no-good-bad-bad' is not a valid criteria name
-    ╭─[audits.toml:27:1]
- 27 │ [[audits.serde]]
- 28 │ criteria = "no-good-bad-bad"
+    ╭─[audits.toml:24:1]
+ 24 │ [[audits.serde]]
+ 25 │ criteria = "no-good-bad-bad"
     ·            ─────────────────
- 29 │ violation = "^5.0.0"
+ 26 │ violation = "^5.0.0"
     ╰────
   help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
 
diff --git a/src/tests/snapshots/cargo_vet__tests__store_parsing__many_bad_config.snap b/src/tests/snapshots/cargo_vet__tests__store_parsing__many_bad_config.snap
index fb3d6d6..288d97a 100644
--- a/src/tests/snapshots/cargo_vet__tests__store_parsing__many_bad_config.snap
+++ b/src/tests/snapshots/cargo_vet__tests__store_parsing__many_bad_config.snap
@@ -11,25 +11,7 @@ Error:
  18 │ version = "1.0.0"
  19 │ criteria = "oops"
     ·            ──────
- 20 │ dependency-criteria = { clap_derive = "nah", oops = ["no", "safe-to-run"] }
-    ╰────
-  help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
-Error: 
-  × 'nah' is not a valid criteria name
-    ╭─[config.toml:19:1]
- 19 │ criteria = "oops"
- 20 │ dependency-criteria = { clap_derive = "nah", oops = ["no", "safe-to-run"] }
-    ·                                       ─────
- 21 │ 
-    ╰────
-  help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
-Error: 
-  × 'no' is not a valid criteria name
-    ╭─[config.toml:19:1]
- 19 │ criteria = "oops"
- 20 │ dependency-criteria = { clap_derive = "nah", oops = ["no", "safe-to-run"] }
-    ·                                                      ────
- 21 │ 
+ 20 │ 
     ╰────
   help: the possible criteria are ["good", "safe-to-run", "safe-to-deploy"]
 Error: 
diff --git a/src/tests/snapshots/cargo_vet__tests__vet__builtin-simple-unaudited-nested-weaker-req-needs-dep-criteria.json.snap b/src/tests/snapshots/cargo_vet__tests__vet__builtin-simple-unaudited-nested-weaker-req-needs-dep-criteria.json.snap
deleted file mode 100644
index b01144e..0000000
--- a/src/tests/snapshots/cargo_vet__tests__vet__builtin-simple-unaudited-nested-weaker-req-needs-dep-criteria.json.snap
+++ /dev/null
@@ -1,57 +0,0 @@
----
-source: src/tests/vet.rs
-expression: json
----
-{
-  "conclusion": "fail (vetting)",
-  "failures": [
-    {
-      "name": "transitive-third-party1",
-      "version": "10.0.0",
-      "missing_criteria": [
-        "safe-to-deploy"
-      ]
-    }
-  ],
-  "suggest": {
-    "suggestions": [
-      {
-        "name": "transitive-third-party1",
-        "notable_parents": "third-party1",
-        "suggested_criteria": [
-          "safe-to-deploy"
-        ],
-        "suggested_diff": {
-          "from": null,
-          "to": "10.0.0",
-          "diffstat": {
-            "insertions": 100,
-            "deletions": 0,
-            "files_changed": 1
-          }
-        }
-      }
-    ],
-    "suggest_by_criteria": {
-      "safe-to-deploy": [
-        {
-          "name": "transitive-third-party1",
-          "notable_parents": "third-party1",
-          "suggested_criteria": [
-            "safe-to-deploy"
-          ],
-          "suggested_diff": {
-            "from": null,
-            "to": "10.0.0",
-            "diffstat": {
-              "insertions": 100,
-              "deletions": 0,
-              "files_changed": 1
-            }
-          }
-        }
-      ]
-    },
-    "total_lines": 100
-  }
-}
diff --git a/src/tests/snapshots/cargo_vet__tests__vet__builtin-simple-unaudited-nested-weaker-req-needs-dep-criteria.snap b/src/tests/snapshots/cargo_vet__tests__vet__builtin-simple-unaudited-nested-weaker-req-needs-dep-criteria.snap
deleted file mode 100644
index f60bc4f..0000000
--- a/src/tests/snapshots/cargo_vet__tests__vet__builtin-simple-unaudited-nested-weaker-req-needs-dep-criteria.snap
+++ /dev/null
@@ -1,16 +0,0 @@
----
-source: src/tests/vet.rs
-expression: output
----
-Vetting Failed!
-
-1 unvetted dependencies:
-  transitive-third-party1:10.0.0 missing ["safe-to-deploy"]
-
-recommended audits for safe-to-deploy:
-    cargo vet inspect transitive-third-party1 10.0.0  (used by third-party1)  (100 lines)
-
-estimated audit backlog: 100 lines
-
-Use |cargo vet certify| to record the audits.
-
diff --git a/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_fail.json.snap b/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_fail.json.snap
deleted file mode 100644
index 18dc4c2..0000000
--- a/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_fail.json.snap
+++ /dev/null
@@ -1,57 +0,0 @@
----
-source: src/tests/vet.rs
-expression: json
----
-{
-  "conclusion": "fail (vetting)",
-  "failures": [
-    {
-      "name": "transitive-third-party1",
-      "version": "10.0.0",
-      "missing_criteria": [
-        "peer-company::reviewed"
-      ]
-    }
-  ],
-  "suggest": {
-    "suggestions": [
-      {
-        "name": "transitive-third-party1",
-        "notable_parents": "third-party1",
-        "suggested_criteria": [
-          "peer-company::reviewed"
-        ],
-        "suggested_diff": {
-          "from": null,
-          "to": "10.0.0",
-          "diffstat": {
-            "insertions": 100,
-            "deletions": 0,
-            "files_changed": 1
-          }
-        }
-      }
-    ],
-    "suggest_by_criteria": {
-      "peer-company::reviewed": [
-        {
-          "name": "transitive-third-party1",
-          "notable_parents": "third-party1",
-          "suggested_criteria": [
-            "peer-company::reviewed"
-          ],
-          "suggested_diff": {
-            "from": null,
-            "to": "10.0.0",
-            "diffstat": {
-              "insertions": 100,
-              "deletions": 0,
-              "files_changed": 1
-            }
-          }
-        }
-      ]
-    },
-    "total_lines": 100
-  }
-}
diff --git a/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_fail.snap b/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_fail.snap
deleted file mode 100644
index 1f031f9..0000000
--- a/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_fail.snap
+++ /dev/null
@@ -1,16 +0,0 @@
----
-source: src/tests/vet.rs
-expression: output
----
-Vetting Failed!
-
-1 unvetted dependencies:
-  transitive-third-party1:10.0.0 missing ["peer-company::reviewed"]
-
-recommended audits for peer-company::reviewed:
-    cargo vet inspect transitive-third-party1 10.0.0  (used by third-party1)  (100 lines)
-
-estimated audit backlog: 100 lines
-
-Use |cargo vet certify| to record the audits.
-
diff --git a/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_pass.json.snap b/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_pass.json.snap
deleted file mode 100644
index 327e9fb..0000000
--- a/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_pass.json.snap
+++ /dev/null
@@ -1,23 +0,0 @@
----
-source: src/tests/vet.rs
-expression: json
----
-{
-  "conclusion": "success",
-  "vetted_fully": [
-    {
-      "name": "transitive-third-party1",
-      "version": "10.0.0"
-    },
-    {
-      "name": "third-party1",
-      "version": "10.0.0"
-    },
-    {
-      "name": "third-party2",
-      "version": "10.0.0"
-    }
-  ],
-  "vetted_partially": [],
-  "vetted_with_exemptions": []
-}
diff --git a/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_pass.snap b/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_pass.snap
deleted file mode 100644
index f229132..0000000
--- a/src/tests/snapshots/cargo_vet__tests__vet__builtin_simple_foreign_dep_criteria_pass.snap
+++ /dev/null
@@ -1,6 +0,0 @@
----
-source: src/tests/vet.rs
-expression: output
----
-Vetting Succeeded (3 fully audited)
-
diff --git a/src/tests/store_parsing.rs b/src/tests/store_parsing.rs
index 62791a5..d4f2959 100644
--- a/src/tests/store_parsing.rs
+++ b/src/tests/store_parsing.rs
@@ -58,21 +58,18 @@ implies = ["safe-to-deploy", "bad-imply"]
 [[audits.serde]]
 criteria = "bad"
 version = "1.0.0"
-dependency-criteria = { serde_derive = ["bad1", "good", "bad2"], toml = "bad-dep" }
 
 [[audits.serde]]
 criteria = "safe-to-jog"
 version = "2.0.0"
-dependency-criteria = { toml = "unsafe-to-destroy" }
 
 [[audits.serde]]
-criteria = ["safe-to-run", "dang"]
+criteria = "oops"
 delta = "1.0.0 -> 1.1.0"
 
 [[audits.serde]]
-criteria = "oops"
+criteria = ["safe-to-run", "dang"]
 delta = "1.0.0 -> 1.1.0"
-dependency-criteria = { nope = "nah" }
 
 [[audits.serde]]
 criteria = "no-good-bad-bad"
@@ -104,7 +101,6 @@ dependency-criteria = { clap = ["safe-to-run", "unsafe-for-all", "good"], serde_
 [[exemptions.clap]]
 version = "1.0.0"
 criteria = "oops"
-dependency-criteria = { clap_derive = "nah", oops = ["no", "safe-to-run"] }
 
 [[exemptions.clap_derive]]
 version = "1.0.0"
diff --git a/src/tests/vet.rs b/src/tests/vet.rs
index 3dcfe2e..262bef0 100644
--- a/src/tests/vet.rs
+++ b/src/tests/vet.rs
@@ -185,7 +185,7 @@ fn mock_simple_weaker_transitive_req() {
     let mock = MockMetadata::simple();
 
     let metadata = mock.metadata();
-    let (config, mut audits, imports) = files_full_audited(&metadata);
+    let (mut config, mut audits, imports) = files_full_audited(&metadata);
 
     let trans_audits = &mut audits.audits.get_mut("transitive-third-party1").unwrap();
     trans_audits.clear();
@@ -193,11 +193,12 @@ fn mock_simple_weaker_transitive_req() {
 
     let direct_audits = &mut audits.audits.get_mut("third-party1").unwrap();
     direct_audits.clear();
-    direct_audits.push(full_audit_dep(
-        ver(DEFAULT_VER),
-        "reviewed",
-        [("transitive-third-party1", ["weak-reviewed"])],
-    ));
+    direct_audits.push(full_audit(ver(DEFAULT_VER), "reviewed"));
+
+    config.policy.insert(
+        "third-party1".to_string(),
+        dep_policy([("transitive-third-party1", ["weak-reviewed"])]),
+    );
 
     let store = Store::mock(config, audits, imports);
     let report = crate::resolver::resolve(&metadata, None, &store, ResolveDepth::Shallow);
@@ -214,7 +215,7 @@ fn mock_simple_weaker_transitive_req_using_implies() {
     let mock = MockMetadata::simple();
 
     let metadata = mock.metadata();
-    let (config, mut audits, imports) = files_full_audited(&metadata);
+    let (mut config, mut audits, imports) = files_full_audited(&metadata);
 
     let trans_audits = &mut audits.audits.get_mut("transitive-third-party1").unwrap();
     trans_audits.clear();
@@ -222,11 +223,12 @@ fn mock_simple_weaker_transitive_req_using_implies() {
 
     let direct_audits = &mut audits.audits.get_mut("third-party1").unwrap();
     direct_audits.clear();
-    direct_audits.push(full_audit_dep(
-        ver(DEFAULT_VER),
-        "reviewed",
-        [("transitive-third-party1", ["weak-reviewed"])],
-    ));
+    direct_audits.push(full_audit(ver(DEFAULT_VER), "reviewed"));
+
+    config.policy.insert(
+        "third-party1".to_string(),
+        dep_policy([("transitive-third-party1", ["weak-reviewed"])]),
+    );
 
     let store = Store::mock(config, audits, imports);
     let report = crate::resolver::resolve(&metadata, None, &store, ResolveDepth::Shallow);
@@ -911,7 +913,7 @@ fn mock_complex_core10_partially_too_weak() {
     let _enter = TEST_RUNTIME.enter();
     let mock = MockMetadata::complex();
     let metadata = mock.metadata();
-    let (config, mut audits, imports) = files_full_audited(&metadata);
+    let (mut config, mut audits, imports) = files_full_audited(&metadata);
 
     audits.audits.insert(
         "third-core".to_string(),
@@ -921,11 +923,7 @@ fn mock_complex_core10_partially_too_weak() {
         ],
     );
 
-    let audit_with_weaker_req = full_audit_dep(
-        ver(DEFAULT_VER),
-        "reviewed",
-        [("third-core", ["weak-reviewed"])],
-    );
+    let audit_with_weaker_req = full_audit(ver(DEFAULT_VER), "reviewed");
     audits
         .audits
         .insert("thirdA".to_string(), vec![audit_with_weaker_req.clone()]);
@@ -933,6 +931,15 @@ fn mock_complex_core10_partially_too_weak() {
         .audits
         .insert("thirdAB".to_string(), vec![audit_with_weaker_req]);
 
+    config.policy.insert(
+        "thirdA".to_string(),
+        dep_policy([("third-core", ["weak-reviewed"])]),
+    );
+    config.policy.insert(
+        "thirdAB".to_string(),
+        dep_policy([("third-core", ["weak-reviewed"])]),
+    );
+
     let store = Store::mock(config, audits, imports);
     let report = crate::resolver::resolve(&metadata, None, &store, ResolveDepth::Shallow);
     assert_report_snapshot!("mock-complex-core10-partially-too-weak", &metadata, report);
@@ -945,7 +952,7 @@ fn mock_complex_core10_partially_too_weak_via_weak_delta() {
     let _enter = TEST_RUNTIME.enter();
     let mock = MockMetadata::complex();
     let metadata = mock.metadata();
-    let (config, mut audits, imports) = files_full_audited(&metadata);
+    let (mut config, mut audits, imports) = files_full_audited(&metadata);
 
     audits.audits.insert(
         "third-core".to_string(),
@@ -955,11 +962,7 @@ fn mock_complex_core10_partially_too_weak_via_weak_delta() {
         ],
     );
 
-    let audit_with_weaker_req = full_audit_dep(
-        ver(DEFAULT_VER),
-        "reviewed",
-        [("third-core", ["weak-reviewed"])],
-    );
+    let audit_with_weaker_req = full_audit(ver(DEFAULT_VER), "reviewed");
     audits
         .audits
         .insert("thirdA".to_string(), vec![audit_with_weaker_req.clone()]);
@@ -967,6 +970,15 @@ fn mock_complex_core10_partially_too_weak_via_weak_delta() {
         .audits
         .insert("thirdAB".to_string(), vec![audit_with_weaker_req]);
 
+    config.policy.insert(
+        "thirdA".to_string(),
+        dep_policy([("third-core", ["weak-reviewed"])]),
+    );
+    config.policy.insert(
+        "thirdAB".to_string(),
+        dep_policy([("third-core", ["weak-reviewed"])]),
+    );
+
     let store = Store::mock(config, audits, imports);
     let report = crate::resolver::resolve(&metadata, None, &store, ResolveDepth::Shallow);
     assert_report_snapshot!(
@@ -994,11 +1006,7 @@ fn mock_complex_core10_partially_too_weak_via_strong_delta() {
         ],
     );
 
-    let audit_with_weaker_req = full_audit_dep(
-        ver(DEFAULT_VER),
-        "reviewed",
-        [("third-core", ["weak-reviewed"])],
-    );
+    let audit_with_weaker_req = full_audit(ver(DEFAULT_VER), "reviewed");
     audits
         .audits
         .insert("thirdA".to_string(), vec![audit_with_weaker_req.clone()]);
@@ -1010,6 +1018,14 @@ fn mock_complex_core10_partially_too_weak_via_strong_delta() {
         "firstA".to_string(),
         dep_policy([("third-core", ["weak-reviewed"])]),
     );
+    config.policy.insert(
+        "thirdA".to_string(),
+        dep_policy([("third-core", ["weak-reviewed"])]),
+    );
+    config.policy.insert(
+        "thirdAB".to_string(),
+        dep_policy([("third-core", ["weak-reviewed"])]),
+    );
 
     let store = Store::mock(config, audits, imports);
     let report = crate::resolver::resolve(&metadata, None, &store, ResolveDepth::Shallow);
@@ -1781,7 +1797,6 @@ fn builtin_simple_exemptions_in_direct_full() {
 #[test]
 fn builtin_simple_exemptions_nested_weaker_req() {
     // (Pass) A dep that has weaker requirements on its dep
-    // including dependency_criteria on an exemptions entry
 
     let _enter = TEST_RUNTIME.enter();
     let mock = MockMetadata::simple();
@@ -1792,18 +1807,8 @@ fn builtin_simple_exemptions_nested_weaker_req() {
     audits.audits.insert(
         "third-party1".to_string(),
         vec![
-            delta_audit_dep(
-                ver(3),
-                ver(6),
-                SAFE_TO_DEPLOY,
-                [("transitive-third-party1", [SAFE_TO_RUN])],
-            ),
-            delta_audit_dep(
-                ver(6),
-                ver(DEFAULT_VER),
-                SAFE_TO_DEPLOY,
-                [("transitive-third-party1", [SAFE_TO_RUN])],
-            ),
+            delta_audit(ver(3), ver(6), SAFE_TO_DEPLOY),
+            delta_audit(ver(6), ver(DEFAULT_VER), SAFE_TO_DEPLOY),
         ],
     );
     audits.audits.insert(
@@ -1814,64 +1819,9 @@ fn builtin_simple_exemptions_nested_weaker_req() {
         ],
     );
 
-    config.exemptions.insert(
-        "third-party1".to_string(),
-        vec![exemptions_dep(
-            ver(3),
-            SAFE_TO_DEPLOY,
-            [("transitive-third-party1", [SAFE_TO_RUN])],
-        )],
-    );
-
-    config.exemptions.insert(
-        "transitive-third-party1".to_string(),
-        vec![exemptions(ver(4), SAFE_TO_RUN)],
-    );
-
-    let store = Store::mock(config, audits, imports);
-    let report = crate::resolver::resolve(&metadata, None, &store, ResolveDepth::Shallow);
-
-    assert_report_snapshot!(
-        "builtin-simple-unaudited-nested-weaker-req",
-        &metadata,
-        report
-    );
-}
-
-#[test]
-fn builtin_simple_exemptions_nested_weaker_req_needs_dep_criteria() {
-    // (Fail) A dep that has weaker requirements on its dep
-    // but the exemptions entry is missing that so the whole thing fails
-
-    let _enter = TEST_RUNTIME.enter();
-    let mock = MockMetadata::simple();
-
-    let metadata = mock.metadata();
-    let (mut config, mut audits, imports) = builtin_files_full_audited(&metadata);
-
-    audits.audits.insert(
+    config.policy.insert(
         "third-party1".to_string(),
-        vec![
-            delta_audit_dep(
-                ver(3),
-                ver(6),
-                SAFE_TO_DEPLOY,
-                [("transitive-third-party1", [SAFE_TO_RUN])],
-            ),
-            delta_audit_dep(
-                ver(6),
-                ver(DEFAULT_VER),
-                SAFE_TO_DEPLOY,
-                [("transitive-third-party1", [SAFE_TO_RUN])],
-            ),
-        ],
-    );
-    audits.audits.insert(
-        "transitive-third-party1".to_string(),
-        vec![
-            delta_audit(ver(4), ver(8), SAFE_TO_RUN),
-            delta_audit(ver(8), ver(DEFAULT_VER), SAFE_TO_RUN),
-        ],
+        dep_policy([("transitive-third-party1", [SAFE_TO_RUN])]),
     );
 
     config.exemptions.insert(
@@ -1888,7 +1838,7 @@ fn builtin_simple_exemptions_nested_weaker_req_needs_dep_criteria() {
     let report = crate::resolver::resolve(&metadata, None, &store, ResolveDepth::Shallow);
 
     assert_report_snapshot!(
-        "builtin-simple-unaudited-nested-weaker-req-needs-dep-criteria",
+        "builtin-simple-unaudited-nested-weaker-req",
         &metadata,
         report
     );
@@ -1908,22 +1858,16 @@ fn builtin_simple_exemptions_nested_stronger_req() {
         "first-party".to_string(),
         dep_policy([("third-party1", [SAFE_TO_RUN])]),
     );
+    config.policy.insert(
+        "third-party1".to_string(),
+        dep_policy([("transitive-third-party1", [SAFE_TO_DEPLOY])]),
+    );
 
     audits.audits.insert(
         "third-party1".to_string(),
         vec![
-            delta_audit_dep(
-                ver(3),
-                ver(6),
-                SAFE_TO_RUN,
-                [("transitive-third-party1", [SAFE_TO_DEPLOY])],
-            ),
-            delta_audit_dep(
-                ver(6),
-                ver(DEFAULT_VER),
-                SAFE_TO_RUN,
-                [("transitive-third-party1", [SAFE_TO_DEPLOY])],
-            ),
+            delta_audit(ver(3), ver(6), SAFE_TO_RUN),
+            delta_audit(ver(6), ver(DEFAULT_VER), SAFE_TO_RUN),
         ],
     );
     audits.audits.insert(
@@ -2688,103 +2632,3 @@ fn builtin_simple_mega_foreign_tag_team() {
 
     assert_report_snapshot!("builtin_simple_mega_foreign_tag_team", &metadata, report);
 }
-
-#[test]
-fn builtin_simple_foreign_dep_criteria_fail() {
-    // (Fail) Vetting hinges on some foreign audit with non-local depenency_criteria
-    // In this case we're "forced" to suggest a foreign audit
-
-    let _enter = TEST_RUNTIME.enter();
-    let mock = MockMetadata::simple();
-
-    let metadata = mock.metadata();
-    let (mut config, mut audits, mut imports) = builtin_files_full_audited(&metadata);
-    audits.audits.remove("third-party1");
-    imports.audits.insert(
-        FOREIGN.to_owned(),
-        AuditsFile {
-            criteria: [(DEFAULT_CRIT.to_owned(), criteria("nice"))]
-                .into_iter()
-                .collect(),
-            audits: [(
-                "third-party1".to_owned(),
-                vec![full_audit_dep(
-                    ver(DEFAULT_VER),
-                    SAFE_TO_DEPLOY,
-                    [("transitive-third-party1", [DEFAULT_CRIT])],
-                )],
-            )]
-            .into_iter()
-            .collect(),
-        },
-    );
-    config.imports.insert(
-        FOREIGN.to_owned(),
-        crate::format::RemoteImport {
-            url: FOREIGN_URL.to_owned(),
-            ..Default::default()
-        },
-    );
-
-    let store = Store::mock(config, audits, imports);
-    let report = crate::resolver::resolve(&metadata, None, &store, ResolveDepth::Shallow);
-
-    assert_report_snapshot!(
-        "builtin_simple_foreign_dep_criteria_fail",
-        &metadata,
-        report
-    );
-}
-
-#[test]
-fn builtin_simple_foreign_dep_criteria_pass() {
-    // (Fail) Vetting hinges on some foreign audit with non-local depenency_criteria
-    // In this case we're "forced" to suggest a foreign audit
-
-    let _enter = TEST_RUNTIME.enter();
-    let mock = MockMetadata::simple();
-
-    let metadata = mock.metadata();
-    let (mut config, mut audits, mut imports) = builtin_files_full_audited(&metadata);
-    audits.audits.remove("third-party1");
-    imports.audits.insert(
-        FOREIGN.to_owned(),
-        AuditsFile {
-            criteria: [(DEFAULT_CRIT.to_owned(), criteria("nice"))]
-                .into_iter()
-                .collect(),
-            audits: [
-                (
-                    "third-party1".to_owned(),
-                    vec![full_audit_dep(
-                        ver(DEFAULT_VER),
-                        SAFE_TO_DEPLOY,
-                        [("transitive-third-party1", [DEFAULT_CRIT])],
-                    )],
-                ),
-                (
-                    "transitive-third-party1".to_owned(),
-                    vec![full_audit(ver(DEFAULT_VER), DEFAULT_CRIT)],
-                ),
-            ]
-            .into_iter()
-            .collect(),
-        },
-    );
-    config.imports.insert(
-        FOREIGN.to_owned(),
-        crate::format::RemoteImport {
-            url: FOREIGN_URL.to_owned(),
-            ..Default::default()
-        },
-    );
-
-    let store = Store::mock(config, audits, imports);
-    let report = crate::resolver::resolve(&metadata, None, &store, ResolveDepth::Shallow);
-
-    assert_report_snapshot!(
-        "builtin_simple_foreign_dep_criteria_pass",
-        &metadata,
-        report
-    );
-}
diff --git a/tests/snapshots/test_cli__markdown-help.snap b/tests/snapshots/test_cli__markdown-help.snap
index 40a3a51..4b8e967 100644
--- a/tests/snapshots/test_cli__markdown-help.snap
+++ b/tests/snapshots/test_cli__markdown-help.snap
@@ -363,11 +363,6 @@ The criteria to certify for this audit
 
 If not provided, we will prompt you for this information.
 
-#### `--dependency-criteria <DEPENDENCY_CRITERIA>`
-The dependency-criteria to require for this audit to be valid
-
-If not provided, we will still implicitly require dependencies to satisfy `criteria`.
-
 #### `--who <WHO>`
 Who to name as the auditor
 
@@ -527,11 +522,6 @@ The criteria to assume (trust)
 
 If not provided, we will prompt you for this information.
 
-#### `--dependency-criteria <DEPENDENCY_CRITERIA>`
-The dependency-criteria to require for this exemption to be valid
-
-If not provided, we will still implicitly require dependencies to satisfy `criteria`.
-
 #### `--notes <NOTES>`
 A free-form string to include with the new forbid entry
 
diff --git a/tests/test-project/supply-chain/audits.toml b/tests/test-project/supply-chain/audits.toml
index be9d15a..ab370a6 100644
--- a/tests/test-project/supply-chain/audits.toml
+++ b/tests/test-project/supply-chain/audits.toml
@@ -72,7 +72,6 @@ delta = "0.2.0 -> 1.3.2"
 [[audits.clap]]
 criteria = "safe-to-deploy"
 version = "3.1.8"
-dependency-criteria = { atty = "safe-to-run", bitflags = ["audited", "fuzzed"] }
 notes = "test for custom criteria (low-grade and high-grade)"
 
 [[audits.syn]]
diff --git a/tests/test-project/supply-chain/config.toml b/tests/test-project/supply-chain/config.toml
index 1d709d3..b6a8adb 100644
--- a/tests/test-project/supply-chain/config.toml
+++ b/tests/test-project/supply-chain/config.toml
@@ -1,6 +1,9 @@
 
 # cargo-vet config file
 
+[policy.clap]
+dependency-criteria = { atty = "safe-to-run", bitflags = ["audited", "fuzzed"] }
+
 [policy.proc-macro2]
 audit-as-crates-io = true