Skip to content

safe_outputs: support local body file references with strict runtime safeguards #44951

Description

@straub

Summary

For editor/update workflows, agents often edit large content in a local file, but must still emit the full final body inline in safe output payloads. This increases token cost and context pressure.

Request: add an opt-in safe_outputs capability to reference a local file for body content (for example body_file) while preserving the existing safety model.

Background / problem

Current pattern for large updates:

  1. Read issue/PR/discussion body
  2. Write to local file
  3. Edit surgically
  4. Emit safe output

Step 4 currently requires the entire body inline, even when the authoritative edited content is already on disk.

Proposed shape (example)

{
  "type": "update_discussion",
  "discussion_number": 123,
  "body_file": "gh-aw-safe/body.md",
  "body_sha256": "<digest>"
}

Apply to body-bearing operations where appropriate (e.g. update_discussion, update_issue, update_pull_request, add_comment, etc.).

Adversarial review / threat model

A naive implementation is unsafe. Main risks:

  • policy bypass if file-based bodies skip current validators/sanitizers
  • TOCTOU mismatch between reviewed content and posted content
  • path exfiltration (pointing at unintended files)
  • reduced auditability/provenance compared with inline payloads
  • non-deterministic replay/staged behavior with mutable workspace state
  • prompt-injection pivot to attacker-controlled file paths
  • resource abuse via huge/binary files

Required guardrails

  1. Opt-in only (disabled by default)
  2. Strict path allowlist (for example under $RUNNER_TEMP/gh-aw-safe/ only)
  3. Reject traversal/symlink escapes
  4. Text-only with hard size limits
  5. body_sha256 required + verified
  6. Atomic single read/snapshot at safe-output execution
  7. Pass the exact same validation/sanitization pipeline used by inline bodies
  8. Emit audit metadata (path, digest, bytes) without leaking content by default
  9. Same deterministic behavior in staged/non-staged modes

Non-goals

  • arbitrary file references across workspace
  • bypassing existing safe-output content policy
  • changing cross-run persistence semantics

Agentic implementation plan

  1. Schema + parser updates

    • Add optional body_file / body_sha256 fields to relevant output item schemas.
    • Enforce mutual exclusivity/precedence rules between body and body_file.
  2. Path resolution hardening

    • Add a resolver that canonicalizes and enforces allowlisted root(s).
    • Block traversal and symlink escapes.
  3. Content ingestion layer

    • Read file once, compute SHA-256, verify exact digest match.
    • Enforce text-only and max-size checks before further processing.
  4. Unify policy pipeline

    • Route file-backed content into the existing body sanitizer/validator path (URL rules, mention/reference handling, footer/disclosure behavior, length constraints).
  5. Execution + observability

    • Ensure handlers use the frozen in-memory snapshot only.
    • Emit structured audit fields for file source metadata.
  6. Docs + examples

    • Update safe-outputs docs with examples and explicit security constraints.
    • Clarify recommended workflow pattern for surgical edits.
  7. Tests

    • Happy path: valid allowlisted file + digest.
    • Failure cases: digest mismatch, binary file, oversize, disallowed path, symlink escape, both body and body_file invalid combinations.
    • Verify parity with inline-body sanitization behavior.

Acceptance criteria

  • MVP support for at least one update operation using body_file
  • All guardrails above enforced
  • Inline and file-backed paths share one sanitization/validation pipeline
  • Clear compile/runtime errors for invalid references
  • Documentation includes threat model and secure usage guidance

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions