Skip to content

Conversation

@rdoxenham
Copy link

This commit adds support for providing custom CA certificates during the build process. It allows a user to specify a path to a local directory, either by updating kiwi.yml with ca_certificates:path, or by passing --ca-certificates=<directory> via the command line.

The code looks for all *.pem, *.crt, and *.crt files in the specified directory and imports them immediately post bootstrap (where the required CA update tools are available), but before any further packages are retrieved, solving for situations where the chroot environment needs certificates, e.g. when there's a proxy server in the build environment.

Reference: #2721

@schaefi schaefi requested review from Conan-Kudo and schaefi December 5, 2025 09:25
@schaefi
Copy link
Collaborator

schaefi commented Dec 5, 2025

Hey @rdoxenham this is great work thank you very much 👍

I hope you don't mind I pushed a commit to fix the tests

Other than that there is a bit of "metadata" to complete the change. Can you please do the following

  • There is a kiwi.yml file which contains all possible options as comments. Can you please add your new runtime config setup there too ?
  • Your patch adds a new commandline option. Can you please add documentation for it to the man pages in doc/source/commands

Would be great thanks in advance

@Conan-Kudo
Copy link
Member

This needs a stanza in the XML too.

@schaefi
Copy link
Collaborator

schaefi commented Dec 5, 2025

@rdoxenham ah sorry I saw you already added the docs topics... nevermind forget what I said :)

@schaefi
Copy link
Collaborator

schaefi commented Dec 5, 2025

This needs a stanza in the XML too.

I agree, it could also be added in a followup PR though

@rdoxenham
Copy link
Author

This needs a stanza in the XML too.

I agree, it could also be added in a followup PR though

I actually have some questions about this from #2721... do you expect for it to be something like:

<certificates>
    <certificate name="/path/to/certificate1.pem"/>
    <certificate name="/path/to/certificate2.pem"/>
</certificates>

Otherwise, I'm curious as to what would be placed into each entry other than a path?

@schaefi
Copy link
Collaborator

schaefi commented Dec 5, 2025

I actually have some questions about this from #2721... do you expect for it to be something like:

<certificates>
    <certificate name="/path/to/certificate1.pem"/>
    <certificate name="/path/to/certificate2.pem"/>
</certificates>

Otherwise, I'm curious as to what would be placed into each entry other than a path?

Yes it would be good to add this new <certificates> section. As you implemented in a way that you take all certs from a path I'm fine if you add something like this

<certificates>
    <certificate path="/some/path"/>
</certificates>

We should allow for more than one entry though. In the commandline implementation we allow --ca-certificates only once. you can consider to allow this option multiple times. This would then return a list and you would be compatible with the XML stanza

@rdoxenham
Copy link
Author

Yes it would be good to add this new <certificates> section. As you implemented in a way that you take all certs from a path I'm fine if you add something like this

<certificates>
    <certificate path="/some/path"/>
</certificates>

We should allow for more than one entry though. In the commandline implementation we allow --ca-certificates only once. you can consider to allow this option multiple times. This would then return a list and you would be compatible with the XML stanza

Are you ok with this being a follow-up change?

@Conan-Kudo
Copy link
Member

I would prefer it to be part of this change.

@rdoxenham
Copy link
Author

I would prefer it to be part of this change.

Understood. Can you and @schaefi help me with expected behaviour, please? We're introducing three different ways of specifying additional CA certificates to import:

  1. Via --ca-certificates=/path entries in the CLI
  2. Via ca_certificates:path[] in kiwi.yml runtime configuration
  3. Via <certificate path=".."/> elements in the XML state

In the current PR, (1) is favoured over (2). How do you envisage this happening with (3)? The way I'm thinking about it is still one or the other, in that if either (1) or (3) are specified, they override (2), yet if both (1) and (3) are specified then they're combined into a single list. Written more easily:

  • Entries only in kiwi.yml --> Only these are used
  • Entries in kiwi.yml and either --ca-certificates or <certificate path=".."/> --> kiwi.yml is ignored
  • As above, but if --ca-certificates and <certificate path=".."/> --> one longer list is used, kiwi.yml is still ignored

Thoughts? Is the original plan of ignoring kiwi.yml even a good idea, or should it always be considered, regardless of others being specified?

@Conan-Kudo
Copy link
Member

None of them should be ignored. It's combinatorial.

@schaefi
Copy link
Collaborator

schaefi commented Dec 5, 2025

@rdoxenham Thinking more about it I believe the implementation to read certificates from the the kiwi runtime config might be an uncommon place. The kiwi.yml runtime config actually only contains settings that affects kiwi as a builder. For example compression options or how to bundle results, etc etc. As of today there are no settings in the runtime config that affects the image to build. Therefore you could also think of dropping the reading of certificates from the runtime config and stick to only two places:

  • commandline
  • image description

The two source of information should be combined.

