Skip to content

Security

Temp edited this page Jan 12, 2026 · 16 revisions

Security

Security features and best practices for Memory Journal MCP Server.

Local-First Design: Your project context stays on your machine. No external API calls, no cloud dependencies - your development history remains private.


Security Model

Memory Journal is local-first:

  • All data stored locally in SQLite
  • No external API calls
  • No telemetry or analytics
  • You own and control your data

Input Validation

Content Size Limits

const MAX_CONTENT_SIZE = 50 * 1024;  // 50KB per entry
const MAX_TAG_LENGTH = 100;          // 100 characters per tag

Why limits:

  • Prevent resource exhaustion
  • Ensure reasonable performance
  • Protect database integrity

SQL Injection Prevention

All queries use parameterized statements:

// Safe - parameterized query
db.run(
  'INSERT INTO memory_journal (content) VALUES (?)',
  [userContent]
);

// NEVER do this (vulnerable to SQL injection)
db.run(`INSERT INTO memory_journal (content) VALUES ('${userContent}')`);  // DON'T!

Benefits:

  • SQL injection impossible
  • Safe handling of quotes and special characters
  • Database-level validation

Docker Security

Non-Root Execution

# Create non-root user
RUN addgroup -g 1000 appuser && \
    adduser -D -u 1000 -G appuser appuser

# Switch to non-root user
USER appuser

Benefits:

  • Container cannot modify host system
  • Reduced attack surface
  • Follows least privilege principle

Minimal Base Image

FROM node:24-alpine

Alpine Linux benefits:**

  • Small attack surface (~5MB base)
  • Security-focused distribution
  • Fewer vulnerabilities
  • Fast updates

No Privileged Access

{
  "command": "docker",
  "args": [
    "run", "--rm", "-i",
    // NO --privileged flag
    // NO --cap-add flags
    "-v", "./data:/app/data",
    "writenotenow/memory-journal-mcp:latest"
  ]
}

Volume Mount Security

{
  "args": [
    "-v", "./data:/app/data:rw",  // Only data directory
    // NOT: "-v", "/:/host" - would expose entire host
  ]
}

Best practices:

  • Mount only necessary directories
  • Use read-only mounts where possible
  • Avoid mounting sensitive host directories

Supply Chain Security

SHA-Pinned Images

Recommended (highest security):

# Use SHA-256 digest for immutable reference
docker pull writenotenow/memory-journal-mcp@sha256:abc123...

# Find SHA digests at:
# https://hub.docker.com/r/writenotenow/memory-journal-mcp/tags

Benefits:

  • Immutable image reference
  • Protection against tag hijacking
  • Reproducible deployments
  • Supply chain verification

Tag-based (convenience):

docker pull writenotenow/memory-journal-mcp:latest

Database Security

WAL Mode Safety

PRAGMA journal_mode = WAL;      -- Write-Ahead Logging
PRAGMA synchronous = NORMAL;    -- Balance safety/speed

Benefits:

  • Crash recovery
  • Data integrity
  • Concurrent access safety

Foreign Key Constraints

FOREIGN KEY (entry_id) REFERENCES memory_journal(id) ON DELETE CASCADE

Benefits:

  • Referential integrity
  • Automatic cleanup
  • Prevents orphaned records

Transaction Safety

db.run('BEGIN TRANSACTION');
try {
  db.run('INSERT ...');
  db.run('UPDATE ...');
  db.run('COMMIT');
} catch (error) {
  db.run('ROLLBACK');
  throw error;
}

Benefits:

  • ACID compliance
  • Data consistency
  • Error recovery

Data Privacy

Local-Only Storage

No network access:

  • No cloud storage
  • No API calls (except Git/GitHub CLI)
  • No user tracking
  • No analytics

Data location:

  • npm: ~/.memory-journal/memory_journal.db
  • Docker: ./data/memory_journal.db (volume mount)

Git/GitHub Integration

Optional and transparent:

create_entry({
  content: "...",
  auto_context: false  // Disable Git integration
})

Git operations:

  • Read-only (no commits)
  • Local repository info only
  • Optional GitHub CLI (user-controlled)

Data captured:

  • Repository name and path
  • Current branch
  • Latest commit
  • GitHub issues (if gh CLI installed)

Not captured:

  • File contents
  • Uncommitted changes
  • Remote repository data
  • Credentials

Soft Delete Security

Recoverable Deletes

// Soft delete (default)
delete_entry({ entry_id: 42, permanent: false })
// Sets deleted_at timestamp, entry remains in DB

// Permanent delete (explicit)
delete_entry({ entry_id: 42, permanent: true })
// Removes from database completely

Benefits:

  • Accidental deletion recovery
  • Audit trail
  • No data loss

Soft-deleted entries:

  • Excluded from searches
  • Not visible in lists
  • Still in database (for recovery)

Access Control

MCP Client Authentication

Security handled by MCP client:

  • Cursor IDE: Desktop app security
  • Claude Desktop: Desktop app security
  • User controls which servers run

File System Permissions

npm installation:

# Database created with user permissions
chmod 600 ~/.memory-journal/memory_journal.db

Docker installation:

# Volume mount with appropriate permissions
mkdir -m 755 data

Secure Configuration

Environment Variables

Docker environment variables:

{
  "args": [
    "-e", "DB_PATH=/app/data/custom.db",
    // NO sensitive data in env vars
    // NO API keys
    // NO credentials
  ]
}

Secrets Management

No secrets required:

  • No API keys
  • No passwords
  • No tokens
  • Optional: GitHub CLI (user manages gh auth)

Security Best Practices

For Users

1. Regular backups:

# Backup database
cp ./data/memory_journal.db ./backups/journal-$(date +%Y%m%d).db

2. Docker image verification:

# Verify SHA digest
docker images --digests | grep memory-journal

# Use SHA-pinned images
docker pull writenotenow/memory-journal-mcp@sha256:...

3. Limit Docker access:

{
  "args": [
    "-v", "./data:/app/data",  // Only mount data dir
    "--read-only",              // Read-only root filesystem
    "--tmpfs", "/tmp"           // Writable tmp
  ]
}

4. Review logs:

# Check for errors
docker logs <container_id>

For Developers

1. Input validation:

if (content.length > MAX_CONTENT_SIZE) {
  throw new Error(`Content too large: ${content.length} > ${MAX_CONTENT_SIZE}`);
}

2. Parameterized queries:

// Always use ? placeholders
db.run('SELECT * FROM memory_journal WHERE id = ?', [entryId]);

3. Error handling:

try {
  // Operation
} catch (error) {
  // Log, don't expose internals to user
  logger.error('Internal error', { error });
  return { error: 'Operation failed' };
}

4. Least privilege:

// Don't request unnecessary permissions
// Don't access unnecessary files
// Don't make unnecessary network calls

Vulnerability Reporting

Found a security issue?

  1. Do NOT open a public GitHub issue
  2. Email: security@example.com (use your actual security contact)
  3. Include:
    • Description of vulnerability
    • Steps to reproduce
    • Potential impact
    • Suggested fix (if any)

We will:

  • Acknowledge within 48 hours
  • Provide fix timeline
  • Credit you (if desired)
  • Publish security advisory

Security Audit

Self-Audit Checklist

  • ✅ Input validation (size limits)
  • ✅ SQL injection prevention (parameterized queries)
  • ✅ No credentials in code
  • ✅ Non-root Docker execution
  • ✅ Minimal base image (Alpine)
  • ✅ No unnecessary privileges
  • ✅ Local-only data storage
  • ✅ Transaction safety (ACID)
  • ✅ Error handling
  • ✅ Soft delete option

Threat Model

In Scope

Protected against:

  • SQL injection
  • Resource exhaustion (size limits)
  • Accidental data loss (soft delete)
  • Database corruption (WAL, transactions)
  • Container escape (non-root, no privileges)

Out of Scope

Not protected against:

  • Malicious MCP client
  • Compromised host system
  • Physical access to database file
  • User deleting database file

Why:

  • Local-first design trusts the host
  • User has full control
  • Desktop application security model

Compliance

Data Protection

GDPR-friendly:

  • No data collection
  • No data transmission
  • Local storage only
  • User controls all data
  • Easy data export/deletion

No PII collection:

  • No names
  • No email addresses
  • No tracking
  • No analytics

Security Updates

Staying Secure

npm:

# Update to latest version
npm install -g memory-journal-mcp@latest

Docker:

# Pull latest image
docker pull writenotenow/memory-journal-mcp:latest

# Or specific SHA
docker pull writenotenow/memory-journal-mcp@sha256:...

Monitor:

  • GitHub releases
  • Docker Hub updates
  • Security advisories

Next: Check Architecture or Performance.

Clone this wiki locally