-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Inject CA trust bundle into managed containers and set SSL_CERT_DIR
- Loading branch information
Showing
20 changed files
with
560 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Custom CA Bundle | ||
|
||
Configuring deployments to trust custom Certificate Authorities (CAs) or self-signed certificates is often necessary for | ||
ensuring secure communication between components or external OIDC service. This guide provides instructions how to add | ||
custom CA bundle for managed operands. | ||
|
||
## Prerequisites: ConfigMap with the CA Bundle | ||
|
||
Before configuring an operand, you need to create a ConfigMap that includes your CA bundle in the same namespace where | ||
the application will be deployed. You can achieve this using one of the following methods: | ||
|
||
1. **Manually Create a ConfigMap**: | ||
|
||
Create a ConfigMap manually by following the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/). | ||
|
||
Example: | ||
```yaml | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: custom-ca-bundle | ||
data: | ||
ca-bundle.crt: | | ||
-----BEGIN CERTIFICATE----- | ||
MIIC... (certificate content) | ||
-----END CERTIFICATE----- | ||
``` | ||
2. **Use Cert-Manager**: | ||
Cert-Manager can generate and manage trusted CA bundles. Follow the [Cert-Manager Documentation](https://cert-manager.io/docs/usage/certificate/) for detailed steps. | ||
3. **Use OpenShift's Feature to Inject Trusted CA Bundles**: | ||
OpenShift can automatically inject trusted CA bundles into a ConfigMap. Follow the [OpenShift Documentation](https://docs.openshift.com/container-platform/latest/networking/configuring-a-custom-pki.html#certificate-injection-using-operators_configuring-a-custom-pki) for detailed steps. | ||
## Configure operand to use Custom CA Bundle | ||
This is done by adding an annotation to the relevant Custom Resource Definitions (CRDs). It can be added to any CRD that | ||
the operator manages (Securesign, Trillian, Fulcio, Rekor, CTlog). The annotation key is `rhtas.redhat.com/trusted-ca`, | ||
and the value should be the name of the ConfigMap created in the prerequisites. | ||
|
||
### Example on a Securesign | ||
|
||
```yaml | ||
apiVersion: rhtas.redhat.com/v1alpha1 | ||
kind: Securesign | ||
metadata: | ||
name: example-instance | ||
annotations: | ||
rhtas.redhat.com/trusted-ca: "name-of-your-configmap" | ||
spec: | ||
# other specifications | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package annotations | ||
|
||
import ( | ||
"maps" | ||
"reflect" | ||
"strconv" | ||
"testing" | ||
) | ||
|
||
func TestFilterInheritable(t *testing.T) { | ||
allIn := make(map[string]string) | ||
allCopy := make(map[string]string) | ||
for i, a := range inheritable { | ||
allIn[a] = strconv.FormatInt(int64(i), 10) | ||
} | ||
maps.Copy(allCopy, allIn) | ||
|
||
type args struct { | ||
annotations map[string]string | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want map[string]string | ||
}{ | ||
{ | ||
name: "empty", | ||
args: args{ | ||
annotations: make(map[string]string), | ||
}, | ||
want: map[string]string{}, | ||
}, | ||
{ | ||
name: "nil", | ||
args: args{ | ||
annotations: nil, | ||
}, | ||
want: map[string]string{}, | ||
}, | ||
{ | ||
name: "no inheritable", | ||
args: args{ | ||
annotations: map[string]string{ | ||
"name1": "value", | ||
"name2": "value", | ||
}, | ||
}, | ||
want: map[string]string{}, | ||
}, | ||
{ | ||
name: "all inheritable", | ||
args: args{ | ||
annotations: allIn, | ||
}, | ||
want: allCopy, | ||
}, | ||
{ | ||
name: "one inheritable", | ||
args: args{ | ||
annotations: map[string]string{ | ||
"name1": "value", | ||
"name2": "value", | ||
TrustedCA: "ca", | ||
}, | ||
}, | ||
want: map[string]string{ | ||
TrustedCA: "ca", | ||
}, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := FilterInheritable(tt.args.annotations); !reflect.DeepEqual(got, tt.want) { | ||
t.Errorf("FilterInheritable() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package utils | ||
|
||
import ( | ||
"errors" | ||
"github.com/securesign/operator/api/v1alpha1" | ||
"github.com/securesign/operator/internal/controller/annotations" | ||
corev1 "k8s.io/api/core/v1" | ||
) | ||
|
||
// SetTrustedCA mount config map with trusted CA bundle to all deployment's containers. | ||
func SetTrustedCA(template *corev1.PodTemplateSpec, lor *v1alpha1.LocalObjectReference) error { | ||
if template == nil { | ||
return errors.New("SetTrustedCA: PodTemplateSpec is not set") | ||
} | ||
|
||
for i, container := range template.Spec.Containers { | ||
if template.Spec.Containers[i].Env == nil { | ||
template.Spec.Containers[i].Env = make([]corev1.EnvVar, 0) | ||
} | ||
template.Spec.Containers[i].Env = append(container.Env, corev1.EnvVar{ | ||
Name: "SSL_CERT_DIR", | ||
Value: "/var/run/configs/tas/ca-trust:/var/run/secrets/kubernetes.io/serviceaccount", | ||
}) | ||
|
||
if template.Spec.Containers[i].VolumeMounts == nil { | ||
template.Spec.Containers[i].VolumeMounts = make([]corev1.VolumeMount, 0) | ||
} | ||
template.Spec.Containers[i].VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ | ||
Name: "ca-trust", | ||
MountPath: "/var/run/configs/tas/ca-trust", | ||
ReadOnly: true, | ||
}) | ||
} | ||
|
||
projections := make([]corev1.VolumeProjection, 0) | ||
if lor != nil { | ||
projections = append(projections, corev1.VolumeProjection{ | ||
ConfigMap: &corev1.ConfigMapProjection{ | ||
LocalObjectReference: corev1.LocalObjectReference{ | ||
Name: lor.Name, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
if template.Spec.Volumes == nil { | ||
template.Spec.Volumes = make([]corev1.Volume, 0) | ||
} | ||
template.Spec.Volumes = append(template.Spec.Volumes, corev1.Volume{ | ||
Name: "ca-trust", | ||
VolumeSource: corev1.VolumeSource{ | ||
Projected: &corev1.ProjectedVolumeSource{ | ||
Sources: projections, | ||
DefaultMode: Pointer(int32(420)), | ||
}, | ||
}, | ||
}) | ||
return nil | ||
} | ||
|
||
func TrustedCAAnnotationToReference(anns map[string]string) *v1alpha1.LocalObjectReference { | ||
if v, ok := anns[annotations.TrustedCA]; ok { | ||
return &v1alpha1.LocalObjectReference{ | ||
Name: v, | ||
} | ||
} | ||
return nil | ||
} |
Oops, something went wrong.