Skip to content

[awf] smoke-test: add services: port-mapping smoke test for --allow-host-service-ports compiler integration #1525

@lpcox

Description

@lpcox

Problem

When gh-aw compiles a workflow that uses GitHub Actions services: with port mappings, the compiler will auto-generate --allow-host-service-ports from those mappings (see gh-aw#23756). The AWF flag already exists and is implemented correctly, but there is no end-to-end smoke test validating the full path:

compiler extracts ports → $\{\{ job.services.X.ports['PORT'] }} resolves at runner time → AWF receives numeric port(s) → iptables rules allow traffic to host gateway → agent successfully reaches the service container

Without this smoke test, regressions in any of the following could go undetected:

  • containers/agent/setup-iptables.sh host-service-port iptables rules (lines 239–280)
  • src/cli.ts validateAllowHostServicePorts / applyHostServicePortsConfig
  • src/host-iptables.ts allowHostServicePorts host-side rules
  • src/docker-manager.ts AWF_HOST_SERVICE_PORTS env var injection

Context

  • Upstream feature request: feat: auto-generate --allow-host-service-ports from services: port mappings gh-aw#23756
  • The --allow-host-service-ports flag is fully implemented in AWF (src/cli.ts:1325, containers/agent/setup-iptables.sh:239–280, src/host-iptables.ts:457–464)
  • Existing unit tests cover the flag in isolation (tests/integration/host-tcp-services.test.ts, src/host-iptables.test.ts:810, src/cli-workflow.test.ts:137)
  • No smoke workflow currently exercises services: port mappings end-to-end

Root Cause

The AWF repository has no smoke test that boots a real GitHub Actions service container (e.g., Redis or PostgreSQL), lets the compiler-generated $\{\{ job.services.X.ports['PORT'] }} expression resolve to a concrete port, and verifies the AWF agent can actually reach that service.

Relevant files:

  • .github/workflows/smoke-*.md — smoke workflow sources (compiled with gh-aw compile)
  • containers/agent/setup-iptables.sh:239–280 — where AWF_HOST_SERVICE_PORTS is converted to per-port ACCEPT rules scoped to the host gateway IP
  • src/cli.ts:705–770 — port validation and auto-enable-host-access logic
  • src/host-iptables.ts:457–464 — host-side iptables rules for service ports

Proposed Solution

Add a new smoke workflow (e.g., .github/workflows/smoke-services.md) that:

  1. Declares a services: block with at least Redis and PostgreSQL using explicit port mappings:

    services:
      redis:
        image: redis:7
        ports:
          - 6379:6379
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: testpass
        ports:
          - 5432:5432
    ```
    
  2. Passes compiler-generated expressions to AWF via --allow-host-service-ports:

    --allow-host-service-ports "$\{\{ job.services.redis.ports['6379'] }},$\{\{ job.services.postgres.ports['5432'] }}"
    
  3. Instructs the agent (e.g., Claude or Copilot) to:

    • Run redis-cli -h localhost -p $\{\{ job.services.redis.ports['6379'] }} ping and verify PONG
    • Run pg_isready -h localhost -p $\{\{ job.services.postgres.ports['5432'] }} and verify success
    • No special AWF context should be given to the agent — it should use the services as any normal workflow would
  4. The agent must not be told about AWF port configuration — the whole point is that the compiler handles it transparently.

Implementation steps:

  1. Create .github/workflows/smoke-services.md following the pattern of existing smoke workflows
  2. Run gh-aw compile .github/workflows/smoke-services.md to generate the .lock.yml
  3. Run npx tsx scripts/ci/postprocess-smoke-workflows.ts to post-process the lock file (replace GHCR refs with local build, per AGENTS.md)
  4. Add the workflow to the CI matrix (or run standalone on push/schedule)

Validation:

  • Smoke passes end-to-end: agent reaches Redis and PostgreSQL via localhost
  • awf-squid access log shows no blocked traffic to host gateway ports
  • Verifies that dangerous ports (6379, 5432) are reachable via host gateway but NOT to the open internet (existing host-tcp-services.test.ts already covers the negative case)

Generated by Firewall Issue Dispatcher ·

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions