Back to Insights
The Governance API: Integrating GuardSpine Into Your Stack
AI Governance Code Governance GuardSpine API Integration DevOps

The Governance API: Integrating GuardSpine Into Your Stack

Your CI/CD pipeline has no governance layer and ripping it out is not an option. GuardSpine's API takes a diff, returns an evidence bundle. Webhooks, REST, and drop-in integration.

The last governance tool your team evaluated required a six-week integration project, a dedicated Slack channel for troubleshooting, and a “solutions architect” who billed $300 an hour to configure webhooks. By month two, half the team had found workarounds to skip it entirely. By month four, the contract was up for “re-evaluation.” You know how that story ends.

Governance tools fail at integration for a predictable reason: they want to own your pipeline. They insert themselves as a sequential gate, demand custom runners, and break when your CI system updates. They are fragile by design because fragility creates lock-in.

GuardSpine’s API takes the opposite approach. Send it a diff, get back an evidence bundle. One HTTP call. If you can run curl, you can integrate governance. Everything else — GitHub Actions, GitLab CI, webhooks, n8n workflows — is a convenience layer on top of that single interaction.

The Core Endpoint

The fundamental API call submits a change for review and returns an evidence bundle:

curl -X POST https://api.guardspine.dev/v1/review \
  -H "Authorization: Bearer $GUARDSPINE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "diff": "diff --git a/src/auth/login.ts ...",
    "context": {
      "repository": "myorg/myapp",
      "branch": "feature/oauth-refactor",
      "commit": "a1b2c3d4",
      "author": "jane@example.com",
      "pr_number": 42
    },
    "rubric": "default"
  }'

The response contains the complete evidence bundle:

{
  "bundle_id": "f8a2c3d1-4b5e-6f7a-8b9c-0d1e2f3a4b5c",
  "risk_tier": "L2",
  "decision": "approved",
  "council_votes": [
    {
      "model": "claude-3.5-sonnet",
      "decision": "approve",
      "findings": [],
      "agreement_score": 0.92
    },
    {
      "model": "gpt-4",
      "decision": "approve",
      "findings": [
        {
          "line": 15,
          "severity": "info",
          "message": "Consider using constant-time comparison for token validation"
        }
      ],
      "agreement_score": 0.92
    }
  ],
  "evidence_bundle": { ... },
  "escalation_required": false
}

Three fields in the request. A diff, the context about where it came from, and which rubric to apply. Three fields in the response that matter immediately: risk tier, decision, and whether escalation is required. The full evidence bundle is there for audit purposes, but the decision is what your CI pipeline acts on.

Authentication

Every API call requires a bearer token. Tokens are scoped to an organization and can be restricted to specific repositories or rubrics. A token for your production repository should not have access to submit reviews for your internal tools repository.

Token creation and rotation happens through the management API or the dashboard. Tokens have expiration dates. There is no “never expires” option. If you need long-lived access, set a 90-day expiration and automate rotation. Forgotten credentials with infinite lifetimes are a governance problem, and I am not going to build one into a governance tool.

# Create a scoped token
curl -X POST https://api.guardspine.dev/v1/tokens \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -d '{
    "name": "github-actions-myapp",
    "scope": {
      "repositories": ["myorg/myapp"],
      "rubrics": ["default", "hipaa"]
    },
    "expires_in_days": 90
  }'

Webhook Integration

For event-driven architectures, GuardSpine can send webhooks when specific events occur:

{
  "webhooks": [
    {
      "url": "https://your-app.com/hooks/guardspine",
      "events": ["review.completed", "escalation.required", "bundle.sealed"],
      "secret": "whsec_..."
    }
  ]
}

The webhook payload includes a signature header (X-GuardSpine-Signature) computed as HMAC-SHA256 of the payload body using the webhook secret. Verify this signature before processing the webhook. Every webhook integration guide says this and most developers skip it. Do not skip it.

Three webhook events cover most use cases:

review.completed fires when the AI council finishes its review, regardless of the decision. Use this to update your PR with review comments or status checks.

escalation.required fires when a review triggers human escalation. Use this to notify the right people through your existing alerting system — Slack, PagerDuty, email, whatever your team uses.

bundle.sealed fires when the evidence bundle is finalized with signatures. Use this to archive the bundle to your long-term storage or send it to your compliance system.

CI/CD Integration Patterns

GitHub Actions (Pre-Built)

The simplest integration. Add codeguard-action to your workflow:

- uses: DNYoussef/codeguard-action@v1
  with:
    api_key: ${{ secrets.GUARDSPINE_API_KEY }}
    rubric: default
    fail_on: L3

The fail_on parameter controls which risk tier blocks the pipeline. Set it to L3 and L0-L2 changes pass through. Set it to L2 if you want tighter control. Set it to L4 if you only want to block the most critical changes.

GitLab CI

