-
Notifications
You must be signed in to change notification settings - Fork 34
Implement agentic output collection with adversarial LLM content sanitization #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
| // Set the environment variable for subsequent steps | ||
| const fs2 = require('fs'); | ||
| fs2.appendFileSync(process.env.GITHUB_ENV, `GITHUB_AW_OUTPUT=${outputFile}\n`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot use actions/core helper to set the environment variable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done! Updated the implementation to use core.exportVariable('GITHUB_AW_OUTPUT', outputFile); instead of manually writing to process.env.GITHUB_ENV. This is cleaner and follows GitHub Actions best practices. Changes applied in commit dbb0a27.
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. 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:
|
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. 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:
|
|
@copilot update the prompt of test-claude.md and ask to respond in the action output with a haiku. |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Updated the test-claude.md prompt to include instructions for the agent to write a haiku about the analyzed PR changes to the action output. The agent will now create a creative and thoughtful poetic interpretation of the code changes and write it to the GITHUB_AW_OUTPUT file, demonstrating the new output collection functionality. Changes committed in a9d7d2c. 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:
|
|
@copilot update Claude agentic engine generated code/configuration to allow writing to the file pointed by GITHUB_AW_OUTPUT env variable. |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Updated the Claude engine to pass the 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:
|
pkg/workflow/compiler.go
Outdated
| yaml.WriteString(" let sanitized = content.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '');\n") | ||
| yaml.WriteString(" \n") | ||
| yaml.WriteString(" // Limit total length to prevent DoS (64KB max)\n") | ||
| yaml.WriteString(" const maxLength = 65536;\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allow ~1Mb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the length limit from 64KB to 1MB (1,048,576 bytes) as requested. Changes committed in c51f5f0.
pkg/workflow/compiler.go
Outdated
| yaml.WriteString(" \n") | ||
| yaml.WriteString(" // Limit number of lines to prevent log flooding (1000 max)\n") | ||
| yaml.WriteString(" const lines = sanitized.split('\\n');\n") | ||
| yaml.WriteString(" const maxLines = 1000;\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allow ~65k lines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the line limit from 1,000 to 65,000 lines as requested. Changes committed in c51f5f0.
pkg/workflow/compiler.go
Outdated
| yaml.WriteString(" \n") | ||
| yaml.WriteString(" // Remove potential shell injection patterns\n") | ||
| yaml.WriteString(" sanitized = sanitized.replace(/\\$\\([^)]*\\)/g, '[shell-command-removed]');\n") | ||
| yaml.WriteString(" sanitized = sanitized.replace(/`[^`]*`/g, '[backtick-content-removed]');\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
allow backtick (allow markdown)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the backtick sanitization to allow markdown formatting. Backticks are now preserved in the output. Changes committed in c51f5f0.
pelikhan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot apply comments
…s, and markdown backticks Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. 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:
|
pkg/workflow/compiler.go
Outdated
| yaml.WriteString(" // Remove control characters (except newlines and tabs)\n") | ||
| yaml.WriteString(" let sanitized = content.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '');\n") | ||
| yaml.WriteString(" \n") | ||
| yaml.WriteString(" // Limit total length to prevent DoS (1MB max)\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot reduce max length to 0.5mb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reduced the maximum content length limit from 1MB to 0.5MB (524,288 bytes) in the content sanitization function. Changes committed in b737de5.
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. 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:
|
pkg/workflow/compiler.go
Outdated
| yaml.WriteString(" }\n") | ||
| yaml.WriteString(" \n") | ||
| yaml.WriteString(" // Remove potential shell injection patterns\n") | ||
| yaml.WriteString(" sanitized = sanitized.replace(/\\$\\([^)]*\\)/g, '[shell-command-removed]');\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot remove this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the shell injection pattern sanitization line as requested. This allows more flexibility in legitimate agent outputs that may include command-like patterns while maintaining other security protections. Changes committed in f539410.
|
@copilot remove the shell $ sanitization line |
- Removed the line that removes $(command) patterns from sanitized content - Allows more flexibility in legitimate agent outputs that may include command-like patterns - Maintains other security protections (length limits, line limits, control character removal) - Updated all compiled workflow files to reflect the change Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. 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:
|
The shell $ sanitization line has already been removed in commit f539410. The line that previously removed 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:
|
This PR implements support for exposing outputs from agentic engines as workflow output variables, enabling downstream workflows and jobs to access results generated by AI agents. The implementation includes comprehensive security measures to protect against adversarial LLM outputs.
Implementation
The feature adds a complete pipeline for capturing agent outputs:
Pre-step: Output file setup
actions/github-script@v7to generate a random temp file under/tmpGITHUB_AW_OUTPUTenvironment variable for subsequent steps/tmpdirectory exists and verifies successful file creation for reliable LLM appendingPrompt injection
Environment variable passing
GITHUB_AW_OUTPUTis passed to both command-based and action-based engine executionPost-step: Secure output collection
GITHUB_AW_OUTPUTfile after agent executionJob output declaration
${{ needs.job-name.outputs.output }}Security Features
The sanitization implementation protects against common adversarial LLM attack vectors while allowing legitimate content:
The implementation balances security with flexibility by removing overly restrictive pattern matching that could interfere with legitimate agent outputs while maintaining essential protections against DoS attacks and malicious content injection.
Example Usage
After this change, agentic workflows automatically support secure output collection:
The agent can write to the output file when it has meaningful results to share:
Demonstration
The test-claude workflow demonstrates this functionality by instructing the agent to write a haiku about analyzed PR changes to the action output. This provides a creative example of how agents can produce structured output that other workflows can consume safely.
Testing
Added comprehensive test coverage with
TestAgenticOutputCollection()that verifies:All existing tests continue to pass, ensuring backward compatibility.
Fixes #115.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.