Configure Custom Certificates

For Administrators

This guide is for cluster administrators who need to configure PAC to trust self-signed certificates or custom CA certificates for Git providers.

Note: Throughout this document, <pac-namespace> or tekton-pipelines refers to the namespace where PAC is deployed. The default namespace is tekton-pipelines, but you can customize it via targetNamespace in the TektonConfig CR. Replace <pac-namespace> or tekton-pipelines with your actual namespace name if different.

This guide explains how to configure PAC to work with Git hosting services that use self-signed certificates or custom CA certificates, such as GitHub Enterprise or self-hosted GitLab.

Prerequisites

Before configuring custom certificates, ensure you have:

  • PAC component deployed
  • Administrator access to the cluster
  • Access to the CA certificate file
  • Ability to modify the TektonConfig CR

Overview

When your Git hosting service uses self-signed certificates or certificates signed by a custom CA, configure the trust chain for each outbound connection separately:

ConnectionWhat it doesConfiguration
pipelines-as-code-controller -> Git provider APIFetches repository content and reports status after webhook delivery.Mount the CA and set GIT_SSL_CAINFO and SSL_CERT_FILE in the PAC controller.
tektoncd-enhancement-controller -> Git provider APIRegisters or updates GitLab/GitHub webhooks for PAC Repository resources.Mount the same CA and set SSL_CERT_FILE (and optionally GIT_SSL_CAINFO) in the Enhancement controller.
Git provider -> PAC webhookDelivers webhook events to the PAC endpoint.The provider validates the PAC endpoint certificate. Automatic registration enables this validation by default; see webhook-target-tls-verify.

This requires:

  1. Creating a ConfigMap with the CA certificate
  2. Mounting the certificate in PAC controller pods
  3. Mounting the same certificate in the tektoncd-enhancement-controller when automatic webhook registration is used
  4. Configuring Git and HTTPS clients to use the certificate

Step 1: Prepare the CA Certificate

Obtain the CA certificate file from your Git hosting service administrator or from your organization's certificate authority.

Common locations for CA certificates:

  • Self-hosted GitLab: Usually available in the GitLab installation or from your organization's CA
  • GitHub Enterprise: Available from your GitHub Enterprise Server administrator

The certificate file should be in PEM format:

-----BEGIN CERTIFICATE-----
<certificate-content>
-----END CERTIFICATE-----

Step 2: Create ConfigMap with CA Certificate

Create a ConfigMap containing the CA certificate in the PAC namespace (default: tekton-pipelines, replace with your actual PAC namespace if different):

Method 1: From File

kubectl create configmap git-ca-cert \
  --from-file=ca.crt=/path/to/ca.crt \
  -n <pac-namespace>  # Default: tekton-pipelines

Example output:

configmap/git-ca-cert created

Method 2: Manual Creation

Create a YAML file git-ca-cert-configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: git-ca-cert
  namespace: <pac-namespace>  # Default: tekton-pipelines
data:
  ca.crt: |
    -----BEGIN CERTIFICATE-----
    <your-ca-certificate-content>
    -----END CERTIFICATE-----

Apply it:

kubectl apply -f git-ca-cert-configmap.yaml

Example output:

configmap/git-ca-cert created

Note: Replace <your-ca-certificate-content> with the actual certificate content.

Step 3: Mount Certificate in PAC Controller

Mount the certificate in the PAC controller pods by updating the TektonConfig CR.

For TektonConfig CR

On a Kubernetes cluster the PAC options live under platforms.kubernetes. The operator rejects platforms.openshift there, and rejects platforms.kubernetes on OpenShift:

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  targetNamespace: tekton-pipelines  # Default namespace, you can customize this
  platforms:
    kubernetes:
      pipelinesAsCode:
        enable: true
        options:
          disabled: false
          deployments:
            pipelines-as-code-controller:
              spec:
                template:
                  spec:
                    containers:
                    - name: pac-controller
                      volumeMounts:
                      - name: git-ca-cert
                        mountPath: /etc/ssl/certs/git-ca.crt
                        subPath: ca.crt
                        readOnly: true
                      env:
                      - name: GIT_SSL_CAINFO
                        value: /etc/ssl/certs/git-ca.crt
                      - name: SSL_CERT_FILE
                        value: /etc/ssl/certs/git-ca.crt
                    volumes:
                    - name: git-ca-cert
                      configMap:
                        name: git-ca-cert

Do not put this block on the derived OpenShiftPipelinesAsCode CR instead. The operator copies options back over from TektonConfig on every reconcile, so the mount disappears again. The one exception is a cluster where TektonConfig does not manage PAC at all — spec.profile is basic or lite — in which case the same options block goes on that CR under spec.options. See How the Operator Manages PAC.

Important:

  • The certificate is mounted at /etc/ssl/certs/git-ca.crt in the container
  • Environment variables GIT_SSL_CAINFO and SSL_CERT_FILE tell Git to use this certificate
  • After TektonConfig is updated, the Operator will automatically restart the PAC controller pods

For automatic webhook registration

If you use automatic webhook registration for GitLab or GitHub Webhook mode, mount the same CA bundle into tektoncd-enhancement-controller and set SSL_CERT_FILE. This controller is managed by TektonConfig, so update spec.pipeline.options.deployments instead of patching the Deployment directly. The controller also honors GIT_SSL_CAINFO when SSL_CERT_FILE is not set.

Example TektonConfig patch:

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pipeline:
    options:
      deployments:
        tektoncd-enhancement-controller:
          spec:
            template:
              spec:
                containers:
                - name: manager
                  volumeMounts:
                  - name: git-ca-cert
                    mountPath: /etc/ssl/certs/git-ca.crt
                    subPath: ca.crt
                    readOnly: true
                  env:
                  - name: SSL_CERT_FILE
                    value: /etc/ssl/certs/git-ca.crt
                  - name: GIT_SSL_CAINFO
                    value: /etc/ssl/certs/git-ca.crt
                volumes:
                - name: git-ca-cert
                  configMap:
                    name: git-ca-cert

The CA mounted in this section is needed only for the Enhancement controller-to-Git-provider API connection. It does not change webhook payload validation or the certificate verification performed by the Git provider when it calls the PAC webhook.

Configure automatic webhook registration

The tektoncd-enhancement-controller reads automatic webhook registration settings from the managed tektoncd-enhancement-config ConfigMap. Configure that ConfigMap through TektonConfig; do not edit the managed ConfigMap directly:

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pipeline:
    options:
      configMaps:
        tektoncd-enhancement-config:
          data:
            config: |
              pac-webhook-registration:
                enabled: true
                # Set false only when the PAC webhook certificate is not trusted
                # by the Git provider (for example, in a non-production cluster).
                webhook-target-tls-verify: false

webhook-target-tls-verify controls only whether GitLab or GitHub verifies the PAC webhook URL certificate when delivering events. It does not disable TLS verification for tektoncd-enhancement-controller or pipelines-as-code-controller when they call the Git provider API. For those connections, configure the CA mount and environment variables above. See Configure Enhancement Features via TektonConfig for the full configuration reference.

Keep webhook-target-tls-verify: true in production whenever the Git provider can trust the PAC webhook certificate. Setting it to false weakens verification of the provider-to-PAC connection and is not a substitute for installing the correct CA certificate.

Step 4: Apply Configuration

Apply the updated TektonConfig:

kubectl apply -f your-tektonconfig-file.yaml

Example output:

tektonconfig.operator.tekton.dev/config configured

The Operator reconciles the managed ConfigMap and deployments after the CR update. pac-webhook-registration.* settings are hot-reloaded and do not require a rollout; changing a CA volume or environment variable does require the corresponding controller deployment to restart. Check the affected deployments as applicable:

