[PostgreSQL] Must TLS configuration parameters mirror what's available in `libpq`?
I have found these related issues/pull requests
Description
The current PgConfig definition seems to mirror quite closely, for TLS, the corresponding options in libpq: sslmode, sslrootcert, sslcert, sslkey.
I'm currently trying to build an application that uses a unified TLS policy across all its clients. In particular, a consistent set of trusted root certificates.
I'm struggling to get sqlx to fit. As far as I understand, these are my options:
- I can specify
sslrootcert, but this requires me to manually "bundle" all my certs into a single PEM bundle - I can use
tls-rustls-native-rootsto get the certs trusted by the OS (soon viarustls-plaftorm-verifier)
There is no way for me to say: I want the certs trusted by the OS as well as these other N roots. Something equivalent to Verifier::new_with_extra_roots.
Prefered solution
I can see various options to solve the problem:
- Move away from mirroring
libpqwhen it comes to TLS configuration, using a more expressive set of options for server certificate verification - Allow the user to pass a preconfigured
rustls::Config(although that'd have semver implications)
and probably others I haven't thought about. But I'd like to first understand if there is an interest in tackling the problem.
Is this a breaking change? Why or why not?
It'd most likely be a breaking change.
We can add options beyond what libpq supports, that's not a problem. We just used libpq as a baseline.
However, I'm leaning towards letting the user specify a custom rustls::ClientConfig since it has plenty of other use-cases as well, like #4044.
It could be a SemVer hazard, but we could just mark that API as SemVer-exempt. However, Rustls has been on the 0.23 release for at least a year and 0.24 seems to be a ways off still, so that's possibly a non-issue.
However, I'm leaning towards letting the user specify a custom
rustls::ClientConfigsince it has plenty of other use-cases as well, like #4044.
How do you envision that working? A method along the lines of reqwest::ClientBuilder::use_preconfigured_tls on PgConnectOptions (and, I assume, all other database drivers)?
It could be a SemVer hazard, but we could just mark that API as SemVer-exempt. However, Rustls has been on the 0.23 release for at least a year and 0.24 seems to be a ways off still, so that's possibly a non-issue.
Yes, I don't think 0.24.x is coming out any time soon.
I'd just have a method that takes rustls::ClientConfig and one that takes... I dunno, probably a native_tls::TlsConnector.
If we wanted to support it in the same method then we'd need to create a common trait to implement for both types. Which is possible, I'm just not sure what the value is. I guess that would allow third-party implementations, which could be useful.
As for the SemVer issue, we could just try using a range when Rustls 0.24 releases. I think that's less hazardous than taking dyn Any because if Cargo fails to constrain the version correctly it'll error at compile time instead of runtime.
I'd just have a method that takes
rustls::ClientConfigand one that takes... I dunno, probably anative_tls::TlsConnector.
I've started to sketch the design in https://github.com/launchbadge/sqlx/pull/4051. There are some open questions that would benefit from your input, before I go further with the implementation work.
If we wanted to support it in the same method then we'd need to create a common trait to implement for both types. Which is possible, I'm just not sure what the value is. I guess that would allow third-party implementations, which could be useful.
That's something that could be added later on, if desired, in a backwards-compatible manner. E.g. it'd allow sqlx to support multiple versions of rustls, if desired.
I'm leaning towards letting the user specify a custom rustls::ClientConfig since it has plenty of other use-cases as well, like #4044.
@abonander Would it be okay to have #4044 in the meantime, or do you want to go directly for the support of custom rustls::ClientConfig?
While not crucial, it will enable us to rely on a single TLS implementation.