guardspine-review:
  stage: review
  image: curlimages/curl:latest
  script:
    - |
      DIFF=$(git diff origin/main...HEAD)
      RESPONSE=$(curl -s -X POST https://api.guardspine.dev/v1/review \
        -H "Authorization: Bearer $GUARDSPINE_API_KEY" \
        -H "Content-Type: application/json" \
        -d "{\"diff\": $(echo "$DIFF" | jq -Rs .), \"context\": {\"repository\": \"$CI_PROJECT_PATH\", \"branch\": \"$CI_COMMIT_REF_NAME\", \"commit\": \"$CI_COMMIT_SHA\"}, \"rubric\": \"default\"}")
      TIER=$(echo "$RESPONSE" | jq -r '.risk_tier')
      echo "Risk tier: $TIER"
      if [ "$TIER" = "L3" ] || [ "$TIER" = "L4" ]; then
        echo "High-risk change detected. Escalation required."
        exit 1
      fi
  rules:
    - if: $CI_MERGE_REQUEST_IID

Jenkins

stage('Governance Review') {
    steps {
        script {
            def diff = sh(script: 'git diff origin/main...HEAD', returnStdout: true)
            def response = httpRequest(
                url: 'https://api.guardspine.dev/v1/review',
                httpMode: 'POST',
                customHeaders: [[name: 'Authorization', value: "Bearer ${env.GUARDSPINE_API_KEY}"]],
                requestBody: JsonOutput.toJson([
                    diff: diff,
                    context: [repository: env.JOB_NAME, branch: env.BRANCH_NAME, commit: env.GIT_COMMIT],
                    rubric: 'default'
                ])
            )
            def result = readJSON text: response.content
            if (result.escalation_required) {
                error "Escalation required: ${result.risk_tier}"
            }
        }
    }
}

The pattern is identical across CI systems: get the diff, send it to the API, check the response, and act on the decision. The API does not care what CI system you use. It takes a diff and returns a verdict.

Batch Review for Large Changes

Some changes are too large for a single API call. A migration that touches 200 files or a refactor across the entire codebase would produce a diff that exceeds practical size limits. The batch endpoint handles this:

curl -X POST https://api.guardspine.dev/v1/review/batch \
  -H "Authorization: Bearer $GUARDSPINE_API_KEY" \
  -d '{
    "chunks": [
      {"diff": "...", "files": ["src/auth/login.ts", "src/auth/session.ts"]},
      {"diff": "...", "files": ["src/api/routes.ts", "src/api/middleware.ts"]}
    ],
    "context": { ... },
    "rubric": "default"
  }'

Each chunk is reviewed independently by the council. The response includes per-chunk risk tiers and a rollup risk tier for the entire batch (the maximum tier across all chunks). The evidence bundle contains all chunks, and the hash chain covers the full set.

Chunking is automatic in the GitHub Action. If the diff exceeds the configured threshold, it splits by file group and submits a batch review. You do not need to handle this yourself unless you are using the API directly.

Retrieving and Querying Bundles

Evidence bundles are stored and queryable through the API:

# Get a specific bundle
curl https://api.guardspine.dev/v1/bundles/f8a2c3d1-4b5e-6f7a-8b9c-0d1e2f3a4b5c \
  -H "Authorization: Bearer $GUARDSPINE_API_KEY"

# Query bundles by date range and risk tier
curl "https://api.guardspine.dev/v1/bundles?from=2026-01-01&to=2026-03-31&risk_tier=L3,L4" \
  -H "Authorization: Bearer $GUARDSPINE_API_KEY"

# Export bundles for audit
curl "https://api.guardspine.dev/v1/bundles/export?from=2026-01-01&to=2026-03-31&format=zip" \
  -H "Authorization: Bearer $GUARDSPINE_API_KEY" \
  -o audit-q1-2026.zip

The export endpoint produces a ZIP file containing every evidence bundle in the date range, plus a manifest with bundle IDs, timestamps, risk tiers, and root hashes. Hand this to your auditor. They can verify any bundle independently with guardspine-verify.

Rate Limits and Pricing

The API has rate limits to prevent abuse and ensure fair usage. The current limits are:

  • Free tier: 100 reviews per month, 1 repository, default rubric only
  • Team tier: 2,000 reviews per month, unlimited repositories, custom rubrics
  • Organization tier: Unlimited reviews, dedicated infrastructure, SLA

Rate limit headers are included in every response (X-RateLimit-Remaining, X-RateLimit-Reset). If you hit the limit, the API returns 429 with a Retry-After header. Your CI pipeline should handle this gracefully — queue the review and retry, not fail the build.

The Integration Principle

I built the API to be the smallest possible surface that delivers governed code review. One endpoint to submit a review. One endpoint to query bundles. Webhooks for event-driven workflows. Authentication with scoped, expiring tokens.

You should not need to rewrite your CI/CD pipeline to add governance. You should need to add one step — a single API call — to your existing pipeline. If integration takes more than an afternoon, the API is too complicated.

Governance that is hard to integrate does not get integrated. Governance that requires a three-month migration project stays on the roadmap. The API exists so that governance can be a Thursday afternoon addition, not a quarterly initiative.


Want to integrate GuardSpine into your CI/CD pipeline? Book a technical walkthrough and I will help you wire it up on a call.