Skip to content

⚡ Copilot Token Optimization2026-07-12 — security-review #6129

Description

@github-actions

Target Workflow: security-review (Daily Security Review and Threat Modeling)

Source report: Daily Copilot Token Usage Analyzer run #29186588360
Estimated AIC per run: 104.671
Estimated total tokens per run: ~104,700
Runtime: 10.9 minutes
GitHub API calls: 11
Schedule: Daily at 06:51 UTC

Current Configuration

Setting Value
Tools loaded github (toolsets: repos, code_security), bash, cache-memory
Network groups github
Pre-agent steps Yes — fetches escape test results into /tmp/gh-aw/escape-test-summary.txt
Prompt size ~4,900 chars body + 3,225 chars shared import (mcp-pagination.md)
File evidence gathered ~106,900 chars of source files cat'd per run (~26,700 tokens)
Largest single file read containers/agent/entrypoint.sh — 65,929 chars (~16,500 tokens)

Root Cause: Massive In-Agent File Reading

The workflow prompts the agent to run a single large bash block that cats entire source files:

echo "=== CONTAINER SECURITY ==" && \
  cat containers/agent/seccomp-profile.json && \
  cat containers/agent/entrypoint.sh      # 65,929 chars alone!
echo "=== NETWORK SECURITY ===" && \
  cat src/host-iptables.ts && \
  cat containers/agent/setup-iptables.sh   # 24,411 chars

This file content enters the context as tool_result messages and stays for the rest of the session, consuming ~26,700 input tokens every single run — regardless of what actually changed in those files.

Recommendations

1. Move File Pre-processing to steps: (Pre-Agent)

Estimated savings: ~20,000–25,000 tokens/run (~20–25%)

Instead of having the agent cat large files, extract only the security-relevant sections in a pre-agent step and pass a summary. The agent doesn't need the full entrypoint.sh — it needs the capability-drop section, the chroot setup, and the DNS config.

Implementation — add to the steps: block in security-review.md:

steps:
  - name: Fetch latest escape test results
    run: |
      # ... existing escape test fetch ...

  - name: Extract security-critical code sections
    run: |
      mkdir -p /tmp/gh-aw

      # Extract capability-drop section from entrypoint.sh (~50 lines)
      grep -n -A5 -B2 'capsh\|cap_drop\|SYS_CHROOT\|SYS_ADMIN\|chroot\|UID\|GID\|nobody' \
        containers/agent/entrypoint.sh > /tmp/gh-aw/entrypoint-security.txt

      # Extract DNAT / iptables rules from setup-iptables.sh (~80 lines)
      grep -n -A3 -B1 'DNAT\|ACCEPT\|DROP\|LOG\|REJECT\|80\|443\|22\|25' \
        containers/agent/setup-iptables.sh > /tmp/gh-aw/iptables-security.txt

      # Extract seccomp syscall allow/deny list (structure only)
      jq '{defaultAction,syscalls:[.syscalls[]|{names:.names[:3],action}][:10]}' \
        containers/agent/seccomp-profile.json > /tmp/gh-aw/seccomp-summary.json 2>/dev/null || \
        cat containers/agent/seccomp-profile.json > /tmp/gh-aw/seccomp-summary.json

      # Aggregate small security-relevant TS files
      cat src/host-iptables.ts src/domain-patterns.ts src/squid-config.ts \
        > /tmp/gh-aw/ts-security-files.txt

      wc -l /tmp/gh-aw/entrypoint-security.txt /tmp/gh-aw/iptables-security.txt
    env:
      GH_TOKEN: ${{ github.token }}

Then update the Phase 2 prompt to reference these pre-extracted files instead of running cat on the originals:

## Phase 2: Codebase Security Analysis

All security-critical code sections have been pre-extracted. Read them:

