Add DIFC_FILTERED event support to gateway log parsing#21681
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
@copilot download logs until you find a log with DIFC_FILTERED event; then try out the filtering. Print out the log run url in the generated comment. |
…gateway.jsonl) Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Found run with DIFC_FILTERED events: https://github.com/github/gh-aw/actions/runs/23272536774 That run has 4 DIFC_FILTERED events in Filtering worked correctly. The generated step summary section looks like: 🔒 DIFC Filtered Events (4)
The following tool calls were blocked by DIFC integrity or secrecy checks:
| Time | Server | Tool | Reason | User | Resource |
|------|--------|------|--------|------|----------|
| 2026-03-18 23:45:22Z | github | `pull_request_read` | Resource 'pr:github/gh-aw#21582' has lower integrity... | - | pr:github/gh-aw#21582 |
...Two fixes were needed vs. the initial implementation (commit
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
| const trimmed = line.trim(); | ||
| if (!trimmed) continue; | ||
| try { | ||
| const entry = JSON.parse(trimmed); |
There was a problem hiding this comment.
@copilot do a quick string contains before parsing
There was a problem hiding this comment.
Done in 3edcb80. parseGatewayJsonlForDifcFiltered now short-circuits with !trimmed.includes("DIFC_FILTERED") before calling JSON.parse.
There was a problem hiding this comment.
Pull request overview
Adds end-to-end support for DIFC_FILTERED events so integrity/secrecy blocks are surfaced in both GitHub Actions step summaries (JS) and CLI audit/log reporting (Go).
Changes:
- Parse
gateway.jsonl/rpc-messages.jsonlforDIFC_FILTEREDevents and render a dedicated markdown summary section in the Actions step summary. - Extend Go gateway metrics to count and retain structured DIFC filtered event records, including aggregation across runs.
- Surface filtered events through CLI data models (
MCPToolUsageData/MCPToolUsageSummary) so they appear in JSON outputs.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
actions/setup/js/parse_mcp_gateway_log.cjs |
Adds JSONL scanning for DIFC_FILTERED and renders a collapsible markdown table in the step summary. |
actions/setup/js/parse_mcp_gateway_log.test.cjs |
Adds unit tests for DIFC JSONL parsing and summary rendering. |
pkg/cli/gateway_logs.go |
Extends gateway parsing/metrics to count and collect DIFC filtered events and render them in console tables. |
pkg/cli/audit_report.go |
Surfaces filtered events in MCPToolUsageData JSON output for gh aw audit. |
pkg/cli/logs_models.go |
Adds FilteredEvents to MCPToolUsageSummary model for aggregated logs output. |
pkg/cli/logs_report.go |
Aggregates FilteredEvents across runs into the overall MCP tool usage summary. |
Comments suppressed due to low confidence (1)
pkg/cli/gateway_logs.go:637
renderGatewayMetricsTablenow conditionally adds aFilteredcolumn and also renders a dedicated "DIFC Filtered Events" table, but existing tests forrenderGatewayMetricsTabledon’t exercise theTotalFiltered > 0path. Consider adding/adjusting tests to assert the extra column/table appears (and is omitted when there are no filtered events).
if hasFiltered {
output.WriteString(console.RenderTable(console.TableConfig{
Title: "Server Usage",
Headers: []string{"Server", "Requests", "Tool Calls", "Avg Time", "Errors", "Filtered"},
Rows: serverRows,
}))
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| const tool = event.tool_name ? `\`${event.tool_name}\`` : "-"; | ||
| const reason = (event.reason || "-").replace(/\n/g, " ").replace(/\|/g, "\\|"); | ||
| const user = event.author_login ? `${event.author_login} (${event.author_association || "NONE"})` : "-"; | ||
| const resource = event.html_url ? `[#${event.number}](${event.html_url})` : event.description || "-"; |
| core.summary.addRaw(gatewayMdContent); | ||
|
|
||
| // Append DIFC_FILTERED section if any events found | ||
| if (difcFilteredEvents.length > 0) { | ||
| const difcSummary = generateDifcFilteredSummary(difcFilteredEvents); |
pkg/cli/gateway_logs.go
Outdated
| ToolName string `json:"tool_name,omitempty"` | ||
| Description string `json:"description,omitempty"` | ||
| Reason string `json:"reason,omitempty"` | ||
| SecrecyTags []string `json:"secrecy_tags,omitempty"` | ||
| IntegrityTags []string `json:"integrity_tags,omitempty"` |
| // Handle DIFC_FILTERED events | ||
| if entry.Type == "DIFC_FILTERED" { | ||
| metrics.TotalFiltered++ | ||
| // DIFC_FILTERED events use server_id; fall back to server_name for compatibility | ||
| serverKey := entry.ServerID |
| // Aggregate DIFC filtered events | ||
| allFilteredEvents = append(allFilteredEvents, pr.MCPToolUsage.FilteredEvents...) |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
@copilot review all comments |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Addressed all review comments in
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Summary
Adds support for
DIFC_FILTEREDevents (DIFC integrity/secrecy check failures) across the gateway log parsing stack — both in the JavaScript step-summary renderer and the Go audit/logs reporters.Changes
JavaScript (
actions/setup/js/parse_mcp_gateway_log.cjs)parseGatewayJsonlForDifcFiltered(jsonlContent)— parsesgateway.jsonlline by line and extracts allDIFC_FILTEREDentriesgenerateDifcFilteredSummary(filteredEvents)— renders a collapsible<details>Markdown table showing Server, Tool, Reason, User (login + association), and Resource (linked issue or description)main()to always readgateway.jsonlfor DIFC events and append the section to the step summary, regardless of whethergateway.mdor legacy log files are usedJavaScript tests (
actions/setup/js/parse_mcp_gateway_log.test.cjs)parseGatewayJsonlForDifcFiltered: extraction, no-match, empty input, malformed lines, blank linesgenerateDifcFilteredSummary: empty/null inputs, table structure, field rendering (tool code format, server, reason, user, linked resource, pipe escaping), multi-event countGo (
pkg/cli/gateway_logs.go)GatewayLogEntrywith DIFC-specific JSON fields:ServerID,Reason,SecrecyTags,IntegrityTags,AuthorAssociation,AuthorLogin,HTMLURL,Number,DescriptionDifcFilteredEventstruct for structured filtered event recordsTotalFiltered intandFilteredEvents []DifcFilteredEventtoGatewayMetricsFilteredCount inttoGatewayServerMetricsprocessGatewayLogEntrynow handlestype == "DIFC_FILTERED"— increments counters and appends toFilteredEvents; also improved timestamp parsing to support RFC3339NanorenderGatewayMetricsTableshowsTotal DIFC Filteredin summary, adds aFilteredcolumn to the server table when events exist, and renders a dedicated DIFC Filtered Events tabledisplayAggregatedGatewayMetricsaggregatesTotalFiltered,FilteredCount, andFilteredEventsacross runsextractMCPToolUsageDatapopulatesFilteredEventsfrom gateway metricsGo (
pkg/cli/audit_report.go)FilteredEvents []DifcFilteredEventtoMCPToolUsageData(surfaced ingh aw auditJSON output)Go (
pkg/cli/logs_models.go)FilteredEvents []DifcFilteredEventtoMCPToolUsageSummaryGo (
pkg/cli/logs_report.go)buildMCPToolUsageSummarynow collects and aggregatesFilteredEventsacross all processed runs; updated nil-return guard to also check filtered events; updated log messageSecurity Summary
No new security vulnerabilities introduced. DIFC_FILTERED events are read-only log entries; no user input is executed or used in sensitive operations.