Skip to content

Commit f38c66d

Browse files
authored
Merge 1baab03 into e63fd01
2 parents e63fd01 + 1baab03 commit f38c66d

File tree

24 files changed

+1952
-53
lines changed

24 files changed

+1952
-53
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
# v2.5.0
2+
## Features
3+
- Add support to specify a ConfigMap for CA trust bundles in Issuer / ClusterIssuer resources via the `caBundleConfigMapName` specification.
4+
- Add support for specifying a key on a Secret / ConfigMap resource for the CA trust bundle via the `caBundleKey` specification on an Issuer / ClusterIssuer resource.
5+
- Add a timeout when fetching ambient Azure credentials to move onto other ambient credential methods.
6+
7+
## Chores
8+
- Add documentation for how to configure command-cert-manager-issuer with ambient credentials on Google Kubernetes Engine (GKE).
9+
- Add documentation for configuring CA trust bundles via Secret and ConfigMap resources using trust-manager.
10+
111
# v2.4.0
212
## Features
313
- Add a `healthcheck` specification to Issuer / ClusterIssuer resources, allowing flexibility in the health check interval.

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ test: manifests generate fmt vet envtest ## Run tests.
6767
# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
6868
.PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up.
6969
test-e2e:
70-
go test ./test/e2e/ -v -ginkgo.v
70+
cd e2e && source .env && ./run_tests.sh
7171

7272
.PHONY: lint
7373
lint: golangci-lint ## Run golangci-lint linter & yamllint

