Patterns below follow TG-EXECUTION-AUTH-01. Use your own gateway URL (e.g. Cloud Run) or follow the public example repo. The site's verification API (API reference) remains live for receipt and signature checks without a gateway.
GitHub Deploy Gate
DENY production deployments in GitHub Actions until authorized by TrigGuard. Fail-closed if authorization service is unavailable.
Terraform Pre-Apply Gate
Require authorization before terraform apply. Use external data source to gate infrastructure changes.
REST API Integration
Direct API integration using curl, Python, Node.js, or Go. Verify receipts offline.
CLI Integration
Shell script patterns for command-line authorization. Exit codes, receipt caching, retry logic.
Minimal deploy (GitHub)
Public pattern with a working workflow_dispatch flow: checkout → official authorize action → simulated deploy. OIDC to GCP; no static API key.
GITHUB ACTIONS
GitHub Deploy Gate
Canonical minimal workflow: see Examples for the published uses: line and OIDC layout. The longer pattern below shows a curl-based gate for custom runners.
# Production deployment with TrigGuard authorization gate name: Deploy to Production on: push: branches: [main] jobs: authorize: runs-on: ubuntu-latest outputs: receipt_id: ${{ steps.auth.outputs.receipt_id }} steps: - name: Request TrigGuard Authorization id: auth run: | RESPONSE=$(curl -sf https://api.trigguardai.com/execute \ -H "Authorization: Bearer ${{ secrets.TRIGGUARD_API_KEY }}" \ -H "Content-Type: application/json" \ -d '{ "surface": "deploy.release", "action": "promote-to-production", "context": { "commit": "${{ github.sha }}", "branch": "${{ github.ref_name }}", "actor": "${{ github.actor }}", "repo": "${{ github.repository }}" } }') DECISION=$(echo "$RESPONSE" | jq -r '.decision') RECEIPT_ID=$(echo "$RESPONSE" | jq -r '.receipt_id') if [ "$DECISION" != "PERMIT" ]; then echo "::error::Authorization denied: $DECISION" exit 1 fi echo "receipt_id=$RECEIPT_ID" >> $GITHUB_OUTPUT echo "Authorization granted: $RECEIPT_ID" deploy: needs: authorize runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Deploy Application env: TG_RECEIPT_ID: ${{ needs.authorize.outputs.receipt_id }} run: | echo "Deploying with receipt: $TG_RECEIPT_ID" # Your deployment commands here
TERRAFORM
Terraform Pre-Apply Gate
# Request TrigGuard authorization before infrastructure changes data "http" "trigguard_auth" { url = "https://api.trigguardai.com/execute" method = "POST" request_headers = { Authorization = "Bearer ${var.trigguard_api_key}" Content-Type = "application/json" } request_body = jsonencode({ surface = "infra.terraform" action = "apply" context = { workspace = terraform.workspace environment = var.environment actor = var.actor } }) } locals { auth_response = jsondecode(data.http.trigguard_auth.response_body) authorized = local.auth_response.decision == "PERMIT" } # Fail if not authorized resource "null_resource" "authorization_check" { count = local.authorized ? 0 : 1 provisioner "local-exec" { command = "echo 'TrigGuard authorization denied' && exit 1" } } output "receipt_id" { value = local.auth_response.receipt_id description = "TrigGuard authorization receipt" }
REST API
Direct API Integration
Python
Using the requests library:
import requests
response = requests.post(
"https://api.trigguardai.com/execute",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
},
json={
"surface": "deploy.release",
"action": "promote"
}
)
if response.json()["decision"] == "PERMIT":
# Proceed with action
pass
Node.js
Using fetch:
const response = await fetch(
'https://api.trigguardai.com/execute',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
surface: 'deploy.release',
action: 'promote'
})
}
);
const { decision } = await response.json();
if (decision === 'PERMIT') {
// Proceed
}
Go
Using net/http:
req, _ := http.NewRequest(
"POST",
"https://api.trigguardai.com/execute",
bytes.NewBuffer(payload),
)
req.Header.Set("Authorization",
"Bearer "+apiKey)
req.Header.Set("Content-Type",
"application/json")
resp, _ := client.Do(req)
SHELL
CLI Integration Pattern
#!/bin/bash set -euo pipefail # TrigGuard authorization wrapper # Usage: ./authorize.sh <surface> <action> SURFACE="${1:?Surface required}" ACTION="${2:-default}" RESPONSE=$(curl -sf \ -H "Authorization: Bearer $TRIGGUARD_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"surface\": \"$SURFACE\", \"action\": \"$ACTION\"}" \ https://api.trigguardai.com/execute) DECISION=$(echo "$RESPONSE" | jq -r '.decision') RECEIPT_ID=$(echo "$RESPONSE" | jq -r '.receipt_id') case "$DECISION" in PERMIT) echo "[TG] Authorized: $RECEIPT_ID" export TG_RECEIPT_ID="$RECEIPT_ID" exit 0 ;; DENY) REASON=$(echo "$RESPONSE" | jq -r '.reason') echo "[TG] Blocked: $REASON" >&2 exit 1 ;; *) echo "[TG] Failed: $DECISION" >&2 exit 2 ;; esac
Client Libraries
Official client libraries for JavaScript, Python, Go, and Ruby are planned. The patterns above represent the current recommended integration approach via REST API.