Skip to content

Add custom lints covering our CP/CPS profiles - #8485

Open
aarongable wants to merge 14 commits into
mainfrom
cps-lints
Open

Add custom lints covering our CP/CPS profiles#8485
aarongable wants to merge 14 commits into
mainfrom
cps-lints

Conversation

@aarongable

@aarongable aarongable commented Nov 8, 2025

Copy link
Copy Markdown
Contributor

Add five new custom zlint lints, each covering one of the profiles listed in Version TKTK of our CP/CPS:

  • Root CA Certificate
  • Cross-Certified Subordinate CA Certificate
  • TLS Subordinate CA Certificate
  • Subscriber Server Certificate
  • Precertificate

Each lint walks down the corresponding table in our CP/CPS, checking each row in order. Every check includes a quote of the relevant statement and a link to the exact commit and line of our CP/CPS. This will allow us to automated enforcement of updates to our lints when our CP/CPS changes, and vice versa.

Several of the items in our CP/CPS profiles state that our certificates either match their issuer certificate, or (for Cross-Certified certs) match a pre-existing certificate. In order to support this, abuse zlint's configuration mechanism to allow us to configure the issuer and pre-existing cert before each lint run. Each of the new lints uses the configured issuer to perform several of its checks, and fails the lint if not so configured.

Fixes #5492

An LLM was used to generate three of the lints in the style of the first two hand-written ones, and to generate some test cases for all five.

Warning

DO NOT MERGE until we are confident that we are going to publish a new version of our CP/CPS based on letsencrypt/cp-cps#307. Then, update this PR description and the links within each lint to point at a version tag instead of a commit sha1.

Warning

DO NOT MERGE until we have a solution for cert-checker, which does not currently have a way to supply the issuer certificate to each of these lints. We can either give it that capability, or configure it to ignore these lints, or make the lints not fail if they're not configured.

@aarongable
aarongable force-pushed the cps-lints branch 2 times, most recently from e0879bd to cbb7695 Compare July 18, 2026 00:49
@aarongable
aarongable marked this pull request as ready for review July 18, 2026 01:12
@aarongable
aarongable requested a review from a team as a code owner July 18, 2026 01:12

@mcpherrinm mcpherrinm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this looks pretty good structurally.

I think the biggest concern is I think we could issue a cert for which CheckApplies is false on all lints, and we wouldn't lint it as a result.

My secondary concern is that I think we could make more use of some helper functions to validate each field, as the checks are nearly the same across several lints. I left one comment to that effect but it holds in numerous places.

Comment thread linter/lints/cpcps/helpers.go

func (l *subscriberServerCertificateMatchesCPSProfile) CheckApplies(c *x509.Certificate) bool {
// Precertificates are covered by the Precertificate Profile instead.
return util.IsSubscriberCert(c) && util.IsServerAuthCert(c) && !util.IsExtInCert(c, util.CtPoisonOID)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we ever decided to issue a client auth only cert for whatever reason, I think we'd get a false CheckApplies here.

I think we want a lint that ensures a check is either a cert or precert (for prod boulder), or makes sure it is a root, cross, or intermediate (for ceremony)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah I was having similar thoughts. I don't love the idea of combining them all into just two lints, but I've been contemplating if it would make sense to require that all of our lint environments (the CA, cert-checker, and the ceremony tool) explicitly disable all of the CP/CPS lints except for the one that applies in each situation. Would that make sense to you? Or would you prefer to go with some sort of meta-lint system?

Comment thread linter/lints/cpcps/lint_subscriber_server_certificate.go Outdated
Comment thread linter/lints/cpcps/lint_subscriber_server_certificate.go
Comment thread linter/lints/cpcps/lint_tls_subordinate_ca_certificate.go Outdated
Comment thread core/util_test.go Outdated
Comment thread linter/lints/cpcps/lint_cross_certified_subordinate_ca_certificate.go Outdated
Comment thread linter/lints/cpcps/lint_cross_certified_subordinate_ca_certificate.go Outdated

@jsha jsha left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Partial review; I'm as far as linter/lints/cpcps/lint_cross_certified_subordinate_ca_certificate.go.

Comment thread linter/lints/cpcps/helpers.go Outdated
Comment thread linter/lints/cpcps/lint_cross_certified_subordinate_ca_certificate.go Outdated
Comment thread linter/lints/cpcps/lint_cross_certified_subordinate_ca_certificate.go Outdated
Comment thread linter/lints/cpcps/lint_cross_certified_subordinate_ca_certificate.go Outdated

@jsha jsha left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Done reviewing!

Comment thread linter/lints/cpcps/lint_precertificate.go Outdated
Comment thread linter/lints/cpcps/lint_subscriber_server_certificate.go Outdated
@aarongable

Copy link
Copy Markdown
Contributor Author

I've responded to all comments except for the one about CheckApplies. I'm still unsure of the best path forward there. Thoughts and feedback appreciated.

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.

Add zlint lints based on our specific CP/CPS

3 participants