```bash
cat /tmp/gh-aw/entrypoint-security.txt   # capability-drop, chroot, UID mapping
cat /tmp/gh-aw/iptables-security.txt     # NAT rules, DROP rules, LOG rules
cat /tmp/gh-aw/seccomp-summary.json      # seccomp profile summary
cat /tmp/gh-aw/ts-security-files.txt     # host-iptables.ts, domain-patterns.ts, squid-config.ts

For full file content of a specific section, use targeted grep with context:

grep -n -A20 'pattern' containers/agent/entrypoint.sh

Estimated reduction: entrypoint.sh from 16,500 tokens → ~2,000 tokens (extracted sections); setup-iptables.sh from 6,100 → ~1,500 tokens.

### 2. Remove Unused `mcp-pagination.md` Import

**Estimated savings: ~800 tokens/run (~0.8%)**

The `shared/mcp-pagination.md` import (3,225 chars, ~800 tokens) provides guidance for paginating GitHub MCP responses. The security review workflow uses `bash` for all data gathering and only calls GitHub MCP for `code_security` and `repos` toolsets with small responses (11 API calls total). Pagination guidance is not needed.

**Implementation** — remove from `security-review.md` frontmatter:

```yaml
# Remove this block:
imports:
  - shared/mcp-pagination.md

3. Scope the Evidence-Gathering Bash Block

Estimated savings: ~3,000–5,000 tokens/run (~3–5%)

The current Phase 2 bash block runs grep -r --include="*.ts" -l across all of src/ to find files related to network, injection risks, and Docker. This returns file lists which are low-signal. Replace with targeted searches for the specific patterns that matter:

Current (verbose):

echo "=== INJECTION RISKS ==" && \
  grep -rn --include="*.ts" -l "exec|spawn|shell|command" src/ && echo "---" && \
  grep -rn --include=".sh" '\${' containers/ && echo "---" && \
  grep -rn "args|argv|input" src/cli.ts

Improved (targeted):

# Only show lines with actual shell injection risk, not just file lists
grep -rn --include="*.ts" 'execa\|spawn\|exec(' src/ | grep -v '.test.ts' | head -20
grep -n 'eval\|\$\(\|`' containers/agent/entrypoint.sh | head -20

4. Reduce Output Size: Collapse Evidence Section

Estimated savings: ~2,000–4,000 output tokens/run (~2–4%)

The prompt requests a full Evidence Collection section with all commands and outputs. This drives large output tokens (the discussion body). Change the requirement to a concise summary:

Current:

### 📋 Evidence Collection
All commands run with their outputs (collapsed sections for brevity).

Improved:

### 📋 Key Evidence
Only include commands whose output directly supports a finding. Omit commands with null results.

5. Reduce Discussion Output Frequency

Estimated savings: 104 AIC every other day (~50% of current cost)

This is the most impactful structural recommendation. Full STRIDE threat modeling of a stable codebase does not change meaningfully day-to-day. Consider:

  • Change schedule from daily to weekly (cron: 51 6 * * 1 — Mondays)
  • Or keep daily but alternate: full review weekly, incremental diff review daily

Implementation:

# In security-review.md frontmatter:
on:
  schedule: weekly  # was: daily
  workflow_dispatch:

Expected Impact

Metric Current Projected Savings
Total tokens/run ~104,700 ~75,000 ~-28%
File reading tokens ~26,700 ~3,500 ~-87%
Import tokens ~800 0 -100%
AIC/run 104.671 ~75 ~-28%
Monthly AIC (daily) ~3,140 ~2,250 (daily) / ~320 (weekly) -28% to -90%

Implementation Checklist

  • Add Extract security-critical code sections step to steps: in security-review.md
  • Update Phase 2 prompt to reference pre-extracted files instead of cat-ing originals
  • Remove imports: - shared/mcp-pagination.md from frontmatter
  • Replace broad grep -r -l searches with targeted line-level grep commands
  • Update Evidence Collection section instructions to suppress null-result commands
  • (Optional) Change schedule from daily to weekly
  • Recompile: gh aw compile .github/workflows/security-review.md
  • Verify CI passes on PR
  • Compare AIC on new run vs baseline (target: ≤75 AIC/run)

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

Generated by Daily Copilot Token Optimization Advisor · 60.5 AIC · ⊞ 6.4K ·

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    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