Skip to content

Egress findings say where they are: egressAt in the audit, kinds in X-Cordon-Report - #148

Merged
askalf merged 2 commits into
mainfrom
audit-egress-kinds
Oct 14, 2026
Merged

askalf merged 2 commits into
mainfrom
audit-egress-kinds

Conversation

@askalf

@askalf askalf commented Oct 14, 2026

Copy link
Copy Markdown
Owner

Report-only traffic records only egress: "egress" for a request that would have been refused. That says that a declared identifier survived redaction, but not which kind or where. Without that, a would-refuse in real traffic can't be traced without looking at the body.

  • egressViolations(…, where?): given a map, it records per kind the first place found, plus the reading that caught it: pattern, folded or digits. A location is a path of protocol keys and array indexes, e.g. $.messages[2].content[0].content. A caller-defined key is written * (and *<key> when the key itself matched), so a path never carries text. leaves keeps a parallel path list only when asked, so the default path is unchanged.
  • Audit: the record gains optional egressAt. It is hashed into the chain only when present, so older records verify as before.
  • X-Cordon-Report: gains ; kinds=SUBJECTn_KIND,… on a would-refuse.
  • Docs: README and docs/reference.md are updated, with a CHANGELOG entry.

Tests

  • Unit: a caller key is located as *<key>, and a tool result at its content field.
  • Proxy: a report-only would-refuse names its kinds in the header, and the audit records $.system (pattern) without the value.
  • Results: npm test is all green (262/205/18/5/156/117/94), and the subject fuzz passes at 500 runs per property.

…-Cordon-Report

When the egress check finds a declared identifier, the audit record now carries, per kind, the first place it was found (protocol keys and array indexes, a caller-defined key written *) and which reading caught it (pattern, folded, digits); a report-only X-Cordon-Report lists the kinds. No text is recorded. A would-refuse in report-only traffic can then be traced to its place in the body without the value.
@github-actions github-actions Bot added documentation Improvements or additions to documentation proxy The fail-closed request path audit Audit trail tests Test suite and CI size/M 50-199 hand-written lines labels Oct 14, 2026

@sprayberry-redline sprayberry-redline left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: request changes. The audit and report-header changes carry the first egress location without exposing the matched value, but the changelog entry is currently hidden inside a comment and will not document the release.

1. Blocking: CHANGELOG.md:11

  • Egress findings say where they are: when the egress check finds a declared identifier, the audit record carries egressAt (per kind, the first place it was found, as protocol keys and array indexes with caller-defined keys written *, and which reading caught it), and a report-only X-Cordon-Report lists the kinds. Never text: a would-refuse in report-only traffic can be traced to its place in the body without the value.

This new release note is between the opening <!-- on line 7 and its closing --> on line 15. Renderers and changelog readers therefore omit it, leaving the new externally visible audit and header behavior undocumented in the Unreleased section.

Suggested fix:

Move this entry into the `## [Unreleased]` / `### Added` section after the closing comment.

rule:none

@askalf

askalf commented Oct 14, 2026

Copy link
Copy Markdown
Owner Author

Fix at 5e80918

  • [1] CHANGELOG.md: The egressAt / X-Cordon-Report kinds entry, and the stray ### Added heading that came with it, were inside the release-convention <!-- ... --> comment. Both are out of the comment now, and the entry is the last item under ## [Unreleased] / ### Added, so renderers and the release-notes reader pick it up. The comment is back to its original text, and nothing else in the file changed.

Files: CHANGELOG.md

Tests: npm test exited 0 (5 pass, 0 fail)

@sprayberry-redline sprayberry-redline left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: approve. The egress scan now preserves a text-free first-hit location per subject kind, hashes it into audit records when present, and reports the corresponding kinds for report-only requests. The added unit and proxy coverage exercise caller-key redaction, tool-result paths, audit locations, and the response header.

@askalf
askalf merged commit 42152cf into main Oct 14, 2026
14 checks passed
@askalf
askalf deleted the audit-egress-kinds branch October 14, 2026 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

audit Audit trail documentation Improvements or additions to documentation proxy The fail-closed request path size/M 50-199 hand-written lines tests Test suite and CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants