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, two controller clients may need to trust the CA:

  • pipelines-as-code-controller, which fetches repository content and reports status after webhook delivery.
  • The automatic webhook registration controller, which registers or updates GitLab/GitHub webhooks by calling the Git provider API.

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 automatic webhook registration 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 the automatic webhook registration 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
                volumes:
                - name: git-ca-cert
                  configMap:
                    name: git-ca-cert

The CA is needed only for the controller-to-Git-provider API connection. It does not change webhook payload validation.

If your PAC webhook URL itself uses a self-signed certificate, the Git provider must also trust that certificate when it calls PAC. By default automatic registration enables provider-side TLS verification. For non-production environments, administrators can set pac-webhook-registration.webhook-target-tls-verify: false through TektonConfig; keep it enabled in production.

Step 4: Apply Configuration

Apply the updated TektonConfig:

kubectl apply -f your-tektonconfig-file.yaml

Example output:

tektonconfig.operator.tekton.dev/config configured

Wait for the PAC controller pods to restart:

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

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 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.

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