opencode icon indicating copy to clipboard operation
opencode copied to clipboard

[FEATURE]: export should have some level of obfuscation applied automatically

Open sheldonhull opened this issue 3 weeks ago • 1 comments

Feature hasn't been suggested before.

  • [x] I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

  • I was trying to provide an export of my session, and it took nearly an hour for me to go through the json content and custom scripts to search and obfuscate for every sensitive or private piece of info.
  • env output was raw captured with tokens.
  • I get that secrets are going to be involved with env, but hoping that the default behavior would opt to redact/obfuscate sensitive string values.

I'd like to think the default of export would be to obfuscate tokens/pats, etc. I applied some scripting to better catch other options as well with gitleaks for high entropy strings high entropy strings at the minimum..

After I did a bunch of redaction I ran this and found false errors due to the session ids, but otherwise confirmed all my main concerns had been resolved

I ran this to help do a very aggressive fuzzy matching and just redact content.

I read claudes docs on secrets and I think I will work on some personal sdk tools based on your docs for example on blocking certain commands and see if I can improve my experience. However, some sessions will have to have secrets and while my prompt guidance says to never expose and only output "set" and "not set", a lower level protection in the agent would be great to protect export specifically and maybe filter through to improving the default logging.


cd myrepo && uv run python -c "
import re
import json

# Read raw file with line tracking
with open('session-with-error.json', 'r', encoding='utf-8', errors='replace') as f:
    lines = f.readlines()
    content = ''.join(lines)

# Sensitive keywords to match (case insensitive)
sensitive_patterns = [
    'PAT',
    'TOKEN',
    'ACCESS_KEY',
    'API_KEY',
    'SECRET',
    'CREDENTIAL',
    'PASSWORD',
    'AUTH',
    'KEY',
    'OPENAI'
]

pattern = '|'.join(sensitive_patterns)

# Track what gets redacted
redacted_log = []

# Find all quoted strings and check if they contain sensitive keywords
def redact_sensitive_strings(match):
    string_content = match.group(1)
    if re.search(pattern, string_content, re.IGNORECASE):
        # Find which keyword matched
        matched_keyword = None
        for keyword in sensitive_patterns:
            if re.search(keyword, string_content, re.IGNORECASE):
                matched_keyword = keyword
                break

        # Find line number
        pos = match.start()
        line_num = content[:pos].count('\n') + 1

        redacted_log.append({
            'line_number': line_num,
            'matched_keyword': matched_keyword,
            'original_value': string_content,
            'original_length': len(string_content),
            'replaced_value': '{REDACTED_CONTAINED_SENSITIVE_DATA}',
            'full_match': match.group(0)
        })
        return '\"' + '{REDACTED_CONTAINED_SENSITIVE_DATA}' + '\"'
    return match.group(0)

# Replace strings containing sensitive keywords
content = re.sub(r'\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"', redact_sensitive_strings, content)

# Write detailed redaction log
with open('redaction_log.json', 'w') as f:
    json.dump({
        'total_redacted': len(redacted_log),
        'redacted_items': redacted_log
    }, f, indent=2)

# Write redacted file
with open('session-with-error.json', 'w', encoding='utf-8') as f:
    f.write(content)

print(f'✅ Redaction complete')
print(f'📝 Redacted {len(redacted_log)} sensitive strings')
print(f'📋 Check redaction_log.json for full details')
"
cd myrepo && uv run --with detect-secrets python << 'EOF'
import subprocess
import json

result = subprocess.run(
    ['detect-secrets', 'scan', 'session-with-error.json', '--all-files'],
    capture_output=True,
    text=True
)

data = json.loads(result.stdout)

# Read original file for context
with open('session-with-error.json', 'r') as f:
    lines = f.readlines()

print("=== DETECT-SECRETS FINDINGS WITH CONTEXT ===\n")
for file, findings in data.get('results', {}).items():
    for finding in findings:
        line_num = finding.get('line_number', 0)
        if line_num > 0 and line_num <= len(lines):
            print(f"Line {line_num}: {lines[line_num-1].strip()[:150]}")
            print(f"  Type: {finding.get('type')}")
            print()
EOF

sheldonhull avatar Dec 30 '25 19:12 sheldonhull

This issue might be a duplicate of existing issues. Please check:

  • #3056: pii/secrets censor — censoring PII data and sensitive values with regex patterns
  • #4961: Feature Request: Zero-Trust Architecture for Environment Variable Security — comprehensive secret protection with placeholder replacement before LLM transmission
  • #5091: Session Tainting — A Directional Safety Pattern for Agentic Work — directional safety including read/write boundary controls to prevent data exfiltration

Feel free to ignore if none of these address your specific case.

github-actions[bot] avatar Dec 30 '25 19:12 github-actions[bot]