Skip to main content

CI/CD Integration

Add a safety gate to your pipeline. Before deploying, call the validate endpoint to check if the target cluster is safe.

GitHub Actions

- name: ChangeGuard Safety Check
  run: |
    RESULT=$(curl -s -X POST https://api.changeguard.ai/api/validate \
      -H "X-API-Key: ${{ secrets.CHANGEGUARD_KEY }}" \
      -H "Content-Type: application/json" \
      -d '{
        "cluster_id": "production",
        "resource": "deployment/${{ github.event.repository.name }}",
        "namespace": "default",
        "action": "image_update",
        "image": "${{ env.IMAGE_TAG }}",
        "user": "${{ github.actor }}",
        "source": "github-actions"
      }')
    DECISION=$(echo $RESULT | jq -r '.decision')
    SCORE=$(echo $RESULT | jq -r '.csc_score')
    echo "CSC Score: $SCORE — Decision: $DECISION"
    if [ "$DECISION" = "BLOCK" ]; then
      echo "::error::Deployment blocked — CSC score too low ($SCORE)"
      exit 1
    fi

ArgoCD PreSync Hook

Add a Job with the PreSync annotation to validate before every sync:
apiVersion: batch/v1
kind: Job
metadata:
  name: changeguard-check
  annotations:
    argocd.argoproj.io/hook: PreSync
spec:
  template:
    spec:
      containers:
        - name: validate
          image: curlimages/curl
          command: ["sh", "-c"]
          args:
            - |
              RESULT=$(curl -sf -X POST https://api.changeguard.ai/api/validate \
                -H "X-API-Key: $(cat /secret/api-key)" \
                -H "Content-Type: application/json" \
                -d '{"cluster_id":"production","resource":"argocd-sync","source":"argocd"}')
              DECISION=$(echo $RESULT | grep -o '"decision":"[^"]*"' | cut -d'"' -f4)
              [ "$DECISION" = "BLOCK" ] && exit 1 || exit 0
      restartPolicy: Never