Skip to content

[BUG] OPENSRE_MASK_ENABLED=true # Comma-separated kinds to mask. Empty = project defaults. OPENSRE_MASK_KINDS="pod,namespace,cluster,service_name,hostname,account_id,ip_address,email" # Example: '{"jira_key": "\\b[A-Z]+-\\d+\\b"}' #6714

Description

@saadz2

Summary

Identifier masking is enabled in my environment, but sensitive identifiers
remain visible in the prompt OpenSRE sends to GitHub Copilot CLI.

Expected vs actual behavior

Actual Behavior

The outgoing prompt contains the original identifiers instead of masking
placeholders.

An offline check of CLIBackedLLMClient._prepare_invocation() confirmed:

  • MaskingPolicy.enabled is True.
  • MaskingRules.mask() changes the dummy input.
  • The prepared Copilot stdin still contains the original dummy IP and email.

No LLM request was made during that offline check.

Expected Behavior

When masking is enabled, supported identifiers in user messages, tool results,
and other outgoing context should be replaced before being sent to Copilot.

Returned tool arguments should be unmasked locally before tool execution so
queries still use real identifiers.

Steps to reproduce

  1. Configure Copilot CLI authentication and LLM_PROVIDER=copilot.

  2. Enable masking with the settings above.

  3. Run a request containing dummy identifiers:
    opensre ask "Investigate pod privacy-test-7b5b4cbd55-abcde in namespace privacy-test. Example IP: 192.0.2.42. Contact: privacy-check@example.invalid"

  4. Inspect the corresponding Copilot session's events.jsonl.

  5. Examine data.content in the user.message event.

Can you reproduce it consistently?

Yes

How often does it occur?

Every time

Operating system

Windows

Logs and error output

No response

Additional context

Suspected Cause

integrations/llm_cli/runner.py::_prepare_invocation() calls
apply_guardrails_to_text(), but does not invoke the identifier masker.

Masking, guardrail redaction, and prompt-log redaction are separate controls;
enabling log redaction does not protect the outgoing LLM prompt.

Impact

Users may believe identifiers are masked based on configuration while those
identifiers are still included in externally processed prompts.

Suggested Regression Coverage

  • Enabled masking removes dummy identifiers from outgoing stdin.
  • Disabled masking preserves existing behavior.
  • Returned tool arguments are restored locally.
  • Tool-result context is masked on subsequent calls.
  • Placeholder mappings remain consistent without crossing session boundaries.

Activity

  1. 2025sl93041-gkb commented on Oct 14, 2026

    @2025sl93041-gkb

    Hi — I've opened a PR that fixes this issue: #6729

    Root cause: _prepare_invocation() in integrations/llm_cli/runner.py called apply_guardrails_to_text() but skipped MaskingPolicy/MaskingRules entirely, so OPENSRE_MASK_ENABLED=true had no effect.

    Fix: reads MaskingPolicy.from_env() after guardrails, masks outgoing prompt, stores MaskingRules on _PreparedInvocation, unmaskes response in invoke() and buffers+unmaskes in invoke_stream(). All 7 tests pass including a new regression test.

    I'm a postgraduate student with a semester deadline of November 2025 — would really appreciate a review!

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions