open-policy-agent / opa

Open Policy Agent (OPA) is an open source, general-purpose policy engine.
https://www.openpolicyagent.org
Apache License 2.0
9.6k stars 1.33k forks source link

Keystore support for (m)TLS sensitive files #7107

Open mariuspodean opened 2 days ago

mariuspodean commented 2 days ago

What is the underlying problem you're trying to solve?

In some scenarios it is not feasible to have stored on disk unprotected, sensitive (m)TLS files, such as the server certificate and its private key. Using a password protected keystore improves security in this situation.

Currently, in order to use (m)TLS, we need to pass as params the paths for the following files: server cert & private key and the CA cert. While there is no problem for having the CA cert on disk, there is a different matter when it comes to the certificate itself and especially for the private key. This issue is mainly present on setups that don't use (service) containers and OPA is installed alongside other pieces of software.

Keystores provide a secure way to store this sensitive information, making sure that only authorized entities can access and use the stored keys and certificates.

Describe the ideal solution

Ideally, instead of passing three params to identify the mTLS required 3 files (cert, private key and CA cert), we could pass the path where the keystore is stored and the password to access the data within it.

So instead of using:

...
--tls-cert-file cert.pem \
--tls-private-key-file key.key  \
--tls-ca-cert-file ca.pem \
...

one could use something like the following:

...
--tls-keystore-file keystore.p12 \
--tls-keystore-pass secret \
...

As not everyone needs this level of control, probably both methods for configuring TLS should be in place, leaving to the user to choose.

Ideally we would use PKCS12 keystores, but, if for some reasons that's not possible, JKS would be OK too. PKCS12 is a standardized and language-neutral way of storing encrypted private keys and certificates, and one can use something like the following to bundle together in a secured way the resources:

openssl pkcs12 -export \
    -in cert.pem \
    -inkey cert_key.key \
    -chain \
    -CAfile CA.pem \
    -out keystore_name.p12 \
    -passout keystore_pass \
    -name resources_name_in_keystore

Describe a "Good Enough" solution

The goal here is to protect sensitive resources (server cert & key) and the best way to do it is through the use of keystores. If that is not something that's on the scope for OPA (although one might argue that such a component should use "all means" to secure itself), allowing password protected keys would also be a step up.

Password protected keys would require that we pass an additional param, the key's password. This approach allows us to secure one resource (the certs private key), but leaves the server cert exposed.

Additional Context

All this might not make sense for some setups were we ca use other infra means to protect these resources, but please bear in mind that that's not always possible.

ashutosh-narkar commented 2 days ago

Thanks for filing this detailed issue.

The goal here is to protect sensitive resources (server cert & key) and the best way to do it is through the use of keystores

The scenario here is an attacker has gotten access to the system where OPA is deployed and can now access the files on that system. Is this correct?

On the keystores itself, can you point to examples of other open-source projects where this has been utilized. Also this would require adding a 3rd-party dep iiuc.

mariuspodean commented 2 days ago

The scenario here is an attacker has gotten access to the system where OPA is deployed and can now access the files on that system. Is this correct?

Yes, that would be one of the cases, albeit the most extreme one. Another one would be a machine (Windows ) that hosts other pieces of software, and most importantly, multiple users can have access to it, and you don't fully trust them with this kind of data. Unfortunately, this scenario is more common than one would expect ...

On the keystores itself, can you point to examples of other open-source projects where this has been utilized.

Sure, a lot of projects rely on keystores, one of them being Keycloak (a Cloud Native Computing Foundation incubation project for identity and access management).

Keycloak supports both methods of specifying certs & keys, one could use the files directly:

...
--https-certificate-file=/path/to/certfile.pem \
--https-certificate-key-file=/path/to/keyfile.pem
...

or, by using a keystore:

...
--https-key-store-file=keystore.p12
--https-key-store-password=password
...

Moreover, they allow also to specify the CA chain (or other trusted certs) using truststores (essentially keystores that only store certs, that being the main difference between the two):

...
--https-trust-store-file=truststore.jks
--https-trust-store-password=password
...

Funny thing is that they planed on deprecating the truststore support as mentioned above, but in the latest release (which was out a few days ago), they decided that: Based on the community feedback, we decided to undeprecate https-trust-store-* options to allow better granularity in trusted certificates. source

This comes to prove that these features are more wildly adopted "in the wild" than anticipated.

Also this would require adding a 3rd-party dep iiuc.

As far as I know, this package supports reading PKCS12 keystores: x/crypto. This is not standard library but it extends the crypto.

https://github.com/SSLMate/go-pkcs12/blob/fa70679f0f1622a2705336a97225ee8d6c555f96/pkcs12.go#L413

Checking the Snyk page for it, it seems pretty safe https://snyk.io/advisor/golang/software.sslmate.com/src/go-pkcs12, but yes, it is an external package. For JKS (Java keystores), I thing that's only achievable through a 3rd-party dep, but I'm no Go expert, don't quote me on this :) Between the two formats, I believe PKCS12 is the desired one as it is standardized and language-neutral.

ashutosh-narkar commented 1 day ago

Another one would be a machine (Windows ) that hosts other pieces of software, and most importantly, multiple users can have access to it, and you don't fully trust them with this kind of data. Unfortunately, this scenario is more common than one would expect ...

In this case, shouldn't it be the admin of the machine that should control access. I could imagine if there are other software components in addition to OPA, they may use files with sensitive info as well. What I'm trying to get at is this something that needs to be supported in OPA or can be achieved with some integration or can be addressed in how OPA is deployed.

mariuspodean commented 17 hours ago

If you are aware of any integration that can help us load the files securely (in the specified setup, not containers), please let me know.

I believe that if a piece of software requires some sensitive data in order to work, it should also support the means to load them securely, like through the use of keystores (in this case), or maybe pull them from (a) vault. Otherwise it seems like we're violating the principles of zero trust security. There are multiple ways of loading secrets securely, like keystores, vaults, encrypted files using SOPS etc., and thus not having to rely on what the admin of the machine specifies as access policies for the security of a software.

I strongly believe that this should be supported by OPA because a software that determines to what resources one can have access to (basically authorization) should be as secure as possible.