kubectl rollout status deployment/pipelines-as-code-controller -n <pac-namespace>  # Replace <pac-namespace> with your actual namespace (default: tekton-pipelines)
kubectl rollout status deployment/tektoncd-enhancement-controller -n <pac-namespace>

Example output:

Waiting for deployment "pipelines-as-code-controller" rollout to finish: 0 of 1 updated replicas are available...
deployment "pipelines-as-code-controller" successfully rolled out

Step 5: Verify Certificate Configuration

Check Certificate is Mounted

Verify the certificate is mounted in the PAC controller pod:

# Set your PAC namespace (default: tekton-pipelines)
PAC_NAMESPACE="tekton-pipelines"

kubectl get pod -n ${PAC_NAMESPACE} \
  -l app=pipelines-as-code-controller \
  -o jsonpath='{.items[0].spec.volumes}' | jq

Example output — the git-ca-cert volume is the one this guide adds; tls is present on every PAC controller pod:

[
  {
    "name": "git-ca-cert",
    "configMap": {
      "defaultMode": 420,
      "name": "git-ca-cert"
    }
  },
  {
    "name": "tls",
    "secret": {
      "defaultMode": 420,
      "optional": true,
      "secretName": "pipelines-as-code-tls-secret"
    }
  }
]

If only tls is listed, the operator has not applied the mount yet — or it never reached the Deployment, which is what happens when the options block was written on the derived CR instead of on TektonConfig.

You should see the volume configuration showing the certificate is mounted.

Check Enhancement controller configuration

Verify that the managed Enhancement ConfigMap contains the expected registration settings and that the controller pod has the CA environment variables:

kubectl get configmap tektoncd-enhancement-config -n <pac-namespace> -o yaml
kubectl get deployment tektoncd-enhancement-controller -n <pac-namespace> \
  -o jsonpath='{.spec.template.spec.containers[?(@.name=="manager")].env}'

The pac-webhook-registration.webhook-target-tls-verify value belongs in the ConfigMap data shown above. The CA path belongs in the Enhancement controller environment, and both settings are managed through TektonConfig.

Check PAC Controller Logs

Check the PAC controller logs for any certificate-related errors:

# Set your PAC namespace (default: tekton-pipelines)
PAC_NAMESPACE="tekton-pipelines"

kubectl logs -n ${PAC_NAMESPACE} \
  -l app=pipelines-as-code-controller \
  --tail=100

If configured correctly, you should not see SSL/TLS certificate errors in the logs.

For automatic webhook registration, check the Enhancement controller logs separately:

kubectl logs -n <pac-namespace> \
  -l app=tektoncd-enhancement-controller \
  --tail=100 | grep -Ei 'x509|certificate|tls|webhook|ProviderAPIError'

Errors such as x509: certificate signed by unknown authority in these logs indicate that the Enhancement controller cannot trust the Git provider API certificate. They are not fixed by webhook-target-tls-verify: false; mount the correct CA bundle and set SSL_CERT_FILE/GIT_SSL_CAINFO instead.

Test with a Repository

Trigger a test pipeline from a repository hosted on your Git service:

# Push a commit to trigger the pipeline
git commit --allow-empty -m "Test certificate configuration"
git push origin main

Example output:

[main abc1234] Test certificate configuration
Enumerating objects: 3, done.
Writing objects: 100% (2/2), 240 bytes | 240.00 KiB/s, done.
To https://gitlab.example.com/user/repo
   def5678..abc1234  main -> main

Check if the PipelineRun is created successfully:

kubectl get pipelineruns -n <your-namespace>

Example output:

NAME                    STARTED        DURATION   STATUS
test-pipeline-xxxxx     1 minute ago  25s        Succeeded

Troubleshooting

Check if Certificate is Not Trusted

Problem: PAC still cannot connect to your Git service due to certificate issues.