We have similar implementation already in kiwi for example for the handling of the repositories. You can specify them on the commandline and also in the image description. From an implementation perspective the way how we approach this is as follows:

  1. Create the needed modifications to the schema file kiwi/schema/kiwi.rnc
  2. make sure to call poetry shell now which drops you into an env such that the following works
  3. When you are done with the schema changes call make kiwi/schema/kiwi.rng This call auto generates the schema and the data structures such that they can be consumed by python. (In a future project I plan to add some AI here to make this even easier by just expressing a high level structure change and this performs the needed rnc adaptions :)) But for today you still need to work with the kiwi.rnc file.
  4. When this is done you have access to a new data structure API to read the certificates (get_certificates() , get_certificate(), get_path()) Use this API to read the data as you like to work with it in the kiwi code base. I usually create a method in kiwi/xml_state.py to provide a statefull method for this data.
  5. When you are done with this part you can modify the way how you approach the commandline implementation. The code that handles --ca-certificates should now also use the generated API and transfer the commandline data into the internal data structure by using (set_certificates(), set_certificate(), set_path()). You can use the existing implementation for the repos to get a better understanding if you need to

When doing it that way you also automatically set the precedence for the data which is that the value from the command line may overwrite the data read from the image description

I hope this helps to make you started.

Thanks much

@schaefi
Copy link
Collaborator

schaefi commented Dec 26, 2025

@rdoxenham I hope you don't mind, I have added new commits that implements the suggested change from my last comment. Would be great if you can review the code changes and share your thoughts about it.

With the latest changes we can now specify an optional <certificates> section as discussed. The command-line option I renamed to ca-cert-path and allow it to be specified multiple times. The command-line option handling operates as follows:

  • no <certificates> section present, the first ca-cert-path option would create one using the image description data structure. Any subsequent option would add to it
  • existing <certificates> section, ca-cert-path options are added

Thanks

@schaefi schaefi force-pushed the ca-certificates branch 2 times, most recently from f5fd8ae to 0c09ac8 Compare December 26, 2025 22:51
@schaefi
Copy link
Collaborator

schaefi commented Dec 26, 2025

I we agree this is good to go, feel free to squash commits into one

Comment on lines 139 to 141
<certificates>
<certificate path="/some/path"/>
</certificates>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make sense to list files instead of directories? I don't like the idea of just wholesale importing random files.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not importing random files. @rdoxenham has implemented it in a way that the files from the directory are checked against their prefix to match as a certificate file. I'd like to get feedback from Rhys first to see if that directory import is based on some design pattern.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is no strong design pattern involved here I agree with you that specifying single files is better and more specific

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that even if there was, that pattern is localized to Rhys' setup. As this would be available to everyone, that is a risky proposition.

Plus, usually people import cert bundle files or specialty certs (like a local intranet certificate).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I believe this is enough risk analysis to add a commit that moves this implementation to file based cert setup. But now let's wait for @rdoxenham as I have touched his code a lot :)

Thanks

rdoxenham and others added 6 commits January 3, 2026 21:40
This commit adds support for providing custom CA certificates during the build
process. It allows a user to specify a path to a local directory, either by
updating `kiwi.yml` with `ca_certificates:path`, or by passing
`--ca-certificates=<directory>` via the command line.

The code looks for all `*.pem`, `*.crt`, and `*.crt` files in the specified
directory and imports them immediately post bootstrap (where the required
CA update tools are available), but before any further packages are retrieved,
solving for situations where the chroot environment needs certificates, e.g.
when there's a proxy server in the build environment.

Reference: OSInside#2721
Rename commandline option to ca-cert-path and allow it to
be specified multiple times. Update setup_ca_certificates
to work with a list
In addition to the commandline handling, the certificates
should also be able to get specified in the image description
Update implementation for setup_ca_certificates to read
from xml_state.get_certificates() only. In addition update
the handling of the commandline argument ca-cert-path
to add, create or overwrite into the image description
data structure
Instead of dir based, only allow for file based cert
setup. This commit was done due to review comments
stating issues when syncing arbitrary directory content
@rdoxenham
Copy link
Author

Hey @schaefi! Happy New Year :) my apologies for the slow reply to this. Thanks so much for taking the action to follow-up on this; I had planned on getting to it at some point in the first few weeks of 2026, but I'm very glad to see that you've made the progress, so I certainly do not mind you doing this 👍

As @Conan-Kudo suggests, the pattern that I was originally targeting was to more easily support our containerised Kiwi workflow; in this instance, we'd expect the user to simply bind mount a directory containing their certificates to the container, and we'd iterate over all certificate files found (I specifically chose crt/pem/cer files for this). However, I can see that this may introduce some risks.

I think the path proposed here with files rather than directories can also work; it means a little more effort required for the containerised workflow, but I also see this as a fairly rare use-case, so I don't think it should become a blocker as far as I'm concerned.

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants