Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions examples/fabric-ca/ica-orderer-certmanager.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Example values for deploying Fabric Intermediate CA with cert-manager integration.
#
# Prerequisites:
# 1. cert-manager must be installed in the cluster
# 2. A ClusterIssuer or Issuer must be configured
# 3. The root-ca must be deployed first (with cert-manager if using trustCA)
#
# When trustCA.enabled is true:
# - The root CA's certificate is mounted from a Kubernetes Secret into the init container
# - The init container uses --cacert instead of --insecure to verify the parent CA
# - The secretName should reference a Secret containing the root CA's public certificate
# under the key "ca.crt" (or "tls.crt")
#
# To create the trusted CA secret from the root-ca's certificate:
# kubectl -n orderer create secret generic root-ca-cert \
# --from-file=ca.crt=<(kubectl -n orderer get secret root-ca-tls-secret -o jsonpath='{.data.ca\.crt}' | base64 -d)

imagePullSecrets: []
nameOverride: "ica-orderer"
fullnameOverride: ""
project: yourproject

replicaCount: 1

image:
repository: hyperledger/fabric-ca
pullPolicy: IfNotPresent
tag: "1.5.0"

init:
image:
repository: npcioss/hlf-builder
pullPolicy: IfNotPresent
tag: "2.4"

tls_domain: my-hlf-domain.com
ca_server:
csr_names_country: IN
csr_names_st: Maharashtra
csr_names_l: Mumbai
csr_names_o: Your Company Name
csr_names_ou: Your Organization Unit
container_port: 7051
debug: true
tls_enabled: true
admin_secret: orderer-secret

retry_seconds: 60
recreate_intermediate_cert: false

ica:
enabled: true
parent_ca_endpoint: root-ca.my-hlf-domain.com:30000
intermediate_tls_cert_dir: /tmp/hyperledger/fabric-ca/root-ca-cert
intermediate_tls_cert_file: cert.pem

service:
type: ClusterIP
port: 7051

ingress:
enabled: true
className: "nginx"
annotations: {}

# cert-manager integration for ingress TLS.
certManager:
enabled: true
duration: 2160h
renewBefore: 360h
issuerRef:
name: selfsigned-issuer
kind: ClusterIssuer
group: cert-manager.io
# trustCA: Mount the parent CA's certificate so the ICA init container
# can verify the parent CA without --insecure.
trustCA:
enabled: true
# Name of a Kubernetes Secret containing the parent CA's certificate.
# The certificate should be stored under the key "ca.crt".
# If empty and trustCA is enabled, you must create this secret manually.
secretName: root-ca-cert
caCertPath: /etc/ssl/certs/ca-cert.crt
private:
enabled: false

storage:
pvc_enabled: true
accessMode: ReadWriteOnce
storageClass: standard
size: 1G
path: /tmp/hyperledger/fabric-ca/crypto

serviceAccount:
create: true
annotations: {}
name: ""
102 changes: 102 additions & 0 deletions examples/fabric-ca/root-ca-certmanager.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Example values for deploying Fabric Root CA with cert-manager integration.
#
# Prerequisites:
# 1. cert-manager must be installed in the cluster: https://cert-manager.io/docs/installation/
# 2. A ClusterIssuer or Issuer must be configured (see examples below)
#
# ClusterIssuer example (Let's Encrypt):
# apiVersion: cert-manager.io/v1
# kind: ClusterIssuer
# metadata:
# name: letsencrypt-prod
# spec:
# acme:
# server: https://acme-v02.api.letsencrypt.org/directory
# email: your-email@example.com
# privateKeySecretRef:
# name: letsencrypt-prod
# solvers:
# - http01:
# ingress:
# class: nginx
#
# ClusterIssuer example (self-signed, for testing):
# apiVersion: cert-manager.io/v1
# kind: ClusterIssuer
# metadata:
# name: selfsigned-issuer
# spec:
# selfSigned: {}

