Use self-signed certificates with Helm-based installations
Applies to Helm-based installation only.
Harness Self-Managed Enterprise Edition supports authorization by self-signed certificate. This document explains how to modify the delegate truststore for the use of self-signed certificates in the self-managed environment.
Harness Delegate makes outbound connections to the resources you specify—for example, artifact servers and verification providers. These services typically use public certificates that are included in the operating system or the JRE. You must add the self-signed certificates that you use to the delegate. The process that this document describes is supported for use with the legacy delegate in combination with the Harness CD, CI, and STO modules.
IMPORTANT
- For Golang 1.15 and later, the self-signed certificate must include a Subject Alternative Name (SAN). For more information, go to the JFrog knowledge base.
- For truststores used with Istio, the size of the RSA key must not exceed 2048 bits.
Create the truststore
Generate a self-signed certificate.
Save it to a file named
DigiCertGlobalRootCA.pem
:keytool -import -file DigiCertGlobalRootCA.pem -alias DigiCertRootCA -keystore trustStore.jks
Add the
DigiCertGlobalRootCA.pem
trusted certificate to thetrustStore.jks
truststore:kubectl create secret -n harness-delegate-ng generic mysecret --from-file harness_trustStore.jks=trustStore.jks
Repeat this command for each certificate you want to include in the truststore.
Create the secret
Copy the following YAML to your editor.
apiVersion: v1
kind: Secret
metadata:
name: addcerts
namespace: harness-delegate-ng
type: Opaque
stringData:
ca.bundle: |
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-------
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-------Add your certificates to the
ca.bundle
field.The
XXXXXXXXXXXXXXXXXXXXXXXXXXX
placeholder indicates the position for the certificate body. Enclose each certificate inBEGIN CERTIFICATE
andEND CERTIFICATE
comments.Save the file as
addcerts.yaml
. Apply the manifest to your cluster.kubectl apply -f addcerts.yaml
If another tool such as Argo deletes the secret, you must recreate the secret. Add a MinIO YAML manifest
minio.yaml
file with the following values in addition to your other Harness manifests:apiVersion: v1
kind: Secret
metadata:
name: minio
data:
root-password: ROOT_PASSWORD
root-user: ROOT_USER
Modify the delegate YAML
Open the
harness-delegate.yml
file in your editor.In the
template.spec
section, add the following security context:securityContext:
fsGroup: 1001Locate the
JAVA_OPTS
environment variable. Setvalue
as follows.value: "-Xms64M -Djavax.net.ssl.trustStore=/cacerts/harness_trustStore.jks -Djavax.net.ssl.trustStorePassword=*password*"
Replace password with the password you created for the truststore.
Skip step 5 if your delegates do not run with Harness CI or STO
(Required) Add the following environment variables to the
env
field:- name: CI_MOUNT_VOLUMES
value: /tmp/ca.bundle:/tmp/ca.bundle,/tmp/ca.bundle:/some/other/path/a.crt,/tmp/ca.bundle:/other/path/b.crt,/tmp/ca.bundle:/path/to/ca.bundle
- name: ADDITIONAL_CERTS_PATH
value: /tmp/ca.bundleLocate the template container
spec
. Add the following volume mounts to thespec.containers
field.volumeMounts:
- mountPath: /cacerts
name: custom-truststore
readOnly: true
- name: certvol
mountPath: /tmp/ca.bundle
subPath: ca.bundleLocate the template
spec
and add the following volumes:volumes:
- name: custom-truststore
secret:
secretName: mysecret
defaultMode: 400
- name: certvol
secret:
secretName: addcerts
items:
- key: ca.bundle
path: ca.bundleSkip step 8 if your delegates do not run with Istio service mesh
In the
env
list of environment variables, locate and set thePOLL_FOR_TASKS
value totrue
.- name: POLL_FOR_TASKS
value: "true"This value enables polling for tasks.
Save and apply the modified manifest:
kubectl apply -f harness-delegate.yml
Example: Modified harness-delegate.yml with truststore
The following Kubernetes manifest provides an example of a delegate truststore modified for the generation of self-signed certificates:
Example harness-delegate.yml
apiVersion: v1
kind: Namespace
metadata:
name: harness-delegate-ng
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: harness-delegate-ng-cluster-admin
subjects:
- kind: ServiceAccount
name: default
namespace: harness-delegate-ng
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Secret
metadata:
name: delegatenew-proxy
namespace: harness-delegate-ng
type: Opaque
data:
# Enter base64 encoded username and password, if needed
PROXY_USER: ""
PROXY_PASSWORD: ""
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
harness.io/name: delegatenew
name: delegatenew
namespace: harness-delegate-ng
spec:
replicas: 4
podManagementPolicy: Parallel
selector:
matchLabels:
harness.io/name: delegatenew
serviceName: ""
template:
metadata:
labels:
harness.io/name: delegatenew
spec:
securityContext:
fsGroup: 1001
containers:
- image: docker.io/harness/delegate:latest
imagePullPolicy: Always
name: harness-delegate-instance
ports:
- containerPort: 8080
resources:
limits:
cpu: "2"
memory: "2048Mi"
requests:
cpu: "2"
memory: "2048Mi"
readinessProbe:
exec:
command:
- test
- -s
- delegate.log
initialDelaySeconds: 20
periodSeconds: 10
livenessProbe:
exec:
command:
- bash
- -c
- '[[ -e /opt/harness-delegate/msg/data/watcher-data && $(($(date +%s000) - $(grep heartbeat /opt/harness-delegate/msg/data/watcher-data | cut -d ":" -f 2 | cut -d "," -f 1))) -lt 300000 ]]'
initialDelaySeconds: 240
periodSeconds: 10
failureThreshold: 2
env:
- name: JAVA_OPTS
value: "-Xms64M -Djavax.net.ssl.trustStore=/cacerts/harness_trustStore.jks -Djavax.net.ssl.trustStorePassword=changeit"
- name: ACCOUNT_ID
value: Sfeh1T94QsyLWatE8unScg
- name: MANAGER_HOST_AND_PORT
value: https://smp1.qa.harness.io
- name: DEPLOY_MODE
value: KUBERNETES_ONPREM
- name: DELEGATE_NAME
value: delegatenew
- name: DELEGATE_TYPE
value: "KUBERNETES"
- name: DELEGATE_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: CI_MOUNT_VOLUMES
value: /tmp/ca.bundle:/tmp/ca.bundle,/tmp/ca.bundle:/some/other/path/a.crt,/tmp/ca.bundle:/other/path/b.crt,/tmp/ca.bundle:/path/to/ca.bundle
- name: ADDITIONAL_CERTS_PATH
value: /tmp/ca.bundle
- name: INIT_SCRIPT
value: ""
- name: DELEGATE_DESCRIPTION
value: ""
- name: DELEGATE_TAGS
value: ""
- name: NEXT_GEN
value: "true"
- name: DELEGATE_TOKEN
value: ceb6ce7258713af4be089fdcbc2e2248
- name: WATCHER_STORAGE_URL
value: https://smp1.qa.harness.io/storage/wingswatchers
- name: WATCHER_CHECK_LOCATION
value: watcherprod.txt
- name: DELEGATE_STORAGE_URL
value: https://smp1.qa.harness.io/storage/wingsdelegates
- name: DELEGATE_CHECK_LOCATION
value: delegateprod.txt
- name: HELM_DESIRED_VERSION
value: ""
- name: JRE_VERSION
value: 11.0.14
- name: HELM3_PATH
value: ""
- name: HELM_PATH
value: ""
- name: KUSTOMIZE_PATH
value: ""
- name: KUBECTL_PATH
value: ""
- name: POLL_FOR_TASKS
value: "false"
- name: ENABLE_CE
value: "false"
- name: PROXY_HOST
value: ""
- name: PROXY_PORT
value: ""
- name: PROXY_SCHEME
value: ""
- name: NO_PROXY
value: ""
- name: PROXY_MANAGER
value: "true"
- name: PROXY_USER
valueFrom:
secretKeyRef:
name: delegatenew-proxy
key: PROXY_USER
- name: PROXY_PASSWORD
valueFrom:
secretKeyRef:
name: delegatenew-proxy
key: PROXY_PASSWORD
- name: GRPC_SERVICE_ENABLED
value: "true"
- name: GRPC_SERVICE_CONNECTOR_PORT
value: "8080"
volumeMounts:
- mountPath: /cacerts
name: custom-truststore
readOnly: true
- name: certvol
mountPath: /tmp/ca.bundle
subPath: ca.bundle
restartPolicy: Always
volumes:
- name: custom-truststore
secret:
secretName: mysecret
defaultMode: 400
- name: certvol
secret:
secretName: addcerts
items:
- key: ca.bundle
path: ca.bundle
---
apiVersion: v1
kind: Service
metadata:
name: delegate-service
namespace: harness-delegate-ng
spec:
type: ClusterIP
selector:
harness.io/name: delegatenew
ports:
- port: 8080