Skip to main content
BlogDevOps

GitHub Agentic Workflows: Markdown Automation with gh aw

GitHub Agentic Workflows writes repository automation in Markdown and compiles it to locked Actions YAML. Here is what compile checks, what stays read-only, and the traps.

Matthews Wong

Software Engineer

October 202612 min read
GitHub Agentic Workflows: Markdown Automation with gh aw

Key Takeaway

GitHub Agentic Workflows, or gh-aw, lets you write repository automation as a Markdown file with YAML frontmatter, then compile it with gh aw compile into a locked Actions workflow. The agent runs read-only, and every write passes through declared safe outputs applied by separate jobs. It is in public preview, so start staged and pin what you review.

The workflow I would normally write as a pile of shell and curl was, on GitHub's sample page, a paragraph of English: summarise yesterday's issues, open one report. Above it sat a screen of YAML that decided what that paragraph was allowed to touch. That split, instructions in prose and authority in config, is the whole idea of GitHub Agentic Workflows.

This is a close reading, not a field report. I read the GitHub changelog, the gh-aw documentation pages for architecture, safe outputs, engines, frontmatter and triggers, the README, and the repo-status sample from the githubnext/agentics repository. I have not run gh-aw against a production repository, and where that matters I say so. Every flag and default below comes from a page I read on 17 October 2026.

Markdown is the source, the lock file is what runs

GitHub's changelog announced the technical preview on 13 February 2026. You describe an automation goal in a Markdown file under .github/workflows/, and the gh aw CLI converts it into a standard Actions workflow. The project's FAQ now describes gh-aw as being in public preview, and the repository is MIT licensed. Triggers are the familiar ones: issue and pull request events, a schedule, manual dispatch, or a command typed in a comment.

Two files result. The Markdown file, say repo-status.md, is the one you edit. The generated repo-status.lock.yml is the one GitHub Actions executes, and the FAQ says to commit both, because the lock file must be regenerated after any frontmatter change. The frontmatter is the contract: triggers, permissions, tools, safe outputs, engine. The body is the prompt the agent reads. The quick start only asks you to recompile when the frontmatter changed, which I read as the body being picked up at run time rather than baked into the lock file. That is my inference, so test it before relying on it.

A real workflow, read line by line

The best way to understand gh-aw is the sample GitHub points new users at: repo-status, from the githubnext/agentics repository. It creates a daily status issue. Here is its frontmatter with my comments added and the prose body trimmed.

# .github/workflows/repo-status.md  (the frontmatter of GitHub's sample,
# githubnext/agentics, comments shortened)
---
description: |
  This workflow creates daily repo status reports.

on:
  schedule: daily          # the page shows this shorthand; no cron string
  workflow_dispatch:       # so you can also press the button

permissions:               # what the AGENT job may read. Nothing here writes.
  contents: read
  issues: read
  pull-requests: read

network: defaults          # egress allowlist; explicit, no wildcard domains

tools:
  bash: ["cat", "ls", "find", "grep", "head", "tail", "wc"]
  github:
    lockdown: false        # public repo: allow reading 3rd-party issues
    min-integrity: none    # the sample opts OUT of the integrity filter

safe-outputs:              # the only writes that can ever happen
  mentions: false
  allowed-github-references: []
  create-issue:
    title-prefix: "[repo-status] "
    labels: [report, daily-status]
    close-older-issues: true
---

# Repo Status

Create an upbeat daily status report for the repo as a GitHub issue.
## What to include
- Recent repository activity (issues, PRs, discussions, releases, code changes)
- Actionable next steps for maintainers

Read it from the bottom. Safe outputs say the only write is one issue, with a fixed title prefix and labels, and that older status issues get closed. Mentions are off and external references are blocked, so a hallucinated at-mention cannot ping anyone. The permissions block is all read. The bash tool is an allowlist of seven read-only commands, not a shell.

One line deserves suspicion: min-integrity none. The architecture page says content from low-trust authors is filtered by a min-integrity threshold, and that public repositories get approved applied automatically. This sample deliberately turns the filter off and its own comment says it may examine any issue. That is a reasonable choice for a status report and a poor default to copy into a workflow that can also write.

