Skip to content

tls: add system and combined CA pool modules#7406

Merged
mohammed90 merged 9 commits intocaddyserver:masterfrom
HarshPatel5940:hp/system-ca-pool
Apr 5, 2026
Merged

tls: add system and combined CA pool modules#7406
mohammed90 merged 9 commits intocaddyserver:masterfrom
HarshPatel5940:hp/system-ca-pool

Conversation

@HarshPatel5940
Copy link
Copy Markdown
Contributor

Summary

I've implemented the system trust pool module which uses x509.SystemCertPool() and works as expected.

However, the combined module has a fundamental limitation: Go's x509.CertPool doesn't expose its certificates, making it impossible to merge multiple pools.

so should we modify the CA interface to add a method like Certificates() []*x509.Certificate so sources can expose their certificates for merging? not sure how to proceed here... Would be happy to learn.

Assistance Disclosure

I wrote the code, but Claude generated the tests.

Comment thread modules/caddytls/capools.go Outdated
Comment on lines +751 to +774
// LIMITATION: x509.CertPool doesn't expose its certificates, making it impossible
// to merge multiple pools. Return an error if multiple sources are configured.
if len(ccp.sources) > 1 {
return fmt.Errorf("combined CA pool currently supports only a single source due to x509.CertPool API limitations (got %d sources); to use multiple certificate sources, consider using a single 'file' source with multiple pem_file entries, or contribute a fix to expose certificate data from the CA interface", len(ccp.sources))
}

// At this point we have exactly one source
ccp.pool = ccp.sources[0].CertPool()

return nil
}

// Syntax:
//
// trust_pool combined {
// source <module_name> {
// <module_config>
// }
// }
//
// LIMITATION: Currently only a single source is supported due to x509.CertPool
// API limitations. Specifying multiple sources will result in a provisioning error.
// To combine multiple certificate files, use a single 'file' source with multiple
// pem_file entries instead.
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.

I have intentionally added limitation comments cause i wasnt aware how to proceed here.

@HarshPatel5940
Copy link
Copy Markdown
Contributor Author

"combined merges multiple roots sources" is not satisfied as per issue #7391 and i am erroring out as you see in above comment.

so should we modify the CA interface to add a method like Certificates() []*x509.Certificate so sources can expose their certificates for merging? not sure how to proceed here... Would be happy to learn.

This approach which i think is a breaking change so i wanted to consult with my planned implementation

@FreyreCorona
Copy link
Copy Markdown
Contributor

FreyreCorona commented Jan 2, 2026

Happy new year and i reviewed your code and i have two types of solutions
Ther first is like you say , changin the actual contract of CA interface ,

type CA interface {
    AppendTo(pool *x509.CertPool) error
}

This is breaking change because not all CA pools can expose certificates.

The second way is creating a secondary interface (non breaking change)

type CertificateProvider interface {
    Certificates() []*x509.Certificate
}

The combined module would then check whether each source implements this interface and merge certificates only from those that do.

@HarshPatel5940
Copy link
Copy Markdown
Contributor Author

Hello @FreyreCorona , thank you for the suggestions! will work on a non-breaking solution.

lastly, sorry for the delayed response. forgot about this pr due to work

@HarshPatel5940 HarshPatel5940 marked this pull request as ready for review January 20, 2026 04:50
@FreyreCorona
Copy link
Copy Markdown
Contributor

FreyreCorona commented Jan 20, 2026

Nice work on the implementation, let's wait for the review. No worries, we're all busy, and I've been pretty quiet around here these past few days too.

@mohammed90
Copy link
Copy Markdown
Member

mohammed90 commented Jan 27, 2026

When I first glanced at this, I wondered by I made it return a concrete type instead of an interface, but then remembered that tls.Config takes a struct and there's no way around it.

I don't see the point of the AppendTo(pool *x509.CertPool) error because it still doesn't resolve the issue with system trust, which is it not exporting its certificates. I prefer the other approach of the optional, secondary interface because it's non-breaking and indicates optionality for types that can't implement it.

Open to discuss this further though

@HarshPatel5940
Copy link
Copy Markdown
Contributor Author

I don't see the point of the AppendTo(pool *x509.CertPool) error because it still doesn't resolve the issue with system trust, which is it not exporting its certificates. I prefer the other approach of the optional, secondary interface because it's non-breaking and indicates optionality for types that can't implement it.

Thanks for the review!

I'm confirming that this PR effectively implements the non-breaking, optional interface approach.

To clarify:

  • CertificateProvider as a distinct, optional interface, leaving the main CA contract unchanged (non-breaking).
  • All source modules that can expose certificates (like file, inline, pki) implement this new interface.
  • SystemCAPool intentionally does not implement it because x509.SystemCertPool() doesn't expose underlying certs.
  • The CombinedCAPool module will merge certificates from compatible sources and return an error if you try to combine a source (like system) that doesn't support it.

@HarshPatel5940

This comment was marked as spam.

@mohammed90

This comment was marked as spam.

@HarshPatel5940

This comment was marked as spam.

Copy link
Copy Markdown
Member

@mohammed90 mohammed90 left a comment

Choose a reason for hiding this comment

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

On a high level. It looks good. Please add adapt tests like the ones here:

https://github.com/search?q=repo%3Acaddyserver%2Fcaddy+trust_pool+language%3AText&type=code&l=Text

@HarshPatel5940
Copy link
Copy Markdown
Contributor Author

Hmm, noted. 🤔

* doing it for first time, so not sure if its right.
@HarshPatel5940

This comment was marked as spam.

@FreyreCorona

This comment was marked as spam.

Copy link
Copy Markdown
Member

@mohammed90 mohammed90 left a comment

Choose a reason for hiding this comment

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

Life was busy in the past few months, and this area of the code proved itself critical, so I had to ensure I have clear mind to go through it before merging.

Hopefully this is the last round of review. I believe I've caught everything.

Comment thread modules/caddytls/capools.go Outdated
Comment thread modules/caddytls/capools.go Outdated
Comment thread modules/caddytls/capools.go Outdated
@HarshPatel5940
Copy link
Copy Markdown
Contributor Author

Life was busy in the past few months, and this area of the code proved itself critical, so I had to ensure I have clear mind to go through it before merging.

Definitely understandable.

@HarshPatel5940
Copy link
Copy Markdown
Contributor Author

done the requested changes fad1950

@FreyreCorona

This comment was marked as spam.

@mholt
Copy link
Copy Markdown
Member

mholt commented Mar 31, 2026

Folks, please refrain from the pinging. It is on our list. We are very busy, especially the volunteers who have taken up this PR/issue. The more pinging that happens the more we dismiss the notification on the issue and it goes back to the end of the queue (that's just how GH notifications work, I dunno what other peoples' flows are, but that's mine).

Comment thread modules/caddytls/capools.go
Copy link
Copy Markdown
Member

@mohammed90 mohammed90 left a comment

Choose a reason for hiding this comment

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

Thank you for working on this and persevering through the multiple rounds of review! LGTM

@mohammed90 mohammed90 changed the title feat: add system and combined CA pool modules tls: add system and combined CA pool modules Apr 5, 2026
@mohammed90 mohammed90 merged commit d783467 into caddyserver:master Apr 5, 2026
27 checks passed
@HarshPatel5940
Copy link
Copy Markdown
Contributor Author

Thank you so much for guiding me along the process!

@mohammed90 mohammed90 linked an issue Apr 6, 2026 that may be closed by this pull request
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.

cert_pool: add combined/multi and system

4 participants