Skip to content

Commit 1535ded

Browse files
jbtrystramcgwalters
authored andcommitted
install: Add a config knob for container sigpolicy
Surface the `--enforce-container-sigpolicy` flag as a config file option. Fixes bootc-dev#2112 Assisted-by: OpenCode.ai <Opus 4.6> Signed-off-by: jbtrystram <jbtrystram@redhat.com>
1 parent 0827b14 commit 1535ded

3 files changed

Lines changed: 85 additions & 21 deletions

File tree

crates/lib/src/install.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,7 +1536,7 @@ async fn verify_target_fetch(
15361536
async fn prepare_install(
15371537
mut config_opts: InstallConfigOpts,
15381538
source_opts: InstallSourceOpts,
1539-
target_opts: InstallTargetOpts,
1539+
mut target_opts: InstallTargetOpts,
15401540
mut composefs_options: InstallComposefsOpts,
15411541
target_fs: Option<FilesystemEnum>,
15421542
) -> Result<Arc<State>> {
@@ -1584,6 +1584,33 @@ async fn prepare_install(
15841584
}
15851585
};
15861586

1587+
// Load install configuration from TOML drop-in files early, so that
1588+
// config values are available when constructing the target image reference.
1589+
let install_config = config::load_config()?;
1590+
if let Some(ref config) = install_config {
1591+
tracing::debug!("Loaded install configuration");
1592+
// Merge config file values into config_opts (CLI takes precedence)
1593+
// Only apply config file value if CLI didn't explicitly set it
1594+
if !config_opts.bootupd_skip_boot_uuid {
1595+
config_opts.bootupd_skip_boot_uuid = config
1596+
.bootupd
1597+
.as_ref()
1598+
.and_then(|b| b.skip_boot_uuid)
1599+
.unwrap_or(false);
1600+
}
1601+
1602+
if config_opts.bootloader.is_none() {
1603+
config_opts.bootloader = config.bootloader.clone();
1604+
}
1605+
1606+
if !target_opts.enforce_container_sigpolicy {
1607+
target_opts.enforce_container_sigpolicy =
1608+
config.enforce_container_sigpolicy.unwrap_or(false);
1609+
}
1610+
} else {
1611+
tracing::debug!("No install configuration found");
1612+
}
1613+
15871614
// Parse the target CLI image reference options and create the *target* image
15881615
// reference, which defaults to pulling from a registry.
15891616
if target_opts.target_no_signature_verification {
@@ -1671,26 +1698,6 @@ async fn prepare_install(
16711698
println!("Digest: {digest}");
16721699
}
16731700

1674-
let install_config = config::load_config()?;
1675-
if let Some(ref config) = install_config {
1676-
tracing::debug!("Loaded install configuration");
1677-
// Merge config file values into config_opts (CLI takes precedence)
1678-
// Only apply config file value if CLI didn't explicitly set it
1679-
if !config_opts.bootupd_skip_boot_uuid {
1680-
config_opts.bootupd_skip_boot_uuid = config
1681-
.bootupd
1682-
.as_ref()
1683-
.and_then(|b| b.skip_boot_uuid)
1684-
.unwrap_or(false);
1685-
}
1686-
1687-
if config_opts.bootloader.is_none() {
1688-
config_opts.bootloader = config.bootloader.clone();
1689-
}
1690-
} else {
1691-
tracing::debug!("No install configuration found");
1692-
}
1693-
16941701
let root_filesystem = target_fs
16951702
.or(install_config
16961703
.as_ref()

crates/lib/src/install/config.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ pub(crate) struct InstallConfiguration {
129129
/// Interface (systemd-boot always does, GRUB needs the `bli` module).
130130
/// Defaults to false for broad compatibility.
131131
pub(crate) discoverable_partitions: Option<bool>,
132+
/// Enforce that the containers-storage stack has a non-default
133+
/// (i.e. not `insecureAcceptAnything`) container image signature policy.
134+
pub(crate) enforce_container_sigpolicy: Option<bool>,
132135
}
133136

134137
fn merge_basic<T>(s: &mut Option<T>, o: Option<T>, _env: &EnvProperties) {
@@ -218,6 +221,11 @@ impl Mergeable for InstallConfiguration {
218221
other.discoverable_partitions,
219222
env,
220223
);
224+
merge_basic(
225+
&mut self.enforce_container_sigpolicy,
226+
other.enforce_container_sigpolicy,
227+
env,
228+
);
221229
if let Some(other_kargs) = other.kargs {
222230
self.kargs
223231
.get_or_insert_with(Default::default)
@@ -940,3 +948,46 @@ root-fs-type = "xfs"
940948
.unwrap();
941949
assert_eq!(c.install.unwrap().discoverable_partitions, None);
942950
}
951+
952+
#[test]
953+
fn test_parse_enforce_container_sigpolicy() {
954+
let env = EnvProperties {
955+
sys_arch: "x86_64".to_string(),
956+
};
957+
958+
// Test parsing true and false
959+
for (input, expected) in [("true", true), ("false", false)] {
960+
let toml_str = format!(
961+
r#"[install]
962+
enforce-container-sigpolicy = {input}
963+
"#
964+
);
965+
let c: InstallConfigurationToplevel = toml::from_str(&toml_str).unwrap();
966+
assert_eq!(
967+
c.install.unwrap().enforce_container_sigpolicy.unwrap(),
968+
expected
969+
);
970+
}
971+
972+
// Default (not specified) is None
973+
let c: InstallConfigurationToplevel = toml::from_str(
974+
r#"[install]
975+
root-fs-type = "xfs"
976+
"#,
977+
)
978+
.unwrap();
979+
assert!(c.install.unwrap().enforce_container_sigpolicy.is_none());
980+
981+
// Test merging: last write wins
982+
let mut install: InstallConfiguration = toml::from_str(
983+
r#"enforce-container-sigpolicy = false
984+
"#,
985+
)
986+
.unwrap();
987+
let other = InstallConfiguration {
988+
enforce_container_sigpolicy: Some(true),
989+
..Default::default()
990+
};
991+
install.merge(other, &env);
992+
assert_eq!(install.enforce_container_sigpolicy.unwrap(), true);
993+
}

docs/src/man/bootc-install-config.5.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ The `install` section supports these subfields:
3939
implement the Boot Loader Interface (BLI); systemd-boot always does, GRUB
4040
needs the `bli` module (available in newer builds). Defaults to `true`
4141
when using systemd-boot, `false` otherwise.
42+
- `enforce-container-sigpolicy`: A boolean that controls whether to enforce that
43+
`/etc/containers/policy.json` includes a default policy which requires signatures.
44+
When `true`, image pulls will be rejected if the policy file specifies
45+
`insecureAcceptAnything` as the default. Defaults to `false`.
46+
This is equivalent to the `--enforce-container-sigpolicy` CLI flag.
4247

4348
# filesystem
4449

@@ -79,6 +84,7 @@ kargs = ["nosmt", "console=tty0"]
7984
stateroot = "myos"
8085
root-mount-spec = "LABEL=rootfs"
8186
boot-mount-spec = "UUID=abcd-1234"
87+
enforce-container-sigpolicy = true
8288

8389
[install.ostree]
8490
bls-append-except-default = 'grub_users=""'

0 commit comments

Comments
 (0)