Install, authenticate, run, and watch the bill

The quick start is five commands. The wizard asks which engine you want, configures authentication, writes the files into .github/workflows/ and can trigger a first run. Authentication is where engines differ, and for Claude Code the page is specific about a trap.

# 1. Install the GitHub CLI extension
gh extension install github/gh-aw

# 2. Pull the sample in. The wizard asks for an engine, sets up auth,
#    writes the files into .github/workflows/ and can trigger a first run.
gh aw add-wizard githubnext/agentics/repo-status

# 3. Give the chosen engine a credential. For Claude Code that is an API key.
#    A CLAUDE_CODE_OAUTH_TOKEN from "claude login" is NOT supported.
gh secret set ANTHROPIC_API_KEY < /path/to/key.txt

# 4. Only if you edited the frontmatter by hand
gh aw compile

# 5. Run it, then look at what it cost
gh aw run repo-status
gh aw status
gh aw logs                 # tokens, AI Credits and turns per run
gh aw audit RUN_ID         # one run, broken down

Copilot CLI is the default engine, so the engine field can be omitted for it. The table is the engines page, condensed. One omission is worth knowing: Codex has no default model in gh-aw, so you must set one yourself.

Engineengine valueAuthentication per the docs
GitHub Copilot CLI (default)copilotcopilot-requests: write permission, or the COPILOT_GITHUB_TOKEN secret
Claude CodeclaudeANTHROPIC_API_KEY, or Anthropic workload identity federation
OpenAI CodexcodexCODEX_API_KEY or OPENAI_API_KEY, or Azure Entra OIDC; set engine.model yourself
Google Gemini CLIgeminiGEMINI_API_KEY, or Google WIF; deprecated in favour of agy
Google Antigravity CLI (experimental)agyGEMINI_API_KEY only; Linux x64 only
PipiCopilot auth by default, or a provider key chosen by the model prefix; needs tools.github.mode gh-proxy and tools.cli-proxy true

Cost has three documented levers. The frontmatter page lists max-turns with a default of 500, max-ai-credits with a default of 1000, and timeout-minutes with a default of 20. The project site states that 1 AI Credit is one cent, so by that arithmetic the default per-run ceiling is about ten dollars. That is a ceiling, not an estimate. The FAQ adds that gh-aw itself is free and you also pay Actions minutes, free on public repositories and metered on private ones. Set a lower max-ai-credits before the first scheduled run, not after the first invoice.

What gh aw compile actually does

Compilation is the part that makes this more than a prompt in a YAML file. The architecture page says the compiler runs schema validation, an expression allowlist and action SHA pinning, then security scanners, and the quick start adds that you commit the output. The failure to avoid is quiet, and it looks like this.

# Wrong: edit the frontmatter, commit only the Markdown. Actions runs the
# .lock.yml, so the OLD triggers and permissions keep executing.
git add .github/workflows/repo-status.md
git commit -m "Run twice a day"

# Right: recompile, then commit both files and review the lock diff.
gh aw compile
git add .github/workflows/repo-status.md .github/workflows/repo-status.lock.yml
git commit -m "Run twice a day"

# The architecture page also lists extra scanners the compiler can run:
gh aw compile --actionlint --zizmor --poutine

Strict mode is on by default. The frontmatter page says a workflow compiled with strict set to false cannot run on public repositories, and the architecture page lists what strict enforces: no write permissions in the agent configuration, explicit network configuration, no wildcard domains and no deprecated fields. Those are checks on the file, which is why they sit at compile time.

The same page is candid about the limit: the compiler does not constrain runtime behaviour. It can prove your frontmatter is conservative. It cannot prove the model will behave, which is why the next section exists.

The permission split: agent reads, other jobs write

The architecture page describes a pipeline of jobs, and the useful way to hold it in your head is by who may write. The agent never does. Its output is buffered as an artifact, a detection job inspects it, and only then do narrowly permissioned jobs apply it.

