GitHub Actions
Run AI agents in CI/CD with every tool call gated, audited, and receipted.
Prerequisites
Section titled “Prerequisites”- A GitHub repository with a workflow that runs an AI agent
- Runner with Docker (default
ubuntu-latestrunners include Docker)
Quick start
Section titled “Quick start”name: Agent jobon: [workflow_dispatch]
jobs: run-agent: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Start LatchGate uses: latchgate-ai/latchgate-action@v1 id: latchgate
- name: Run agent run: python my_agent.pyThe action starts LatchGate + Redis + OPA via Docker Compose, waits for health, and exports LATCHGATE_URL as an environment variable for all subsequent steps. On completion, the audit ledger is automatically uploaded as a workflow artifact.
What the action does
Section titled “What the action does”latchgate-ai/latchgate-action@v1 starts a self-contained LatchGate stack inside the runner. It:
- Generates a Docker Compose file with Gate, Redis, and OPA.
- Pulls the LatchGate image (digest-pinned for Redis and OPA).
- Starts all services and waits for the health check to pass.
- Exports
urlandcompose_fileas step outputs. - Sets
LATCHGATE_URLas an environment variable for all subsequent steps. - Uploads the audit ledger as a workflow artifact when the job completes (enabled by default).
The agent process connects via LATCHGATE_URL and all tool calls go through the standard enforcement pipeline.
Inputs
Section titled “Inputs”| Input | Required | Default | Description |
|---|---|---|---|
version | no | latest | LatchGate image tag (e.g. 0.1.0, latest) |
port | no | 3000 | Host port to expose the gate on |
upload_ledger | no | true | Upload audit ledger as a workflow artifact on completion |
ledger_artifact_name | no | latchgate-audit-ledger | Name for the uploaded audit ledger artifact |
Outputs
Section titled “Outputs”| Output | Description |
|---|---|
url | Gate base URL (e.g. http://localhost:3000) |
compose_file | Path to the generated docker-compose file |
LATCHGATE_URL is also set as an environment variable for all subsequent steps — you don’t need to pass it manually.
Audit trail as artifact
Section titled “Audit trail as artifact”The action uploads the audit ledger automatically by default (upload_ledger: true). The artifact is named latchgate-audit-ledger and captured even when the agent step fails — which is often when audit evidence matters most.
To disable automatic upload:
- uses: latchgate-ai/latchgate-action@v1 with: upload_ledger: "false"To customize the artifact name:
- uses: latchgate-ai/latchgate-action@v1 with: ledger_artifact_name: "my-agent-audit"Download the artifact from the Actions tab and inspect it locally:
sqlite3 audit.db "SELECT action_id, decision, trace_id FROM events ORDER BY created_at DESC LIMIT 10"Using with the Python SDK
Section titled “Using with the Python SDK”import asynciofrom latchgate import LatchGateClient
async def main(): # LATCHGATE_URL is set automatically by the action async with LatchGateClient(agent_id="ci-agent") as client: result = await client.execute("http_fetch", { "url": "https://api.github.com/repos/latchgate-ai/latchgate", }) print(result.output) print(f"receipt: {result.receipt_id}")
asyncio.run(main())Examples
Section titled “Examples”Pinned version
Section titled “Pinned version”- uses: latchgate-ai/latchgate-action@v1 with: version: "0.1.0"Custom port
Section titled “Custom port”- uses: latchgate-ai/latchgate-action@v1 with: port: "8080"Explicit cleanup mid-job
Section titled “Explicit cleanup mid-job”The runner VM is destroyed after the job, removing all state. For workflows that need ports or resources freed mid-job:
- uses: latchgate-ai/latchgate-action@v1 id: latchgate
- run: python my_agent.py
- name: Stop LatchGate if: always() run: docker compose -f ${{ steps.latchgate.outputs.compose_file }} down -vWhat runs
Section titled “What runs”The action starts three containers via Docker Compose:
| Service | Image | Purpose |
|---|---|---|
latchgate | ghcr.io/latchgate-ai/latchgate:{version} | Gate server, WASM providers |
redis | redis:7-alpine (digest-pinned) | Replay cache, budget tracking |
opa | openpolicyagent/opa:1.16.1 (digest-pinned) | Rego policy engine |
Redis and OPA images are pinned by @sha256: digest to prevent supply-chain attacks. The digests are updated alongside the main LatchGate release.
Security notes
Section titled “Security notes”The action runs with LATCHGATE_DEV_MODE=true (ephemeral keys, TCP transport). This is appropriate for ephemeral CI runners where UDS identity is not meaningful. For self-hosted runners in production environments, consider running LatchGate as a sidecar service with UDS transport and peercred identity.
All containers run with read_only: true where possible. The audit ledger captures every decision with hash-chain integrity. The runner VM is destroyed after the job, removing all state.
For production deployment and configuration, see Deployment and Configuration.