Solutions:

  1. Verify certificate format: Ensure the certificate is in PEM format with proper BEGIN/END markers
  2. Check certificate path: Verify the certificate is mounted at the correct path
  3. Verify environment variables: Ensure GIT_SSL_CAINFO and SSL_CERT_FILE are set correctly
  4. Check ConfigMap: Verify the ConfigMap exists and contains the certificate:
    kubectl get configmap git-ca-cert -n <pac-namespace> -o yaml  # Replace <pac-namespace> with your actual namespace (default: tekton-pipelines)

Example output:

apiVersion: v1
data:
  ca.crt: |
    -----BEGIN CERTIFICATE-----
    MIIDXTCCAkWgAwIBAgIJAK...
    -----END CERTIFICATE-----
kind: ConfigMap
metadata:
  name: git-ca-cert
  namespace: tekton-pipelines

Check if Certificate is Expired

Problem: The CA certificate has expired.

Solutions:

  1. Obtain a new CA certificate from your certificate authority

  2. Update the ConfigMap:

    # Replace <pac-namespace> with your actual namespace (default: tekton-pipelines)
    kubectl create configmap git-ca-cert \
      --from-file=ca.crt=/path/to/new-ca.crt \
      -n <pac-namespace> \
      --dry-run=client -o yaml | kubectl apply -f -

    Example output:

    configmap/git-ca-cert configured
  3. Restart PAC controller pods:

    kubectl rollout restart deployment/pipelines-as-code-controller -n <pac-namespace>  # Replace <pac-namespace> with your actual namespace (default: tekton-pipelines)

Wrong Certificate

Problem: Using the wrong CA certificate for your Git service.

Solutions:

  1. Verify you're using the correct CA certificate for your Git hosting service
  2. For self-hosted services, obtain the certificate directly from the service
  3. For enterprise services, contact your administrator for the correct certificate

Pod Not Restarting

Problem: PAC controller pods are not restarting after TektonConfig was updated.

Solutions:

  1. Check CR status:

    kubectl get openshiftpipelinesascodes

    Example output:

    NAME                  VERSION   READY   REASON
    pipelines-as-code    0.x.x     True    Ready
  2. Check Operator logs:

    kubectl logs -n tekton-operator -l app=tekton-operator --tail=100

Example output (example log entries):

{"level":"info","ts":"2024-01-01T12:00:00Z","logger":"operator","msg":"Processing OpenShiftPipelinesAsCode CR"}
  1. Manually restart the deployment:
    kubectl rollout restart deployment/pipelines-as-code-controller -n <pac-namespace>  # Replace <pac-namespace> with your actual namespace (default: tekton-pipelines)

Multiple Certificates

If you need to trust multiple CA certificates (e.g., multiple Git hosting services), you can:

Option 1: Combine Certificates in Single ConfigMap

Combine multiple certificates in a single file:

apiVersion: v1
kind: ConfigMap
metadata:
  name: git-ca-cert
  namespace: <pac-namespace>  # Default: tekton-pipelines
data:
  ca.crt: |
    -----BEGIN CERTIFICATE-----
    <certificate-1-content>
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    <certificate-2-content>
    -----END CERTIFICATE-----

Option 2: Use Separate ConfigMaps

Use separate ConfigMaps and mount them in different locations, then configure Git to use a certificate bundle:

env:
- name: GIT_SSL_CAINFO
  value: /etc/ssl/certs/ca-bundle.crt
- name: SSL_CERT_FILE
  value: /etc/ssl/certs/ca-bundle.crt

Create a certificate bundle by combining all certificates into a single file.

Best Practices

1. Certificate Management

  • Store securely: Keep CA certificates in secure storage
  • Version control: Track certificate changes in version control (if not sensitive)
  • Documentation: Document which certificates are used and their sources
  • Expiration tracking: Monitor certificate expiration dates

2. Security

  • Least privilege: Only grant access to necessary certificates
  • Rotation: Rotate certificates regularly
  • Validation: Validate certificates before deploying

3. Troubleshooting

  • Test first: Test certificate configuration with a test repository before applying to production
  • Monitor logs: Regularly check PAC controller logs for certificate errors
  • Backup: Keep backup copies of working certificate configurations

Next Steps