README.md

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,26 @@ Command Issuer is installed using a Helm chart. The chart is available in the [C
144144
--create-namespace
145145
```
146146

147+
You can also install a specific version of the command-cert-manager-issuer Helm chart:
148+
149+
```shell
150+
helm search repo command-issuer/command-cert-manager-issuer --versions
151+
```
152+
153+
```shell
154+
helm install command-cert-manager-issuer command-issuer/command-cert-manager-issuer \
155+
--namespace command-issuer-system \
156+
--version 2.4.0
157+
--create-namespace
158+
```
159+
160+
> For all possible configuration values for the command-cert-manager-issuer Helm chart, please refer to [this list](./deploy/charts/command-cert-manager-issuer/README.md#configuration)
147161
> For all possible configuration values for the command-cert-manager-issuer Helm chart, please refer to [this list](./deploy/charts/command-cert-manager-issuer/README.md#configuration)
148162

149163
> The Helm chart installs the Command Issuer CRDs by default. The CRDs can be installed manually with the `make install` target.
150164

165+
> A list of configurable Helm chart parameters can be found [in the Helm chart docs](./deploy/charts/command-cert-manager-issuer/README.md#configuration)
166+
151167
# Authentication
152168

153169
## Explicit Credentials
@@ -166,6 +182,7 @@ These credentials must be configured using a Kubernetes Secret. By default, the
166182
Command Issuer also supports ambient authentication, where a token is fetched from an Authorization Server using a cloud provider's auth infrastructure and passed to Command directly. The following methods are supported:
167183
168184
- [Managed Identity Using Azure Entra ID Workload Identity](./docs/ambient-providers/azure.md) (if running in [AKS](https://azure.microsoft.com/en-us/products/kubernetes-service))
185+
- [Workload Identity Using Google Kubernetes Engine](./docs/ambient-providers/google.md) (if running in [GKE](https://cloud.google.com/kubernetes-engine))
169186
170187
If you are running your Kubernetes workload in a cloud provider not listed above, you can use workload identity federation with [Azure AD](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation).
171188
@@ -212,11 +229,7 @@ This section has moved. Please refer to [this link](./docs/ambient-providers/azu
212229
213230
# CA Bundle
214231
215-
If the Command API is configured to use a self-signed certificate or with a certificate whose issuer isn't widely trusted, the CA certificate must be provided as a Kubernetes secret.
216-
217-
```shell
218-
kubectl -n command-issuer-system create secret generic command-ca-secret --from-file=ca.crt
219-
```
232+
This section has been moved. Please refer to the new [CA Bundle docs](./docs/ca-bundle/README.md) documentation regarding CA trust with command-cert-manager-issuer.
220233
221234
# Creating Issuer and ClusterIssuer resources
222235
@@ -243,7 +256,9 @@ For example, ClusterIssuer resources can be used to issue certificates for resou
243256
| hostname | The hostname of the Command API Server. |
244257
| apiPath | (optional) The base path of the Command REST API. Defaults to `KeyfactorAPI`. |
245258
| commandSecretName | (optional) The name of the Kubernetes secret containing basic auth credentials or OAuth 2.0 credentials. Omit if using ambient credentials. |
246-
| caSecretName | (optional) The name of the Kubernetes secret containing the CA certificate. Required if the Command API uses a self-signed certificate or it was signed by a CA that is not widely trusted. |
259+
| caSecretName | (optional) The name of the Kubernetes secret containing the CA certificate trust chain. See the [CA Bundle docs](./docs/ca-bundle/README.md) for more information. |
260+
| caBundleConfigMapName | (optional) The name of the Kubernetes ConfigMap containing the CA certificate trust chain. See the [CA Bundle docs](./docs/ca-bundle/README.md) for more information. |
261+
| caBundleKey | (optional) The name of the key in the ConfigMap or Secret specified by `caSecretName` or `caBundleConfigMapName` that contains the CA bundle. If omitted, the last key of the ConfigMap / Secret resource will be used. |
247262
| certificateAuthorityLogicalName | The logical name of the Certificate Authority to use in Command. For example, `Sub-CA` |
248263
| certificateAuthorityHostname | (optional) The hostname of the Certificate Authority specified by `certificateAuthorityLogicalName`. This field is usually only required if the CA in Command is a DCOM (MSCA-like) CA. |
249264
| enrollmentPatternId | The ID of the [Enrollment Pattern](https://software.keyfactor.com/Core-OnPrem/Current/Content/ReferenceGuide/Enrollment-Patterns.htm) to use when this Issuer/ClusterIssuer enrolls CSRs. **Supported by Keyfactor Command 25.1 and above**. If `certificateTemplate` and `enrollmentPatternId` are both specified, the enrollment pattern parameter will take precedence. If `enrollmentPatternId` and `enrollmentPatternName` are both specified, `enrollmentPatternId` will take precedence. Enrollment will fail if the specified certificate template is not compatible with the enrollment pattern. |
@@ -276,7 +291,9 @@ For example, ClusterIssuer resources can be used to issue certificates for resou
276291
hostname: "$HOSTNAME"
277292
apiPath: "/KeyfactorAPI" # Preceding & trailing slashes are handled automatically
278293
commandSecretName: "command-secret" # references the secret created above. Omit if using ambient credentials.
279-
caSecretName: "command-ca-secret" # references the secret created above
294+
# caSecretName: "command-ca-secret" # references a secret containing the CA trust chain (see CA Bundle docs for more info)
295+
# caBundleConfigMapName: "command-ca-configmap" # references a configmap containing the CA trust chain (see CA Bundle docs for more info)
296+
# caBundleKey: "ca.crt" # references the key in the secret/configmap containing the CA trust chain (see CA Bundle docs for more info)
280297
281298
# certificateAuthorityHostname: "$COMMAND_CA_HOSTNAME" # Uncomment if required
282299
certificateAuthorityLogicalName: "$COMMAND_CA_LOGICAL_NAME"
@@ -309,7 +326,9 @@ For example, ClusterIssuer resources can be used to issue certificates for resou
309326
hostname: "$HOSTNAME"
310327
apiPath: "/KeyfactorAPI" # Preceding & trailing slashes are handled automatically
311328
commandSecretName: "command-secret" # references the secret created above. Omit if using ambient credentials.
312-
caSecretName: "command-ca-secret" # references the secret created above
329+
# caSecretName: "command-ca-secret" # references a secret containing the CA trust chain (see CA Bundle docs for more info)
330+
# caBundleConfigMapName: "command-ca-configmap" # references a configmap containing the CA trust chain (see CA Bundle docs for more info)
331+
# caBundleKey: "ca.crt" # references the key in the secret/configmap containing the CA trust chain (see CA Bundle docs for more info)
313332
314333
# certificateAuthorityHostname: "$COMMAND_CA_HOSTNAME" # Uncomment if required
315334
certificateAuthorityLogicalName: "$COMMAND_CA_LOGICAL_NAME"

api/v1alpha1/issuer_types.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,24 @@ type IssuerSpec struct {
106106

107107
// The name of the secret containing the CA bundle to use when verifying
108108
// Command's server certificate. If specified, the CA bundle will be added to
109-
// the client trust roots for the Command issuer.
109+
// the client trust roots for the Command issuer. If both caSecretName and caBundleConfigMapName
110+
// are specified, caBundleConfigMapName will take precedence.
110111
// +optional
111112
CaSecretName string `json:"caSecretName,omitempty"`
112113

114+
// The name of the ConfigMap containing the CA bundle to use when verifying
115+
// Command's server certificate. If specified, the CA bundle will be added to
116+
// the client trust roots for the Command issuer. If both caSecretName and caBundleConfigMapName
117+
// are specified, caBundleConfigMapName will take precedence.
118+
// +optional
119+
CaBundleConfigMapName string `json:"caBundleConfigMapName,omitempty"`
120+
121+
// The key in the Secret or ConfigMap containing the CA certificate bundle.
122+
// Applies to both caSecretName and caBundleConfigMapName.
123+
// If unspecifed, the last key alphabetically in the Secret or ConfigMap data will be used.
124+
// +optional
125+
CaBundleKey string `json:"caBundleKey,omitempty"`
126+
113127
// A list of comma separated scopes used when requesting a Bearer token from an ambient token provider implied
114128
// by the environment, rather than by commandSecretName. For example, could be set to
115129
// api://{tenant ID}/.default when requesting an access token for Entra ID (DefaultAzureCredential). Has no

cmd/main.go

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ func main() {
7171
var clusterResourceNamespace string
7272
var disableApprovedCheck bool
7373
var secretAccessGrantedAtClusterLevel bool
74+
var configMapAccessGrantedAtClusterLevel bool
7475

7576
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
7677
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
@@ -88,6 +89,8 @@ func main() {
8889
"Disables waiting for CertificateRequests to have an approved condition before signing.")
8990
flag.BoolVar(&secretAccessGrantedAtClusterLevel, "secret-access-granted-at-cluster-level", false,
9091
"Set this flag to true if the secret access is granted at cluster level. This will allow the controller to access secrets in any namespace. ")
92+
flag.BoolVar(&configMapAccessGrantedAtClusterLevel, "configmap-access-granted-at-cluster-level", false,
93+
"Set this flag to true if the config map access is granted at cluster level. This will allow the controller to access config maps in any namespace. ")
9194
opts := zap.Options{
9295
Development: true,
9396
}
@@ -130,16 +133,31 @@ func main() {
130133
}
131134

132135
var cacheOpts cache.Options
133-
if secretAccessGrantedAtClusterLevel {
134-
setupLog.Info("expecting SA to have Get+List+Watch permissions for corev1 Secret resources at cluster level")
135-
} else {
136-
setupLog.Info(fmt.Sprintf("expecting SA to have Get+List+Watch permissions for corev1 Secret resources in the %q namespace", clusterResourceNamespace))
136+
137+
// Build the ByObject map if either resource is namespace-scoped
138+
if !secretAccessGrantedAtClusterLevel || !configMapAccessGrantedAtClusterLevel {
139+
byObject := make(map[client.Object]cache.ByObject)
140+
141+
if !secretAccessGrantedAtClusterLevel {
142+
setupLog.Info(fmt.Sprintf("expecting SA to have Get+List+Watch permissions for corev1 Secret resources in the %q namespace", clusterResourceNamespace))
143+
byObject[&corev1.Secret{}] = cache.ByObject{
144+
Namespaces: map[string]cache.Config{clusterResourceNamespace: {}},
145+
}
146+
} else {
147+
setupLog.Info("expecting SA to have Get+List+Watch permissions for corev1 Secret resources at cluster level")
148+
}
149+
150+
if !configMapAccessGrantedAtClusterLevel {
151+
setupLog.Info(fmt.Sprintf("expecting SA to have Get+List+Watch permissions for corev1 ConfigMap resources in the %q namespace", clusterResourceNamespace))
152+
byObject[&corev1.ConfigMap{}] = cache.ByObject{
153+
Namespaces: map[string]cache.Config{clusterResourceNamespace: {}},
154+
}
155+
} else {
156+
setupLog.Info("expecting SA to have Get+List+Watch permissions for corev1 ConfigMap resources at cluster level")
157+
}
158+
137159
cacheOpts = cache.Options{
138-
ByObject: map[client.Object]cache.ByObject{
139-
&corev1.Secret{}: {
140-
Namespaces: map[string]cache.Config{clusterResourceNamespace: cache.Config{}},
141-
},
142-
},
160+
ByObject: byObject,
143161
}
144162
}
145163

config/crd/bases/command-issuer.keyfactor.com_clusterissuers.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,25 @@ spec:
5252
the URL of your Command environment.Has no effect on OAuth 2.0 Client Credential configuration - please specify
5353
the audience for this method in an Opaque secret.
5454
type: string
55+
caBundleConfigMapName:
56+
description: |-
57+
The name of the ConfigMap containing the CA bundle to use when verifying
58+
Command's server certificate. If specified, the CA bundle will be added to
59+
the client trust roots for the Command issuer. If both caSecretName and caBundleConfigMapName
60+
are specified, caBundleConfigMapName will take precedence.
61+
type: string
62+
caBundleKey:
63+
description: |-
64+
The key in the Secret or ConfigMap containing the CA certificate bundle.
65+
Applies to both caSecretName and caBundleConfigMapName.
66+
If unspecifed, the last key alphabetically in the Secret or ConfigMap data will be used.
67+
type: string
5568
caSecretName:
5669
description: |-
5770
The name of the secret containing the CA bundle to use when verifying
5871
Command's server certificate. If specified, the CA bundle will be added to
59-
the client trust roots for the Command issuer.
72+
the client trust roots for the Command issuer. If both caSecretName and caBundleConfigMapName
73+
are specified, caBundleConfigMapName will take precedence.
6074
type: string
6175
certificateAuthorityHostname:
6276
description: |-

config/crd/bases/command-issuer.keyfactor.com_issuers.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,25 @@ spec:
5252
the URL of your Command environment.Has no effect on OAuth 2.0 Client Credential configuration - please specify
5353
the audience for this method in an Opaque secret.
5454
type: string
55+
caBundleConfigMapName:
56+
description: |-
57+
The name of the ConfigMap containing the CA bundle to use when verifying
58+
Command's server certificate. If specified, the CA bundle will be added to
59+
the client trust roots for the Command issuer. If both caSecretName and caBundleConfigMapName
60+
are specified, caBundleConfigMapName will take precedence.
61+
type: string
62+
caBundleKey:
63+
description: |-
64+
The key in the Secret or ConfigMap containing the CA certificate bundle.
65+
Applies to both caSecretName and caBundleConfigMapName.
66+
If unspecifed, the last key alphabetically in the Secret or ConfigMap data will be used.
67+
type: string
5568
caSecretName:
5669
description: |-
5770
The name of the secret containing the CA bundle to use when verifying
5871
Command's server certificate. If specified, the CA bundle will be added to
59-
the client trust roots for the Command issuer.
72+
the client trust roots for the Command issuer. If both caSecretName and caBundleConfigMapName
73+
are specified, caBundleConfigMapName will take precedence.
6074
type: string
6175
certificateAuthorityHostname:
6276
description: |-

deploy/charts/command-cert-manager-issuer/templates/crds/clusterissuers.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,25 @@ spec:
4646
description: APIPath is the base path of the Command API. KeyfactorAPI
4747
by default
4848
type: string
49+
caBundleConfigMapName:
50+
description: |-
51+
The name of the ConfigMap containing the CA bundle to use when verifying
52+
Command's server certificate. If specified, the CA bundle will be added to
53+
the client trust roots for the Command issuer. If both caSecretName and caBundleConfigMapName
54+
are specified, caBundleConfigMapName will take precedence.
55+
type: string
56+
caBundleKey:
57+
description: |-
58+
The key in the Secret or ConfigMap containing the CA certificate bundle.
59+
Applies to both caSecretName and caBundleConfigMapName.
60+
If unspecifed, the last key alphabetically in the Secret or ConfigMap data will be used.
61+
type: string
4962
caSecretName:
5063
description: |-
5164
The name of the secret containing the CA bundle to use when verifying
5265
Command's server certificate. If specified, the CA bundle will be added to
53-
the client trust roots for the Command issuer.
66+
the client trust roots for the Command issuer. If both caSecretName and caBundleConfigMapName
67+
are specified, caBundleConfigMapName will take precedence.
5468
type: string
5569
certificateAuthorityHostname:
5670
description: |-

deploy/charts/command-cert-manager-issuer/templates/crds/issuers.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,25 @@ spec:
4646
description: APIPath is the base path of the Command API. KeyfactorAPI
4747
by default
4848
type: string
49+
caBundleConfigMapName:
50+
description: |-
51+
The name of the ConfigMap containing the CA bundle to use when verifying
52+
Command's server certificate. If specified, the CA bundle will be added to
53+
the client trust roots for the Command issuer. If both caSecretName and caBundleConfigMapName
54+
are specified, caBundleConfigMapName will take precedence.
55+
type: string
56+
caBundleKey:
57+
description: |-
58+
The key in the Secret or ConfigMap containing the CA certificate bundle.
59+
Applies to both caSecretName and caBundleConfigMapName.
60+
If unspecifed, the last key alphabetically in the Secret or ConfigMap data will be used.
61+
type: string
4962
caSecretName:
5063
description: |-
5164
The name of the secret containing the CA bundle to use when verifying
5265
Command's server certificate. If specified, the CA bundle will be added to
53-
the client trust roots for the Command issuer.
66+
the client trust roots for the Command issuer. If both caSecretName and caBundleConfigMapName
67+
are specified, caBundleConfigMapName will take precedence.
5468
type: string
5569
certificateAuthorityHostname:
5670
description: |-

deploy/charts/command-cert-manager-issuer/templates/deployment.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ spec:
3636
{{- if .Values.secretConfig.useClusterRoleForSecretAccess}}
3737
- --secret-access-granted-at-cluster-level
3838
{{- end}}
39+
{{- if .Values.secretConfig.useClusterRoleForConfigMapAccess}}
40+
- --configmap-access-granted-at-cluster-level
41+
{{- end}}
3942
{{- if .Values.defaultHealthCheckInterval }}
4043
- --default-health-check-interval={{ .Values.defaultHealthCheckInterval }}
4144
{{- end }}

0 commit comments

Comments
 (0)