redhat-cop / cert-utils-operator

Set of functionalities around certificates packaged in a Kubernetes operator
Apache License 2.0
95 stars 35 forks source link

Improve docs to better describe how the CA Injector works with CRDs #29

Closed ron1 closed 5 years ago

ron1 commented 5 years ago

It is not clear in the docs how the CA Injector works with CRDs? For the Webhooks, it is clear the injection is done to the WebhookClientConfig.caBundle. This is not the case for CRDs. How is the CA Injector intended to work with CRDs?

I would like to use the CA Injector with Rook/Ceph RGW as briefly described here: https://github.com/rook/rook/pull/3016#issuecomment-532767824. My client application intends to use an ObjectBucketClaim to interact with an SSL-enabled Rook/Ceph RGW S3 endpoint. I would like to use the CA Injector to get the CABundle from the rook-ceph-rgw-cert Secret. Of course my client runs in a different namespace from rook-ceph. My client app is operator-managed and has a CR. I would like to inject the CA bundle somewhere where it is accessible to either my operator or my client app. How is this intended to work?

Note my client app is written in Java so I would also like to use the cert-utils-operator to convert the injected CA bundle into a truststore.jks. Have you considered such a use case in your design? I was thinking my operator could put the injected CA bundle into a kubernetes.io/tls secret with the cert-utils-operator.redhat-cop.io/generate-java-keystores: "true" annotation in order to make it available as a truststore.jks. Thoughts?

raffaelespazzoli commented 5 years ago

so for CRDs there is a field in the CRD definition to define a webhook that is responsible for converting CRDs of the same type but different versions. That is currently the only use of a CA injector for CRD. In other words th CA inject at the moment cover three very specific use cases and it's not general purpose. however, if you are using OCP 4.x there is a generic CA injector operator. Maybe that will cover your use case. It will only inject PEM-based CA bundles though.

ron1 commented 5 years ago

Thanks for the clarification.

The OCP 4.x CA Injector operator's ConfigMapCAInjector (https://github.com/openshift/service-ca-operator/tree/master/pkg/controller/configmapcainjector) does not appear to provide comparable functionality to that offered by this CA Injector for Kubernetes Webhook resources. In light of that fact, would you consider expanding the scope of the cert-utils-operator CA Injector to include ConfigMaps in addition to Webhooks? In this case, the presence of the CA Injector annotation on a ConfigMap would cause the addition or update of a data item with key "ca.crt" or "ca-bundle.crt" or "service-ca.crt" to the ConfigMap.

In order to support the common use case where one-way SSL is used w/some other form of authentication, a.k.a use of the secure lib-bucket-provisioner described above, consider adding CA Injector support for kubernetes.io/tls Secret resources as well. Here, the annotation would cause the data item in the Secret with key "ca.crt" to be updated. If the Secret also had the cert-utils-operator.redhat-cop.io/generate-java-keystores: "true" annotation, the truststore.jks data item would get updated as well. In this use case, the tls.crt and tls.key data items in the Secret would typically be unset so the cert-utils-operator should tolerate generating a truststore.jks w/out a keystore.jks.

WDYT?

raffaelespazzoli commented 5 years ago

I think the feature is well stated and technically feasible. We can add it. To summarize it for the benefit of whomever will help contributing it:

  1. an injection annotation will be observed on configmaps.
  2. the ca.crt from the referenced secret will be injected.
  3. if the secret is annotated to generate a keystore, then the truststore will also be injected.
  4. a secret from a different namespace can be referenced.
raffaelespazzoli commented 5 years ago

One change on the previous design. To favor homogeneity, I think it would be better to inject ca-bundles into secrets as opposed to configmaps. Secrets and configmaps can be used essentially in the same context so this should not limit the usability. So the design becomes the following:

  1. an injection annotation will be observed on secrets of type kubernetes.io/tls.
  2. the ca.crt from the referenced secret will be injected (a secret from a different namespace can be referenced).

If the user wants the ca-bundle to be represented as a truststore, they can annotate the secret with the cert-utils-operator.redhat-cop.io/generate-java-keystores: "true" annotation. So with this approach there is no need to also inject the truststore.

raffaelespazzoli commented 5 years ago

based on prototype in #31, a few things:

  1. I implemented CA injection for both secrets and configmap
  2. configmaps cannot contain trustores because configmaps can only contain text objects.
raffaelespazzoli commented 5 years ago

close by #31