Skip to content

feat: add mask_stdout to redact secrets from sandboxed process output#6

Open
machado144 wants to merge 4 commits intomainfrom
feat/mask-stdout
Open

feat: add mask_stdout to redact secrets from sandboxed process output#6
machado144 wants to merge 4 commits intomainfrom
feat/mask-stdout

Conversation

@machado144
Copy link
Contributor

Summary

  • Adds a mask_stdout config block that intercepts stdout/stderr from sandboxed processes and redacts secrets before they reach the terminal
  • Defense-in-depth layer on top of existing kernel-level protections (namespaces, ACLs, iptables) — purely additive, zero impact on existing sandbox behaviour
  • 5 built-in presets covering the most common secret formats, all enabled by default via aigate init

What's included

New: services/masker.go

  • MaskingWriter — line-buffered io.Writer that applies regex rules before forwarding to the real writer
  • Secrets split across write chunks on the same line are still caught (buffered until \n)
  • Flush() handles the last line if it has no trailing newline

Built-in presets

Preset Matches Output
openai sk-... / sk-proj-... sk-***
anthropic sk-ant-... sk-ant-***
aws_key AKIA... AKIA***
github ghp_, gho_, ghu_, ghs_, ghr_ ghp_***
bearer Bearer <token> Bearer ***

Custom pattern options

mask_stdout:
  patterns:
    - regex: "myapp-secret-[a-z0-9]+"
      show_prefix: 0          # fully masked
    - regex: "token-[a-zA-Z0-9]{16}"
      show_prefix: 6          # token-***
    - regex: "(?:password|secret)\\s*[=:]\\s*\\S+"
      show_prefix: 0
      case_insensitive: true  # catches PASSWORD=, Password=, etc.

Default config (aigate init) now ships with all 5 presets + one example pattern for generic key=value assignments (api_key=, secret:, password=, etc.)

Safety

  • When mask_stdout is absent from config, buildOutputWriters returns os.Stdout/os.Stderr — identical to previous behaviour
  • RunPassthrough now delegates to RunPassthroughWith(os.Stdout, os.Stderr, ...) — same result
  • All platform interface changes (RunSandboxed, Executor) are mechanical — all implementations and test mocks updated
  • No new external dependencies
  • go vet + race detector both pass

Test plan

  • go test ./... -count=1 -race passes
  • aigate init generates config with mask_stdout presets + example pattern
  • aigate run -- env with an OpenAI key in env does not print the raw key
  • Existing sandbox restrictions (deny_read, deny_exec, allow_net) unaffected
  • [aigate] mask_stdout: ... line appears in startup banner when configured

Intercepts stdout/stderr from sandboxed processes at the Go layer and
redacts secrets before they reach the terminal — a defense-in-depth
layer on top of existing kernel-level sandbox protections.

- MaskingWriter: line-buffered io.Writer with regex-based redaction
- 5 built-in presets: openai, anthropic, aws_key, github, bearer
- Custom patterns with show_prefix (partial reveal) and case_insensitive options
- All presets + a generic key=value pattern enabled by default in aigate init
- Banner shows active presets/patterns at sandbox startup
- Zero behavioral change when mask_stdout is absent from config
@github-actions
Copy link

github-actions bot commented Mar 10, 2026

StructLint — All checks passed

71 rules validated against .structlint.yaml. No violations found.

View full run · Powered by StructLint

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Core Changes

  • Implemented mask_stdout functionality to redact sensitive information from sandboxed process output (stdout/stderr).
  • Introduced a MaskingWriter service that uses configurable presets and custom regex patterns for redaction.
  • Integrated output masking into the sandbox execution flow and updated configuration management to support mask_stdout.
  • Enhanced CI/CD with PR title validation, AI code review, struct linting, and improved release automation using releaseforge.

Concerns

None. The changes are additive, well-tested, and enhance the security posture of the application without introducing regressions or critical issues.


Verdict

Approve: The changes are well-implemented, thoroughly tested, and significantly improve the security and maintainability of the project. All internal breaking changes to interfaces have been correctly propagated and handled.


Code review performed by GEMINI - gemini-2.5-flash.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Core Changes

  • Implemented mask_stdout feature to redact secrets from sandboxed process output using configurable presets and custom regex patterns.
  • Updated Platform and Executor interfaces to support custom io.Writer for stdout/stderr, allowing the MaskingWriter to intercept and redact output.
  • Enhanced CI/CD workflows with PR title validation, AI code review, struct linting, and updated release automation to use releaseforge for version bumping and release notes.

Concerns

None. The changes are well-implemented, and the new output masking feature adds a valuable defense-in-depth layer without introducing regressions or critical issues.


Verdict

Approve: The changes introduce a significant security enhancement and improve development workflows. All modifications appear correct and robust.


Code review performed by GEMINI - gemini-2.5-flash.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Core Changes

  • Implemented mask_stdout functionality to redact sensitive information from sandboxed process output using configurable presets and custom regex patterns.
  • Updated CI/CD workflows (pr.yml, release.yml, test.yml) to include new linting tools (structlint, golangci-lint) and enforce conventional commit message formats for PR titles and commit messages.
  • Modified the Platform and Executor interfaces to support passing io.Writer for stdout and stderr, allowing the MaskingWriter to intercept and redact output.

Verdict

Approve: The changes introduce a valuable security feature (output masking) and improve code quality through enhanced linting and commit standards. All breaking interface changes are handled internally, and the new functionality is well-tested. The release.yml input change is a functional update with clear intent.


Code review performed by GEMINI - gemini-2.5-flash.

@murilopmachado murilopmachado self-assigned this Mar 11, 2026
@murilopmachado murilopmachado self-requested a review March 11, 2026 00:55
Copy link
Collaborator

@murilopmachado murilopmachado left a comment

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants