[FEATURE] Add in-memory storage option for background task outputs to prevent sensitive data leakage to disk
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Problem Statement
Current Behavior
When a command times out (default 120s) and runs in the background, Claude Code writes the output to disk at:
/private/tmp/claude-501/-Users-{user}-workspace/{session-id}/tasks/{task-id}.output
Example scenario:
# Query runs in background
Bash(command="psql ... -c 'SELECT ssn, salary FROM employees'", timeout=120000)
# Output written to disk:
/private/tmp/claude-501/.../tasks/abc123.output
Contents of disk file:
- Query results with PII/sensitive data
- Credentials in command strings
- Internal system information
- Proprietary business data
Security Concerns
- Data persistence: Files remain on disk after session ends until:
- Manual deletion by user
- System reboot (varies by OS)
- Automatic temp cleanup (unpredictable timing)
- Access risk: On shared systems or compromised machines:
- Other processes can read
/tmp/files - Forensic recovery possible even after deletion
- Malware can scan temp directories
- No user control: Users cannot:
- Opt-in to memory-only storage
- Configure auto-deletion policies
- Know what data was written to disk
- Compliance issues: Organizations with strict data governance (GDPR, HIPAA, SOC2) may:
- Prohibit PII/PHI touching disk unencrypted
- Require audit trails of data writes
- Need immediate secure deletion capabilities
Proposed Solution
Proposed Solutions
Option 1: In-Memory Buffer (Preferred)
For small outputs (<100KB default, configurable):
// settings.json
{
"backgroundTasks": {
"storage": "auto", // "auto" | "memory" | "disk"
"memoryBufferSize": 102400, // bytes
"autoCleanup": true
}
}
Behavior:
- Buffer output in memory for small results
- Fall back to disk only when buffer exceeds limit
- Warn user: "Output exceeded memory buffer, written to disk at: {path}"
Benefits:
- Zero disk footprint for most queries
- No performance impact for typical use
- Backwards compatible (auto mode uses disk when needed)
Alternative Solutions
Option 2: Secure Temp File Handling
If disk storage is required:
- Immediate encryption:
``bash``
# Encrypt on write
openssl enc -aes-256-cbc -salt -in output.txt -out output.enc
- Secure deletion:
``bash``
# Overwrite before delete (prevents forensic recovery)
shred -vfz -n 3 /tmp/claude-501/tasks/abc123.output
- Auto-cleanup on read:
``typescript``
// After tool reads the output
readTaskOutput(taskId).then(output => {
if (settings.autoCleanup) {
secureDelete(taskOutputPath);
}
return output;
});
---
Option 3: User-Configured Storage Location
Allow users to specify secure storage:
// settings.json
{
"backgroundTasks": {
"outputDirectory": "/Volumes/RAMDisk/claude-tasks", // RAM disk
"useEncryptedVolume": true,
"cleanupPolicy": "immediate" | "session-end" | "manual"
}
}
Benefits:
- Users can mount encrypted volumes
- Users can use RAM disks (tmpfs, memory-backed mounts)
- Enterprise users can point to secure company-managed storage
Priority
Critical - Blocking my work
Feature Category
Other
Use Case Example
Detailed Use Cases
Use Case 1: Financial Data Analysis
User: Data analyst at a bank
Command: Query customer transaction data from Redshift
Issue: Transaction data with account numbers written to /tmp/
Requirement: GDPR Article 32 - data must be encrypted at rest
Desired outcome:
# Query runs, output stays in memory
# User sees results, no disk trace
# Audit log: "Query output: 45KB, stored in memory, auto-purged"
---
Use Case 2: Penetration Testing
User: Security consultant
Command: Run vulnerability scans with API keys in output
Issue: API keys, passwords, exploit details written to disk
Requirement: Client contract requires no sensitive data on tester machines
Desired outcome:
// User sets memory-only mode
{
"backgroundTasks": {
"storage": "memory",
"memoryBufferSize": 1048576, // 1MB
"fallbackToDisk": false // Fail if exceeds buffer
}
}
---
Use Case 3: Healthcare Data Research
User: Medical researcher querying patient data
Command: Aggregate patient outcomes from clinical database
Issue: PHI (Protected Health Information) written to unencrypted temp files
Requirement: HIPAA § 164.312(a)(2)(iv) - encryption required for data at rest
Desired outcome:
# Automatic encryption on write
# Secure deletion after read
# Audit log with cryptographic proof of deletion
Additional Context
Implementation Suggestions
1. Add Memory Buffer to Task Runner
interface BackgroundTask {
id: string;
command: string;
stdout: Buffer; // In-memory buffer
stderr: Buffer;
outputFile?: string; // Only set if exceeds memory limit
storageMode: 'memory' | 'disk';
}
class TaskRunner {
private memoryBufferLimit: number = 102400; // 100KB default
async runTask(command: string): Promise<BackgroundTask> {
const process = spawn(command);
const stdout: Buffer[] = [];
let bytesBuffered = 0;
process.stdout.on('data', (chunk: Buffer) => {
bytesBuffered += chunk.length;
if (bytesBuffered < this.memoryBufferLimit) {
stdout.push(chunk);
} else {
// Fall back to disk
this.spillToDisk(task.id, stdout, chunk);
}
});
}
}
---
2. Add Settings Schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"backgroundTasks": {
"type": "object",
"properties": {
"storage": {
"type": "string",
"enum": ["auto", "memory", "disk"],
"default": "auto",
"description": "Storage strategy for background task outputs"
},
"memoryBufferSize": {
"type": "integer",
"minimum": 1024,
"maximum": 10485760,
"default": 102400,
"description": "Max bytes to buffer in memory before spilling to disk"
},
"autoCleanup": {
"type": "boolean",
"default": true,
"description": "Automatically delete task output files after reading"
},
"secureDelete": {
"type": "boolean",
"default": false,
"description": "Use secure deletion (overwrite before delete) for sensitive data"
},
"outputDirectory": {
"type": "string",
"description": "Custom directory for task output files (default: /tmp/claude-{pid})"
}
}
}
}
}
---
3. Add User Notifications
// When falling back to disk
warningMessage({
message: "Background task output exceeded memory buffer (100KB). Written to disk at:",
path: taskOutputPath,
suggestion: "Increase memoryBufferSize in settings or use LIMIT clause in queries."
});
// When using insecure storage
if (settings.storage === 'disk' && !settings.secureDelete) {
oneTimeWarning({
id: "insecure-task-storage",
message: "Background task outputs are written to disk unencrypted. Consider enabling 'secureDelete' for sensitive data.",
documentation: "https://docs.anthropic.com/claude-code/security/background-tasks"
});
}
---
Backwards Compatibility
Migration Path
Phase 1 (v1.x):
- Default behavior unchanged (disk storage)
- Add opt-in memory storage:
"storage": "memory" - Add warning when sensitive patterns detected in output
Phase 2 (v2.0):
- Change default to
"storage": "auto"(memory-first) - Keep disk as fallback
- Add telemetry to track buffer size usage
Phase 3 (v3.0):
- Consider memory-only as default for small outputs
- Require explicit opt-in for disk storage
---
Security Considerations
What to Detect as "Sensitive"
Heuristics to trigger warnings or force memory-only storage:
const SENSITIVE_PATTERNS = [
/\b\d{3}-\d{2}-\d{4}\b/, // SSN
/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i, // Email
/\b4[0-9]{12}(?:[0-9]{3})?\b/, // Credit card (Visa)
/(?i)\b(password|secret|key|token|api[_-]?key)\b/, // Credentials
/-----BEGIN (RSA|DSA|EC) PRIVATE KEY-----/, // Private keys
];
function containsSensitiveData(output: string): boolean {
return SENSITIVE_PATTERNS.some(pattern => pattern.test(output));
}
Auto-promote to secure storage:
if (containsSensitiveData(output) && settings.storage === 'disk') {
console.warn('⚠️ Sensitive data detected. Forcing memory-only storage.');
task.storageMode = 'memory';
}
---
Testing Checklist
- [ ] Memory buffer handles outputs from 0 bytes to buffer limit
- [ ] Graceful fallback to disk when buffer exceeded
- [ ] Secure deletion actually overwrites data (verify with hex editor)
- [ ] Settings validation rejects invalid configurations
- [ ] Warning shown when sensitive data detected
- [ ] RAM disk paths work correctly on macOS/Linux/Windows
- [ ] Encrypted volumes can be mounted and used
- [ ] Auto-cleanup runs on session end
- [ ] Manual cleanup available via command/API
- [ ] No memory leaks with large buffered outputs
- [ ] Concurrent background tasks don't interfere
- [ ] Task notifications include storage mode information
---
Performance Impact
Benchmark Results (Expected)
| Scenario | Current (Disk) | Proposed (Memory) | Change |
|---|---|---|---|
| 10KB query output | 50ms | 5ms | 10x faster |
| 100KB query output | 150ms | 15ms | 10x faster |
| 1MB query output | 800ms | 850ms (spill to disk) | ~Same |
| 10MB query output | 5s | 5s (disk from start) | Same |
Memory overhead:
- Typical query: 10-50KB buffered = negligible
- Large query: Falls back to disk = no impact
- Max memory footprint:
memoryBufferSize × concurrent_tasks
Example: 10 concurrent tasks × 100KB buffer = 1MB RAM (acceptable)
---
Alternative Considered: Streaming to Claude
Idea: Stream output directly to Claude's context instead of storing locally
Pros:
- Zero local storage
- Immediate availability
Cons:
- Network latency for every chunk
- API rate limits may throttle large outputs
- Context window bloat (2MB query result = wasted tokens)
- Fails if network drops mid-stream
Verdict: Not viable for large outputs or unreliable networks
---
Documentation Requirements
If this feature is implemented, documentation should cover:
- Security Guide:
- How to enable memory-only storage
- How to configure RAM disks
- How to use encrypted volumes
- Compliance considerations (GDPR, HIPAA, SOC2)
- Settings Reference:
- All new
backgroundTaskssettings - Default values and ranges
- Performance implications
- Migration Guide:
- How to upgrade from disk-only storage
- How to verify no data is written to disk
- How to audit existing temp files
- Troubleshooting:
- What to do when memory buffer is too small
- How to diagnose disk spillover
- How to recover from failed secure deletion
---
References
Related Security Best Practices
- OWASP: Sensitive Data Exposure (A02:2021)
- NIST SP 800-88: Guidelines for Media Sanitization
- CIS Benchmark: Secure Temporary File Handling
Similar Implementations
- Docker:
--tmpfsmounts for container temp storage - systemd:
PrivateTmp=truefor service isolation - PostgreSQL:
work_memfor in-memory query execution - Redis: In-memory data store with optional persistence
Claude Code Context
- Current temp file implementation:
src/tools/bash.ts(assumed) - Task runner:
src/task-runner.ts(assumed) - Settings schema:
.claude/settings.schema.json
---
Conclusion
Summary:
This feature request addresses a real security gap where sensitive data from background tasks is written to disk unencrypted and persists beyond session lifetime. The proposed memory-first approach is backwards compatible, performant, and provides users with control over sensitive data handling.
Impact:
- Users: Better privacy and security for sensitive workflows
- Enterprise: Enables compliance with data governance policies
- Security researchers: No credential leakage to disk
- Healthcare/Finance: HIPAA/PCI-DSS compliant data handling
Effort: Medium (estimated 2-4 weeks for core implementation)
Priority Justification:
While not a critical vulnerability (requires local disk access), this is a meaningful security improvement for users handling sensitive data. The opt-in nature allows incremental rollout without breaking existing workflows.
---
Contact
Reporter: narayana-k
Date: 2026-07-30
Willing to contribute: Yes
Available for testing: Yes
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