JobWrite accessWhat the page says it does
ActivationNot statedPrepares context, sanitises event text, validates the lock file
AgentMinimal, read-onlyRuns the engine, redacts secrets, uploads agent_output.json
DetectionNoneEmits a pass or fail verdict on secret leaks, malicious patches and policy violations
Issue, comment and label jobsissues: writeApply the buffered request, only after a safe verdict
Pull request jobcontents: write and pull-requests: writeCreates the pull request from the buffered patch

The page lists issues: write for the issue and label jobs and contents: write plus pull-requests: write for pull request creation. For the activation job it names no permissions, so I have not guessed any. Safe outputs are the vocabulary of requests an agent may make. The safe outputs page lists dozens, from create-issue to merge-pull-request, which it marks experimental, and each has a default ceiling: create-issue allows 1, add-comment 1, close-pull-request 10.

# Safe outputs are a vocabulary of requests, each with its own ceiling.
safe-outputs:
  staged: true             # preview in the step summary, write nothing
  add-labels:
    allowed: [bug, team-*, area/*]   # anything else is refused
    blocked: ["~*", "*[bot]"]        # evaluated BEFORE allowed
    max: 10                          # label operations per run
    max-labels: 5
  add-comment:
    max: 3
    hide-older-comments: true
  submit-pull-request-review:
    allowed-events: [COMMENT]        # the agent can never APPROVE

Credentials follow the same rule. The architecture page says secrets are passed as environment variables, and that before artifacts are uploaded the files under /tmp/gh-aw are scanned and secret values masked by exact string match, not regex. The agent also runs behind a firewall whose egress goes through a domain allowlist, so an injected instruction to curl your token to a stranger has nowhere to go that you did not list.

Where it beats a hand-written workflow, and where it does not

The FAQ is blunt about the boundary: gh-aw complements Actions rather than replacing it. Deterministic work stays deterministic. The table is my comparison, built only from claims on the pages above.

ConcernHand-written Actions YAMLgh-aw
What decides each stepYou write every command in orderAn agent interprets Markdown instructions and calls the tools you allowed
Write accessWhatever the job's permissions block grants, for the whole jobAgent job read-only; writes requested through safe outputs and applied by separate jobs
Swapping the modelRewrite the steps and secrets for each CLIChange the engine field; credentials differ per engine
Supply chain hygieneYour discipline: pin actions, review expressionsCompiler pins SHAs, allowlists expressions, validates schema
Spend controlThe job timeout and whatever checks you script yourselftimeout-minutes, max-turns, max-ai-credits, plus gh aw logs and audit
Builds, tests, deploymentsThe right toolThe wrong tool, per the FAQ

The pattern the sample catalogue points at is judgement work with a small write surface: triage, status reports, documentation upkeep, link checking, reviewing failed CI. The project site lists Repo Assist, CI Doctor, Repo Status and Test Improver as its featured four. Those are tasks where a wrong answer costs a closed issue, not a bad deploy.

What goes wrong: the named trade-offs

First, the safety net has a soft layer. The detection job is itself an AI agent, so it is a probabilistic check, and the architecture page does not discuss its false-negative rate. It sits behind deterministic controls, namely read-only permissions, the firewall and the safe output caps. Treat it as a third line, not the first.

Second, the tool moves fast and has already had a security advisory. The README says GHSA-8h78-hpm7-29gg affects versions from 0.83.3 up to but excluding 0.85.4, and that those releases were retired as a precaution. The GitHub releases page showed v0.91.14 on 14 October, v0.92.0 on 15 October and v0.92.3 on 16 October 2026. That cadence is healthy for fixes and hard on anyone who wants a frozen, reviewed toolchain.

The README states that agentic workflows need careful human supervision and that you use them at your own risk. Review permissions, tools, network access and the generated lock file before deploying, and never merge a lock file you have not read.

Third, the quiet drift from the earlier section: change the frontmatter, forget to recompile, and Actions keeps running the old permissions and triggers. A CI step that runs gh aw compile and fails on a dirty diff turns that into a loud failure. That check is my suggestion, not a documented feature.

Fourth, the boundaries of support. The FAQ says macOS runners are not supported because they lack container jobs, workflows used as required status checks need inlined-imports set to true to resolve runtime imports, and older GitHub Enterprise Server instances need compatibility mode. Staging is also not a sandbox: the staged mode page warns that custom jobs, scripts and external MCP servers need their own controls.

What to do on Monday

Do not start with the featured workflows on your main repository. Start with one low-stakes automation in a throwaway repository, and widen only when the previews have been boring.

  1. Install the extension and run gh aw add-wizard githubnext/agentics/repo-status in a scratch repository. Read the lock file it generates once, end to end.
  2. Write one workflow of your own, as small as the sketch below, with staged set to true under safe-outputs. Staged mode runs the agent fully but replaces writes with a preview in the step summary.
  3. Set max-ai-credits and timeout-minutes below the defaults before the first scheduled run.
  4. Run gh aw compile in CI with the extra scanners, and fail the build if the lock file differs from what is committed.
  5. After a week, read gh aw logs. Keep the workflow only if its cost in credits is below the toil it removed, and remove the staged line only after you have read several previews.
# .github/workflows/issue-labeler.md
# Composed by me from the documented fields. Run gh aw compile before
# trusting it: I have not compiled this exact file.
---
description: Suggest one label for each newly opened issue.

on:
  issues:
    types: [opened]

permissions:
  contents: read
  issues: read

engine: claude             # needs the ANTHROPIC_API_KEY secret
network: defaults
timeout-minutes: 10        # the documented default is 20
max-ai-credits: 100        # 1 AI Credit is $0.01 per the project site

safe-outputs:
  staged: true             # delete this line only after reading a few previews
  add-labels:
    allowed: [bug, question, docs]
    max: 1
---

# Issue labeler

Read the newly opened issue. Choose exactly one of bug, question or docs.
If none clearly fits, choose nothing. Never comment, never close.

The sketch asks the agent for exactly one decision and allows exactly one write. That is the shape I would trust first: a narrow question, a closed list of answers and a cap of one.

gh aw audit with a run id breaks a single run down, and gh aw logs lists tokens, credits and turns across runs. Read both before raising a cap. A workflow that burns its budget on turns is usually asking too vague a question.

The rule I would carry out of this: put authority in frontmatter and judgement in prose, and never let the prose widen what the frontmatter allows. gh-aw makes that separation mechanical, with a compiler on one side and a read-only agent on the other. It is still a preview moving weekly, so adopt it for small, reversible tasks and keep builds and deploys in plain Actions.

FAQ

Frequently Asked Questions

Short answers to what readers ask most about this topic.

What is GitHub Agentic Workflows (gh-aw)?

GitHub Agentic Workflows is an open-source (MIT) tool for writing repository automation as a Markdown file with YAML frontmatter. The gh aw CLI compiles it into a standard GitHub Actions workflow that runs an AI coding agent. The project describes itself as being in public preview.

What does gh aw compile do?

It validates the Markdown workflow and generates a .lock.yml file that GitHub Actions actually runs. The docs say the compiler performs schema validation, expression allowlisting and action SHA pinning. You commit both files and must recompile whenever the frontmatter changes.

Can a gh-aw agent push code or close issues directly?

No. The agent job runs read-only, and writes are requested through declared safe outputs such as create-issue or add-labels. Separate jobs with their own permissions apply them, after a detection job gives a safe verdict. Each safe output has a default cap on how many operations it may perform per run.

Which AI engines does gh-aw support?

GitHub Copilot CLI is the default, and the engines page also lists Claude Code, OpenAI Codex, Google Gemini CLI, Google Antigravity (experimental) and Pi. You pick one with the engine field. Credentials differ per engine; Claude Code uses an ANTHROPIC_API_KEY secret, and a Claude login OAuth token is not supported.

How do I stop a gh-aw workflow from overspending?

Set timeout-minutes, max-turns and max-ai-credits in the frontmatter; the documented defaults are 20 minutes, 500 turns and 1000 AI Credits per run. The project site states that one AI Credit is one cent. Use gh aw logs and gh aw audit to see what each run actually consumed.