diff --git a/workshop/31-control-network-access.md b/workshop/31-control-network-access.md new file mode 100644 index 00000000..992a4eb4 --- /dev/null +++ b/workshop/31-control-network-access.md @@ -0,0 +1,105 @@ + + + + +# Control Which Domains Your Agent Can Reach + +> _Give your agent the internet access it needs, and nothing more._ + +## :dart: What You'll Do + +You'll configure the [`network:` field](https://github.github.com/gh-aw/reference/network/) on one of your workflows so it can reach only the domains you list. When you finish, you'll have a least-privilege allowlist and know how to fix a blocked request without opening everything up. + +Why this matters: the agent runs inside the [sandbox firewall](https://github.github.com/gh-aw/reference/sandbox/), so any request to an unlisted domain is blocked. That protects you from data exfiltration, but it also means every new data source or tool needs a deliberate allowlist entry. + +## :clipboard: Before You Start + +- You completed [Connect a Live Data Source to Your Workflow](16-connect-data-source.md) or have any workflow that calls an external service. +- You can compile workflows with `gh aw compile`. + +## Steps + +### Check your current default + +If a workflow has no `network:` field, it uses `network: defaults`, which allows only basic infrastructure such as certificates, JSON schema, and common package mirrors. Open your workflow and confirm whether it sets `network:` already. + +### Allow only what the workflow needs + +Add a `network:` block to the frontmatter. Mix ecosystem identifiers with specific domains: + +```markdown .github/workflows/daily-status.md +--- +on: + schedule: daily +permissions: + contents: read +network: + allowed: + - defaults + - github + - "api.example.com" +--- +``` + +Listed domains also match their subdomains. Identifiers such as `python` or `node` allow a whole package ecosystem, so prefer a specific domain when the workflow only calls one API. + +Recompile: + +```bash +gh aw compile +``` + +### Block a domain explicitly + +Use `blocked` to exclude an ecosystem or domain. Blocked entries take precedence over `allowed`: + +```markdown .github/workflows/daily-status.md +network: + allowed: + - defaults + - github + - node + blocked: + - "cdn.example.com" +``` + +### Fix a blocked request + +1. Run the workflow with `gh aw run daily-status`. +2. If the agent reports a failed request or a URL shows as `(redacted)` in its output, note the domain. +3. Add only that domain to `network.allowed`, recompile, and run again. + +The same allowlist controls network egress and which URLs survive content sanitization, so one entry fixes both. + +### Lock it down completely + +For a workflow that only reads repository data through GitHub tools, you can block all network access: + +```markdown .github/workflows/daily-status.md +network: {} +``` + +> [!NOTE] +> Hosted web search and fetch tools from Claude and Codex run on provider infrastructure, so `network.allowed` doesn't constrain them. See the [network reference](https://github.github.com/gh-aw/reference/network/) for the separate `hosted-web` policy. + +## :white_check_mark: Checkpoint + +- [ ] Your workflow has an explicit `network:` block and the lock file was recompiled +- [ ] You can explain the difference between `defaults`, `allowed`, `blocked`, and `network: {}` +- [ ] You fixed or deliberately avoided a blocked request by adding only the specific domain needed +- [ ] You committed both the `.md` and `.lock.yml` files + + +Want to choose another branch from the workshop hub? Return to [What's Next? Keep Exploring](14-next-steps.md). + diff --git a/workshop/README.md b/workshop/README.md index 97a99f9a..ff9ae214 100644 --- a/workshop/README.md +++ b/workshop/README.md @@ -42,6 +42,7 @@ A hands-on workshop that takes you from zero to a fully automated, AI-powered wo | 28 | [Orchestrate Multiple Agentic Workflows](28-orchestrate-workflows.md) | | 29 | [Teach Your Agent Domain Knowledge with Skills](29-skills-and-domain-knowledge.md) | | 30 | [Preview Your Workflow's Writes with Staged Mode](30-preview-with-staged-mode.md) | +| 31 | [Control Which Domains Your Agent Can Reach](31-control-network-access.md) | ## Optional Side Quests