imagePullSecrets: []
nameOverride: "root-ca"
fullnameOverride: ""
project: yourproject

replicaCount: 1

image:
repository: hyperledger/fabric-ca
pullPolicy: IfNotPresent
tag: "1.5.0"

tls_domain: my-hlf-domain.com
ca_server:
csr_names_country: IN
csr_names_st: Maharashtra
csr_names_l: Mumbai
csr_names_o: "Your Company Name"
csr_names_ou: "Your Organization Unit"
container_port: 7051
debug: true
tls_enabled: true
admin_secret: rca-secret
additional_sans: []

ica:
enabled: false

service:
type: ClusterIP
port: 7051

ingress:
enabled: true
className: "nginx"
annotations: {}
path: /
pathType: Prefix

# cert-manager integration for ingress TLS.
# When enabled, this creates a Certificate CRD that provisions a TLS certificate
# for the CA ingress. The ingress will terminate TLS using the cert-manager-issued
# certificate instead of using ssl-passthrough.
certManager:
enabled: true
duration: 2160h
renewBefore: 360h
issuerRef:
name: selfsigned-issuer
kind: ClusterIssuer
group: cert-manager.io
# trustCA: When enabled, the parent CA's certificate is mounted as a trusted CA
# in the init container, allowing the ICA to verify the parent CA without --insecure.
# Only relevant when ica.enabled is also true.
trustCA:
enabled: false
secretName: ""
caCertPath: /etc/ssl/certs/ca-cert.crt
private:
enabled: false

storage:
pvc_enabled: true
accessMode: ReadWriteOnce
storageClass: standard
size: 1G
path: /tmp/hyperledger/fabric-ca/crypto

serviceAccount:
create: true
annotations: {}
name: ""
2 changes: 1 addition & 1 deletion helm-charts/fabric-ca/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ apiVersion: v2
name: fabric-ca
description: A Helm chart for deploying Fabric CA Server in Kubernetes.
type: application
version: 1.2.0
version: 1.3.0
appVersion: "1.5.0"
121 changes: 121 additions & 0 deletions helm-charts/fabric-ca/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,124 @@ The following table lists the configurable parameters of the Fabric-ca chart and
| `affinity` | Default affinity | `{}` |
| `nodeSelector` | Default nodeSelector | `{}` |
| `tolerations` | Default tolerations | `[]` |
| `certManager.enabled` | Enable cert-manager integration for ingress TLS | `false` |
| `certManager.duration` | Certificate duration (e.g., `2160h` for 90 days) | `2160h` |
| `certManager.renewBefore` | How long before expiry to renew | `360h` |
| `certManager.issuerRef.name` | Name of the cert-manager Issuer or ClusterIssuer | `""` |
| `certManager.issuerRef.kind` | Kind of issuer (`Issuer` or `ClusterIssuer`) | `"Issuer"` |
| `certManager.issuerRef.group` | API group of the issuer | `"cert-manager.io"` |
| `certManager.trustCA.enabled` | Mount parent CA cert for verified ICA enrollment | `false` |
| `certManager.trustCA.secretName` | K8s Secret containing the trusted CA certificate | `""` |
| `certManager.trustCA.caCertPath` | Path where the CA cert is mounted in the pod | `"/etc/ssl/certs/ca-cert.crt"` |
| `certManager.private.enabled` | Use a private CA issuer (non-ACME) | `false` |

## cert-manager Integration

