Skip to content

GitHub Actions

Run AI agents in CI/CD with every tool call gated, audited, and receipted.

  • A GitHub repository with a workflow that runs an AI agent
  • Runner with Docker (default ubuntu-latest runners include Docker)
name: Agent job
on: [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.py

The 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.

latchgate-ai/latchgate-action@v1 starts a self-contained LatchGate stack inside the runner. It:

  1. Generates a Docker Compose file with Gate, Redis, and OPA.
  2. Pulls the LatchGate image (digest-pinned for Redis and OPA).
  3. Starts all services and waits for the health check to pass.
  4. Exports url and compose_file as step outputs.
  5. Sets LATCHGATE_URL as an environment variable for all subsequent steps.
  6. 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.

InputRequiredDefaultDescription
versionnolatestLatchGate image tag (e.g. 0.1.0, latest)
portno3000Host port to expose the gate on
upload_ledgernotrueUpload audit ledger as a workflow artifact on completion
ledger_artifact_namenolatchgate-audit-ledgerName for the uploaded audit ledger artifact
OutputDescription
urlGate base URL (e.g. http://localhost:3000)
compose_filePath 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.

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:

Terminal window
sqlite3 audit.db "SELECT action_id, decision, trace_id FROM events ORDER BY created_at DESC LIMIT 10"
import asyncio
from 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())
- uses: latchgate-ai/latchgate-action@v1
with:
version: "0.1.0"
- uses: latchgate-ai/latchgate-action@v1
with:
port: "8080"

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 -v

The action starts three containers via Docker Compose:

ServiceImagePurpose
latchgateghcr.io/latchgate-ai/latchgate:{version}Gate server, WASM providers
redisredis:7-alpine (digest-pinned)Replay cache, budget tracking
opaopenpolicyagent/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.

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.