GitHub Actions and CI/CD
EnforceAuth fits into the same Git workflow you use for application code: push Rego changes, run tests in CI, deploy bundles to your bundle destination, and track every run on the Deployments page.
This guide covers GitHub specifically — GitHub App for policy sources, OIDC trust policies for deploy authentication, and the deploy-action for pipeline deploys.
How the pieces fit
Developer pushes to policies/**
│
▼
GitHub Actions workflow
│ OIDC token (no API key)
▼
EnforceAuth API — start deployment
│ clone → opa test → build bundle → upload
▼
S3 / GCS / Azure (bundle destination)
│
▼
OPA / EOPA PDPs poll new bundle
Policy read (clone private repos) uses the GitHub App or a credentials secret.
Policy deploy (trigger EnforceAuth pipeline) uses trust policies + OIDC — not long-lived API keys.
Step 1 — Connect GitHub for policy sources
If your policy repo is private:
- Open System Settings → Integrations (
/system-settings/integrations) - Click Connect GitHub
- Choose github.com or GitHub Enterprise Server (enter hostname if GHE)
Install the app on the org/repos that hold Rego. Then configure Policy sources on your system entity with Storage Type: Git, repository URL, branch, and policy path.
Alternatively, store a GitHub PAT in Secrets and reference it in the policy source Credentials Secret field.
Step 2 — Configure a CI provider (tenant level)
Trust policies bind to a CI provider record:
- Open System Settings → CI Providers (
/system-settings/ci-providers) - Ensure a GitHub provider exists (created automatically when GitHub is connected, or add manually)
- Note the provider's issuer and audience — GitHub Actions OIDC uses
token.actions.githubusercontent.com
For GitLab, CircleCI, or generic OIDC, add the matching provider type and JWKS URI per your platform's documentation.
Step 3 — Create a trust policy on the entity
Trust policies authorize which pipelines may deploy to which entity.
- Open your system entity (
/entities/:id) - Go to the CI/CD Tokens tab
- Click Add Trust Policy
- Fill in:
| Field | Example | Purpose |
|---|---|---|
| Name | main branch deploys | Human-readable label |
| Repository pattern | your-org/policies | GitHub owner/repo |
| Branch pattern | refs/heads/main | Ref that may deploy |
| Environment | production | Optional GitHub Environment name |
| Actor pattern | * | GitHub user triggering the workflow |
| Scopes | pipeline:deploy | Permission to start deployments |
Inherited trust policies from parent orgs appear with an Inherited badge.
Use View workflow example in the console to copy a starter workflow for this policy.
Step 4 — Add deploy-action to your workflow
Repository: github.com/EnforceAuth/deploy-action
Minimal workflow
name: Deploy Policies
on:
push:
branches: [main]
paths:
- 'policies/**'
permissions:
id-token: write # Required for OIDC
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy OPA bundle
uses: EnforceAuth/deploy-action@v1
with:
entity-id: ${{ vars.ENFORCEAUTH_ENTITY_ID }}
Store ENFORCEAUTH_ENTITY_ID as a repository or org variable (vars.ENFORCEAUTH_ENTITY_ID). Copy the entity ID from the entity detail page URL or settings.
Deploy to a named environment
Match the environment field on your trust policy and EnforceAuth entity environment config:
- name: Deploy to staging
uses: EnforceAuth/deploy-action@v1
with:
entity-id: ${{ vars.ENFORCEAUTH_ENTITY_ID }}
environment: staging
Wait for completion and surface outputs
- name: Deploy OPA bundle
id: deploy
uses: EnforceAuth/deploy-action@v1
with:
entity-id: ${{ vars.ENFORCEAUTH_ENTITY_ID }}
wait-for-completion: 'true'
timeout-minutes: '15'
- name: Print result
run: |
echo "Run ID: ${{ steps.deploy.outputs.run-id }}"
echo "Status: ${{ steps.deploy.outputs.status }}"
echo "Bundle version: ${{ steps.deploy.outputs.bundle-version }}"
Action inputs reference
| Input | Required | Default | Description |
|---|---|---|---|
entity-id | Yes | — | Target system entity UUID |
api-url | No | https://api.enforceauth.com | Use https://api.enforceauth.dev for dev |
environment | No | default env | Must match entity environment name |
wait-for-completion | No | true | Poll until Success/Failed/Timeout |
timeout-minutes | No | 10 | Max wait (1–60) |
dry-run | No | false | Validate trust without deploying |
Action outputs
| Output | Description |
|---|---|
run-id | EnforceAuth deployment run ID |
status | success, failed, timeout, pending, in_progress |
bundle-version | Published bundle version on success |
duration-seconds | Pipeline duration |
Step 5 — Verify in the console
Open Deployments. CI-triggered runs show GitHub Actions (or CI/CD) as the initiator. Open the run detail to walk phases: Fetching → Testing → Building → Deploying → Complete.
Correlate the run ID with your workflow logs using steps.deploy.outputs.run-id.
Security model
| Concern | Approach |
|---|---|
| Deploy credentials | OIDC — short-lived per-workflow token, no stored secret |
| Scope of deploy | Trust policy patterns (repo, branch, environment, actor) |
| Policy repo access | GitHub App or scoped PAT in Secrets |
| PDP telemetry | Separate API keys with decisions:write — not used by deploy-action |
| Audit | Every deploy records repository, ref, commit, and actor in EnforceAuth |
Troubleshooting
| Error | Fix |
|---|---|
Failed to get GitHub OIDC token | Add permissions: id-token: write to the job |
No matching trust policy | Repository/branch/environment on the policy must match the workflow run |
| Trust policy disabled | Re-enable on entity CI/CD Tokens tab |
| Deployment times out | Increase timeout-minutes; check Testing phase (opa test failures) |
| Wrong environment bundle | Set environment: input to match EnforceAuth environment name |
| Deploy OK but Fetching failed earlier | CI auth ≠ Git clone auth — see Integrations troubleshooting |
Git clone and S3 upload failures are usually policy source or bundle destination issues, not the deploy-action itself. Use Integrations troubleshooting when the pipeline fails before or during Deploying.
Auto-deploy on Git push (alternative)
Instead of a workflow file, enable Auto-deploy on the entity Environments configuration for a Git-backed policy source. EnforceAuth webhook deploys on push — useful for dev, but most production teams prefer explicit deploy-action gates and GitHub Environment protection rules.
Related guides
- Deployments — run history, promotion, restore
- Policy sources — Git connection
- Bundle destinations — where bundles land
- 15-minute quickstart
- deploy-action README