This chart supports [cert-manager](https://cert-manager.io/) for provisioning TLS certificates at the ingress layer. When enabled, cert-manager replaces the `ssl-passthrough` pattern with standard TLS termination.

### Architecture

When `certManager.enabled: true`, the chart creates a `Certificate` CRD that instructs cert-manager to provision a TLS certificate. The ingress terminates TLS using this certificate, and forwards traffic to the Fabric CA pod over HTTPS (the CA pod still uses its own self-signed Fabric TLS certificate internally).

```
External Clients
|
v
+----------------------------------+
| NGINX Ingress Controller |
| (cert-manager TLS termination) |
+----------------------------------+
| (backend-protocol: HTTPS)
v
+----------------------------------+
| Fabric CA Pod |
| (Fabric CA self-signed TLS) |
+----------------------------------+
```

**Important:** cert-manager only manages the ingress-facing TLS certificate. Fabric CA's internal TLS (`FABRIC_CA_SERVER_TLS_ENABLED`) and the Fabric PKI hierarchy (root CA, intermediate CA, enrollment certificates) remain unchanged.

### Prerequisites

1. Install cert-manager in your cluster: https://cert-manager.io/docs/installation/
2. Create an Issuer or ClusterIssuer. Examples:

**Let's Encrypt (ACME HTTP01):**
```yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
```

**Self-signed (for testing):**
```yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-issuer
spec:
selfSigned: {}
```

**Private CA (e.g., Vault PKI, Smallstep):**
```yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: private-ca-issuer
spec:
ca:
secretName: private-ca-key-pair
```

### Deploying with cert-manager (Root CA)

```bash
kubectl create ns orderer
kubectl -n orderer create secret generic rca-secret --from-literal=user=rca-admin --from-literal=password=rcaComplexPassword
helm install root-ca -n orderer helm-charts/fabric-ca -f examples/fabric-ca/root-ca-certmanager.yaml
```

### Deploying with cert-manager (Intermediate CA with trusted CA)

When deploying an ICA with `certManager.trustCA.enabled: true`, the init container verifies the parent CA's certificate instead of using `--insecure`:

1. First, extract the root CA's certificate and create a Secret:
```bash
kubectl -n orderer create secret generic root-ca-cert \
--from-literal=ca.crt="$(kubectl -n orderer exec root-ca-0 -- cat /tmp/hyperledger/fabric-ca/crypto/ca-cert.pem)"
```

2. Then deploy the ICA:
```bash
helm install ica-orderer -n orderer helm-charts/fabric-ca -f examples/fabric-ca/ica-orderer-certmanager.yaml
```

### Migration from ssl-passthrough

To migrate an existing CA deployment from `ssl-passthrough` to cert-manager:

1. Install cert-manager and create an Issuer/ClusterIssuer
2. Update your values to set `certManager.enabled: true` and configure the issuer
3. Remove `ssl-passthrough` from ingress annotations (it's automatically removed when cert-manager is enabled)
4. Run `helm upgrade`

The chart automatically adds `nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"` when cert-manager is enabled, ensuring the ingress forwards traffic to the CA pod over HTTPS.

### Backward Compatibility

When `certManager.enabled: false` (the default), the chart behaves exactly as before:
- The ingress uses `ssl-passthrough` if specified in annotations
- The ICA init container uses `--insecure` to fetch parent CA certificates
- No Certificate CRD is created
35 changes: 35 additions & 0 deletions helm-charts/fabric-ca/templates/certificate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{{/*
Copyright National Payments Corporation of India. All Rights Reserved.
SPDX-License-Identifier: GPL-3.0
*/}}

{{- if .Values.certManager.enabled -}}
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: {{ include "fabric-ca.fullname" . }}-tls
labels:
{{- include "fabric-ca.labels" . | nindent 4 }}
spec:
secretName: {{ include "fabric-ca.fullname" . }}-tls-secret
duration: {{ .Values.certManager.duration | default "2160h" }}
renewBefore: {{ .Values.certManager.renewBefore | default "360h" }}
{{- with .Values.certManager.issuerRef }}
issuerRef:
{{- toYaml . | nindent 4 }}
{{- end }}
dnsNames:
- {{ include "fabric-ca.fullname" . }}.{{ $.Values.tls_domain }}
{{- range .Values.ca_server.additional_sans }}
- {{ . }}
{{- end }}
usages:
- server auth
- client auth
{{- if .Values.certManager.private.enabled }}
isCA: false
privateKey:
algorithm: RSA
size: 2048
{{- end }}
{{- end }}
Loading