Skip to main content
Deploy the CertWatch Agent to Kubernetes using our official Helm chart, distributed via OCI registry.

Prerequisites

  • Kubernetes 1.19+
  • Helm 3.8+
  • CertWatch account with API key

Quick Start

Testing (Direct API Key)

For quick testing, provide the API key directly:
helm install cw-agent oci://ghcr.io/certwatch-app/helm-charts/cw-agent \
  --set agent.name=my-cluster-agent \
  --set apiKey.value=cw_your_api_key_here \
  --set certificates[0].hostname=api.example.com \
  --set certificates[0].port=443
When using apiKey.value, the key is stored in Helm release history. Use apiKey.existingSecret for production deployments.
For production, create a Kubernetes Secret first:
# Step 1: Create the secret
kubectl create secret generic cw-agent-api-key \
  --from-literal=api-key=cw_your_api_key_here

# Step 2: Install the chart referencing the secret
helm install cw-agent oci://ghcr.io/certwatch-app/helm-charts/cw-agent \
  --set agent.name=my-cluster-agent \
  --set apiKey.existingSecret.name=cw-agent-api-key \
  --set certificates[0].hostname=api.example.com \
  --set certificates[0].port=443

Configuration

Using a Values File

Create a values.yaml for your deployment:
agent:
  name: production-cluster
  syncInterval: 10m
  scanInterval: 1m

apiKey:
  existingSecret:
    name: cw-agent-api-key
    key: api-key

certificates:
  - hostname: api.mycompany.com
    port: 443
    tags:
      - production
      - api
  - hostname: web.mycompany.com
    port: 443
    tags:
      - production
      - web
  - hostname: internal-service.default.svc.cluster.local
    port: 8443
    tags:
      - internal

serviceMonitor:
  enabled: true
  labels:
    release: prometheus
Install with your values file:
helm install cw-agent oci://ghcr.io/certwatch-app/helm-charts/cw-agent -f values.yaml

Configuration Reference

API Key Options

ParameterDescription
apiKey.valueAPI key value (creates Secret, not for production)
apiKey.existingSecret.nameName of existing Secret with API key
apiKey.existingSecret.keyKey in the Secret containing API key (default: api-key)

Agent Settings

ParameterDefaultDescription
agent.name""Required. Unique agent name
agent.logLevelinfoLog level: debug, info, warn, error
agent.syncInterval5mHow often to sync with CertWatch cloud
agent.scanInterval1mHow often to scan certificates
agent.concurrency10Max concurrent certificate scans
agent.metricsPort8080Prometheus metrics port (0 to disable)
agent.heartbeatInterval30sHeartbeat interval for offline alerts

Certificate Configuration

ParameterDescription
certificatesList of certificates to monitor
certificates[].hostnameHostname to connect to
certificates[].portPort (default: 443)
certificates[].tagsTags for organization
certificates[].notesNotes about this certificate

Kubernetes Resources

ParameterDefaultDescription
replicaCount1Number of replicas
image.repositoryghcr.io/certwatch-app/cw-agentContainer image
image.tag""Image tag (defaults to chart appVersion)
resources.limits.cpu100mCPU limit
resources.limits.memory128MiMemory limit
resources.requests.cpu10mCPU request
resources.requests.memory32MiMemory request

External ConfigMap

For complex deployments, use an existing ConfigMap containing the full certwatch.yaml:
existingConfigMap:
  name: my-certwatch-config
  key: certwatch.yaml

GitOps Integration

ArgoCD

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: cw-agent
  namespace: argocd
spec:
  project: default
  source:
    repoURL: ghcr.io/certwatch-app/helm-charts
    chart: cw-agent
    targetRevision: 0.4.1
    helm:
      values: |
        agent:
          name: production-cluster
        apiKey:
          existingSecret:
            name: cw-agent-api-key
        certificates:
          - hostname: api.example.com
            port: 443
  destination:
    server: https://kubernetes.default.svc
    namespace: monitoring
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
Create the API key secret in the target namespace before deploying.

FluxCD

---
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
  name: cw-agent
  namespace: flux-system
spec:
  interval: 5m
  url: oci://ghcr.io/certwatch-app/helm-charts/cw-agent
  ref:
    tag: 0.4.1
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: cw-agent
  namespace: monitoring
spec:
  interval: 5m
  chartRef:
    kind: OCIRepository
    name: cw-agent
    namespace: flux-system
  values:
    agent:
      name: production-cluster
    apiKey:
      existingSecret:
        name: cw-agent-api-key
    certificates:
      - hostname: api.example.com
        port: 443

Prometheus Integration

Enable ServiceMonitor

If you’re using Prometheus Operator:
serviceMonitor:
  enabled: true
  interval: 30s
  labels:
    release: prometheus  # Match your Prometheus selector

Available Metrics

MetricTypeDescription
certwatch_certificate_days_until_expiryGaugeDays until certificate expires
certwatch_certificate_validGaugeCertificate validity (1=valid, 0=invalid)
certwatch_certificate_chain_validGaugeChain validity (1=valid, 0=invalid)
certwatch_scan_totalCounterTotal scans by status
certwatch_sync_totalCounterTotal syncs by status
See the Observability guide for complete metrics documentation and alerting examples.

Health Endpoints

The agent exposes Kubernetes-compatible health endpoints:
EndpointDescription
/healthzBasic liveness check
/readyzReadiness probe - 503 during init
/livezDeep liveness - 503 if no recent scans
The Helm chart automatically configures liveness and readiness probes using these endpoints.

Security

The Helm chart includes secure defaults:
  • Non-root user - Runs as UID 65534
  • Read-only filesystem - Container filesystem is read-only
  • Dropped capabilities - All Linux capabilities dropped
  • No privilege escalation - Blocks privilege escalation
podSecurityContext:
  runAsNonRoot: true
  runAsUser: 65534
  fsGroup: 65534

securityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  capabilities:
    drop:
      - ALL

Monitoring Internal Services

Monitor certificates on services within your Kubernetes cluster:
certificates:
  # Service in same namespace
  - hostname: my-service
    port: 443

  # Service in different namespace
  - hostname: api-gateway.ingress-nginx.svc.cluster.local
    port: 443

  # Ingress controller
  - hostname: ingress-nginx-controller.ingress-nginx.svc.cluster.local
    port: 443
    tags:
      - ingress
      - infrastructure

Upgrading

# Upgrade to latest version
helm upgrade cw-agent oci://ghcr.io/certwatch-app/helm-charts/cw-agent

# Upgrade to specific version
helm upgrade cw-agent oci://ghcr.io/certwatch-app/helm-charts/cw-agent --version 0.4.1

# Upgrade with values file
helm upgrade cw-agent oci://ghcr.io/certwatch-app/helm-charts/cw-agent -f values.yaml

Uninstalling

helm uninstall cw-agent

# Optionally remove the API key secret
kubectl delete secret cw-agent-api-key

Troubleshooting

Verify Deployment

# Check pod status
kubectl get pods -l app.kubernetes.io/name=cw-agent

# View logs
kubectl logs -l app.kubernetes.io/name=cw-agent -f

# Check events
kubectl describe pod -l app.kubernetes.io/name=cw-agent

Common Issues

IssueSolution
Pod in CrashLoopBackOffCheck logs: kubectl logs <pod-name>. Usually API key or agent name issues.
”agent.name is required”Set agent.name in values or via --set agent.name=...
”apiKey is required”Configure apiKey.value or apiKey.existingSecret.name
Cannot reach internal servicesEnsure agent pod can resolve and reach the target hostnames
Metrics not scrapedVerify ServiceMonitor labels match Prometheus selector

Debug Mode

Enable debug logging:
agent:
  logLevel: debug
Then view logs:
kubectl logs -l app.kubernetes.io/name=cw-agent -f