Skip to content

Add certs expiry params#456

Merged
evgeni merged 6 commits intotheforeman:masterfrom
ShimShtein:add_certs_expiry_params
Apr 28, 2026
Merged

Add certs expiry params#456
evgeni merged 6 commits intotheforeman:masterfrom
ShimShtein:add_certs_expiry_params

Conversation

@ShimShtein
Copy link
Copy Markdown
Member

Why are you introducing these changes? (Problem description, related links)

https://redhat.atlassian.net/browse/SAT-43479

We need to expose the certificate validity to the users, so it would be possible to align it with the local security policies.

What are the changes introduced in this pull request?

  • Created new ansible variables to parameterize the expiration date
  • Exposed the variables to the user through metadata.obsah.yaml

How to test this pull request

Steps to reproduce:

  • Run an installation procedure
  • Make sure to set custom expiration for each of the parameters
  • Validate the expiration of certificates

Checklist

  • Tests added/updated (if applicable)
  • Documentation updated (if applicable)

@ShimShtein
Copy link
Copy Markdown
Member Author

@stejskalleos One thing I see already as a problem: the certs are not regenerated if I change the expiry date.

@evgeni
Copy link
Copy Markdown
Member

evgeni commented Apr 20, 2026

@evgeni
Copy link
Copy Markdown
Member

evgeni commented Apr 20, 2026

/packit build

@ShimShtein
Copy link
Copy Markdown
Member Author

@evgeni should we switch to absolute timestamps then? Maybe it will make more sense to us, so we will be able to prolong the validity without too much hassle?

@evgeni
Copy link
Copy Markdown
Member

evgeni commented Apr 20, 2026

My gut feeling is that it wouldn't make the UX any better, but I might have not thought is through completely.

@ShimShtein
Copy link
Copy Markdown
Member Author

I would say that the client and server certs are safe to regenerate, which is not really possible without the option (unless we want to split it into a different feature).
For the CA it's a bit more problematic, since we will need to create a specific merged CA cert, distribute it and switch to a new one. I would vote not to allow the regeneration altogether (only by deleting the current cert).

@evgeni
Copy link
Copy Markdown
Member

evgeni commented Apr 20, 2026

You don't want to regenerate certificates continuously. This will trigger service restarts, which users don't like. And also could have negative effects if people use certificate pinning or similar (based on the actual cert, not the CA, this is clearly "don't do it like this" territory, but often people don't listen to such advice). Also, this is kinda against the whole idea of certificate validity, as it just pushes it out "forever".

So we could either use absolute timestamps (which means we'd have to store them), or dynamically set ignore_timestamps=false when the user indicates they actually want to perform a certificate renewal?

@ShimShtein
Copy link
Copy Markdown
Member Author

I was thinking about using absolute timestamps, as I said previously.
So what I thought was:

  1. Use absolute timestamps for all three fields (ca, server, client)
  2. Set the ignore_timestamps statically to false for server and client
  3. Add a regenerate_ca flag that will control the ignore_timestamps for the CA field.

What do you think, would it make more sense? This way we enable easy change to the more common certs, and a confirmation flag to CA, that requires more attention from the user.

@evgeni
Copy link
Copy Markdown
Member

evgeni commented Apr 20, 2026

In your setup, how would a user renew certificates that are bound to expire in (say) two weeks?

@ShimShtein
Copy link
Copy Markdown
Member Author

If we are talking about server or client certs it would be running

foremanctl deploy --cert-server-validity 20-04-2027 --cert-client-validity 20-04-2027

But if the user wants to change the CA validity, then it would be something like

foremanctl deploy --cert-ca-validity 20-04-2027 --regenerate-ca

@evgeni
Copy link
Copy Markdown
Member

evgeni commented Apr 20, 2026

Okay. And my alternative (for server/client) would be:
Define the validity once via foremanctl --certificate-days 7300
Renew at any time with foremanctl --certificate-renew
(Or whatever the names end up with, thats not important)

Does anyone else have an opinion/preference?

@stejskalleos stejskalleos self-assigned this Apr 20, 2026
@ekohl
Copy link
Copy Markdown
Member

ekohl commented Apr 20, 2026

I think a user wants minimal downtime and secure communication. For that we chose to use certificates and they need to be valid.

@evgeni already mentioned to avoid service restarts due to certificate changes, but downtime can also be caused by expired certificates.

How do we translate that into a process and parameters? You need to create a certificate and determine a validity period (measured in days). Then you also need to determine when to renew. That probably shouldn't be the validity period, otherwise you'll renew it all the time.

Let's Encrypt has proposed a process via RFC 9773. While I don't expect us to implement this right now, I like the idea and we can learn from the concepts. suggestedWindow jumps out to me: can we also determine this for our certificates?

A basic implementation to have a minimum validity period.

Define the validity once via foremanctl --certificate-days 7300

I like this.

Renew at any time with foremanctl --certificate-renew

I'm thinking of automating it and avoid introducing new parameters by using a formula. For example, take half the certificate_days but at most renew every 30 days: min(certificate_days / 2, 30).

I don't know if this also works for the CA or it needs a more nuanced implementation.

@ShimShtein
Copy link
Copy Markdown
Member Author

If we will introduce a single --certificate-renew flag, we won't be able to manage separate validity periods. I would suggest having a parameter per certificate type (ca, client, server).
Specifically for the CA, the problem is that we need to distribute the new CA in a secure way (which means installing a dual CA for a while on the server, distributing the new CA to all the known clients and reinstalling the new CA on the server). I would argue that the CA renewal process should be handled by a separate command.
The problem with automation is not about regeneating the certs, it's about distributing those certs to the clients (smart proxies). This means keeping a list of all known hosts (we can derive it from the list of smart-proxies in Foreman) and orchestrating the upload of the certificates to those hosts.

@evgeni
Copy link
Copy Markdown
Member

evgeni commented Apr 21, 2026

while I can see different validity for CA and non-CA, I see no reason to differentiate between server and client certs.

@ShimShtein
Copy link
Copy Markdown
Member Author

I think I have addressed everything. How does it look now?

@ekohl
Copy link
Copy Markdown
Member

ekohl commented Apr 21, 2026

Should we track the renewal in the same PR? I think there's a lot to discuss on that topic and I don't think we should hold up adding the expiration params on that.

Comment thread src/roles/certificates/tasks/issue.yml Outdated
Comment thread src/roles/certificates/tasks/issue.yml Outdated
Comment thread src/roles/certificates/tasks/issue.yml Outdated
@evgeni
Copy link
Copy Markdown
Member

evgeni commented Apr 21, 2026

Should we track the renewal in the same PR? I think there's a lot to discuss on that topic and I don't think we should hold up adding the expiration params on that.

I think the current state is "good enough" to be used as a starting ground for any follow up discussions if needed (or to be ripped out, if we decide to go a different route).

Comment thread src/playbooks/_certificate_validity/metadata.obsah.yaml Outdated
Comment thread src/roles/certificates/tasks/issue.yml Outdated
Comment thread src/vars/default_certificates.yml Outdated
Comment thread src/vars/installer_certificates.yml Outdated
help: Lifetime of the generated server and client certificates, in days.
parameter: --certificate-validity-days
certificates_renew:
help: Remove and regenerate server and client certificates for each issued hostname (does not regenerate the CA).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
help: Remove and regenerate server and client certificates for each issued hostname (does not regenerate the CA).
help: Regenerate server and client certificates for each issued hostname (does not regenerate the CA).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd start the last bit as a new sentence. Also questioning if the "for each issued hostname" is really relevant. How about:

Suggested change
help: Remove and regenerate server and client certificates for each issued hostname (does not regenerate the CA).
help: Force renewal of the server and client certificates. Does not regenerate the CA.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As we're adding custom certs in #462 and those would not be renewed by this, I wonder if there is a word we could use to differentiate the certs here. Something like "managed server and client certificates"? Doesn't have to be solved in this PR, but having clear wording which movable parts of the stack are "bring your own" and which are "we do it for you" would be cool.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The old default CA and server CA naming was really poor, but I struggle to come up with something better. Internal vs External perhaps?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

"Force renewal of the server and client certificates issued by the internal CA."? Sounds cludgy.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

What about Regenrate server and client certificates previously generated by foremanctl. Does not regenerate the CA.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Technically they are not regenerated (the private and public keys remain the same, only the signature changes), but I don't really mind.

ownca_privatekey_passphrase: "{{ certificates_ca_password }}"
ownca_not_after: "+7300d"
ownca_not_after: "+{{ certificates_validity_days }}d"
force: "{{ certificates_renew | bool }}"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

IMHO here we see the real value of using community.crypto. With our hand crafted openssl statements this would have been a pain.

certificates_cnames: []
certificates_algorithm_type: RSA
certificates_algorithm_size: 4096
# Validity periods in days (used as +Nd for community.crypto not_after).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A bit nitpicky here -- the variable name tells me this information already. And I do not understand the part in parenthesis to feel like it adds value.

Copy link
Copy Markdown
Member

@ehelms ehelms left a comment

Choose a reason for hiding this comment

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

This is missing documentation updates and tests at least for the renew workflow.

@ShimShtein
Copy link
Copy Markdown
Member Author

Updated the documentation, but couldn't understand how to properly add a test that will rerun the installer.

Comment thread docs/user/certificates.md
Comment thread docs/user/certificates.md
Comment thread docs/user/certificates.md Outdated
Comment on lines +2 to +11
variables:
certificates_ca_validity_days:
help: Lifetime of the generated CA certificate, in days.
parameter: --certificate-ca-validity-days
certificates_validity_days:
help: Lifetime of the generated server and client certificates, in days.
parameter: --certificate-validity-days
certificates_renew:
help: Regenrate server and client certificates previously generated by foremanctl. Does not regenerate the CA.
parameter: --certificate-renew
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If I set the expiration period for both the client and server certificates to 5 days each, my question is whether the customer will receive a notification before the certificates expire, as I do not see that happening here.

My second point is that --certificate-renew does not renew the CA certificate. If I set the CA certificate validity to 5 days, how will the CA certificate be renewed?

Also, you mentioned that the certificate is considered to have a lifetime. What exactly does that mean if I explicitly set its validity period to 5 days?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

whether the customer will receive a notification before the certificates expire, as I do not see that happening here.

Is it something that we previously set up?

My second point is that --certificate-renew does not renew the CA certificate. If I set the CA certificate validity to 5 days, how will the CA certificate be renewed?

We have discussed it previously: CA renewal is a process and I want to treat it in a separate story.

Also, you mentioned that the certificate is considered to have a lifetime. What exactly does that mean if I explicitly set its validity period to 5 days?

I may be missing something, but if you set validity period to 5 days, it means that the lifetime of the certificate would be 5 days from the run of the module.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

whether the customer will receive a notification before the certificates expire, as I do not see that happening here.

Is it something that we previously set up?

I guess no, i do not see in the old installer.

Copy link
Copy Markdown

@amolpati30 amolpati30 Apr 27, 2026

Choose a reason for hiding this comment

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

If the server and client certificates have expired and I want to renew them, will this work using this option?
foremanctl deploy --certificate-validity-days 365 --certificate-renew or
foremanctl deploy --certificate-renew

I tried renewing the expired server and client certificates, but it does not seem to be supported. Is it required to have a valid CA certificate first before renewing the server and client certificates?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

foremanctl deploy --certificate-renew should be sufficient, in my understanding

was the CA expired too?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

You can do both. In the shorter case, I guess you will be getting the default validity (7300 days). Unless @evgeni says that we preserve the validity days parameter by default.

Copy link
Copy Markdown
Member Author

@ShimShtein ShimShtein Apr 27, 2026

Choose a reason for hiding this comment

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

Is it required to have a valid CA certificate first before renewing the server and client certificates?

Yes, the CA has to be valid. We are signing the server and client certs with the CA.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

foremanctl deploy --certificate-renew should be sufficient, in my understanding

was the CA expired too?

Yes, the CA certificate has also expired.

Copy link
Copy Markdown
Member

@evgeni evgeni Apr 27, 2026

Choose a reason for hiding this comment

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

You can do both. In the shorter case, I guess you will be getting the default validity (7300 days). Unless @evgeni says that we preserve the validity days parameter by default.

If you haven't marked it as persist: false, it will of course be preserved (which I think is the correct way to do it)

@ShimShtein ShimShtein force-pushed the add_certs_expiry_params branch from 8c8f3d7 to 77fee5f Compare April 26, 2026 12:52
Comment thread docs/user/certificates.md Outdated
Copy link
Copy Markdown
Member

@evgeni evgeni left a comment

Choose a reason for hiding this comment

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

wording nitpick, but otherwise ACK

@ShimShtein ShimShtein force-pushed the add_certs_expiry_params branch from 77fee5f to 3484cc6 Compare April 27, 2026 10:15
@ShimShtein
Copy link
Copy Markdown
Member Author

All the certs were fixed.

Copy link
Copy Markdown

@amolpati30 amolpati30 left a comment

Choose a reason for hiding this comment

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

I have done below testing scenarios here to validate the certificates:

Verify that the default validity period is correctly applied to the certificates.

Explicitly set the certificate validity period, validate it, and then update the server and client certificate validity again using the --certificate-renew parameter, followed by validation.

@evgeni evgeni merged commit acd6faf into theforeman:master Apr 28, 2026
18 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants