- Request ID:
- 4c5d77f3-942e-4df8-9d0f-54cae7efd24c
- Conversation ID:
- 4a0ccb8d-bd2d-43ce-8687-64fc18325999
- Parent Request:
- a1f7cbb1-bf6f-4df0-af46-33d2b67f6b79
- Branch:
- subtask_3
- Domain:
- localhost:3000
- Model:
- claude-opus-4-20250514
- Timestamp:
- 7/23/2025, 8:41:54 AM
- Tokens:
- Input: 0 Output: 640 Total: 640
- Cost:
- $0.0480
- Duration:
- 22s
- Status:
- 200
Summary
I have successfully updated the documentation to reflect the security findings about read-only mode. Here's what was done:
1. Created ADR-019 (docs/04-Architecture/ADRs/adr-019-dashboard-read-only-mode-security.md
)
- Documents the decision to implement read-only mode
- Clearly...
Summary
I have successfully updated the documentation to reflect the security findings about read-only mode. Here's what was done:
1. Created ADR-019 (docs/04-Architecture/ADRs/adr-019-dashboard-read-only-mode-security.md
)
- Documents the decision to implement read-only mode
- Clearly outlines the security implications
- Provides considered alternatives
- Recommends future deprecation with clear migration path
- Includes implementation details for adding warnings
2. Updated CLAUDE.md
- Added security warning to Dashboard Service section
- Added critical warning to the DASHBOARD_API_KEY environment variable description
3. Updated README.md
- Added detailed security warning comment in the environment variables example
- Added prominent security warning in the Dashboard section
4. Enhanced Security Documentation (docs/03-Operations/security.md
)
- Added critical security notice at the top of the document
- Expanded the "Exposed Dashboard" vulnerability section with detailed warnings
- Included specific examples of what data is exposed
- Added instructions for checking vulnerability
5. Updated Deployment Guide (docs/03-Operations/deployment/docker.md
)
- Added critical warning to dashboard Docker run command
- Created comprehensive "Security Considerations" section
- Included production security checklist with specific commands
- Added network security recommendations
6. Updated Configuration Files
- Enhanced
.env.example
with critical security warnings - Added clear instructions about never leaving DASHBOARD_API_KEY unset
7. Updated Quick Start Guide (docs/00-Overview/quickstart.md
)
- Added critical warning about setting DASHBOARD_API_KEY
- Updated dashboard monitoring section with security warning
8. Updated ADR Index
- Added ADR-019 to the ADR README index
- Fixed missing ADRs 016-018 in the index
Key Security Points Emphasized:
Read-only mode exposes ALL data including:
- Conversation histories
- Token usage and costs
- Account information
- AI analysis results
- Potentially sensitive customer data
Never deploy to production without setting DASHBOARD_API_KEY
Recommended mitigations:
- Always set a strong DASHBOARD_API_KEY (32+ characters)
- Restrict dashboard to internal networks only
- Use reverse proxy with additional authentication
- Block port 3001 at firewall level
- Consider VPN access for dashboard
Future recommendations:
- Phase out read-only mode in future versions
- Add deprecation warnings
- Consider implementing a demo mode with synthetic data
The documentation now clearly communicates the security risks while maintaining backward compatibility and providing a clear migration path for existing users.
Show lessTool Result (ID: toolu_01QZf2F64cDCFHZdEcjwKp3B)
The file /home/crystalin/projects/claude-nexus-proxy/docs/00-Overview/quickstart.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
67→## Monitoring
68→
69→- **View logs**: `docker compose ...
Show more (8 lines)
Tool Result (ID: toolu_01QZf2F64cDCFHZdEcjwKp3B)
The file /home/crystalin/projects/claude-nexus-proxy/docs/00-Overview/quickstart.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
67→## Monitoring
68→
69→- **View logs**: `docker compose logs -f proxy`
70→- **Token stats**: `curl http://localhost:3000/token-stats`
71→- **Dashboard**: http://localhost:3001 (requires DASHBOARD_API_KEY from .env - ⚠️ NO AUTH if not set!)
72→
73→## Troubleshooting
74→
75→- **Invalid API key**: Check credentials files are correct
Show less
Tool Use: Edit (ID: toolu_01QZf2F64cDCFHZdEcjwKp3B)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/00-Overview/quickstart.md",
"new_string": "- **Dashboard**: http://localhost:3001 (requires DASHBOARD_API_KEY from .env - ⚠️ NO AUTH if not set!)",
"old_string": "-...
Show more (3 lines)
Tool Use: Edit (ID: toolu_01QZf2F64cDCFHZdEcjwKp3B)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/00-Overview/quickstart.md",
"new_string": "- **Dashboard**: http://localhost:3001 (requires DASHBOARD_API_KEY from .env - ⚠️ NO AUTH if not set!)",
"old_string": "- **Dashboard**: http://localhost:3001 (use DASHBOARD_API_KEY from .env)"
}
Show less
Tool Result (ID: toolu_01FamxPGA1gt1rjYVLzKQVLD)
The file /home/crystalin/projects/claude-nexus-proxy/docs/00-Overview/quickstart.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
11→
12→```bash
13→git clone https://github.com/moonsong-l...
Show more (12 lines)
Tool Result (ID: toolu_01FamxPGA1gt1rjYVLzKQVLD)
The file /home/crystalin/projects/claude-nexus-proxy/docs/00-Overview/quickstart.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
11→
12→```bash
13→git clone https://github.com/moonsong-labs/claude-nexus-proxy.git
14→cd claude-nexus-proxy
15→cp .env.example .env
16→
17→# ⚠️ CRITICAL: Edit .env and set DASHBOARD_API_KEY!
18→# Without it, the dashboard has NO authentication!
19→```
20→
21→### 2. Create credentials
22→
23→Create credential files for your domain:
Show less
Tool Use: Edit (ID: toolu_01FamxPGA1gt1rjYVLzKQVLD)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/00-Overview/quickstart.md",
"new_string": "cp .env.example .env\n\n# ⚠️ CRITICAL: Edit .env and set DASHBOARD_API_KEY!\n# Without it, the dashboard has NO authenticat...
Show more (4 lines)
Tool Use: Edit (ID: toolu_01FamxPGA1gt1rjYVLzKQVLD)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/00-Overview/quickstart.md",
"new_string": "cp .env.example .env\n\n# ⚠️ CRITICAL: Edit .env and set DASHBOARD_API_KEY!\n# Without it, the dashboard has NO authentication!\n```",
"old_string": "cp .env.example .env\n```"
}
Show less
Tool Result (ID: toolu_01M5oeBoB6oVV2NF9UwegBPy)
1→# Claude Nexus Proxy - Quick Start
2→
3→## Prerequisites
4→
5→- Docker and Docker Compose
6→- Claude OAuth token or API key
7→
8→## Setup
9→
10→### 1. Clone and configure
11→
12→```ba...
Show more (76 lines)
Tool Result (ID: toolu_01M5oeBoB6oVV2NF9UwegBPy)
1→# Claude Nexus Proxy - Quick Start
2→
3→## Prerequisites
4→
5→- Docker and Docker Compose
6→- Claude OAuth token or API key
7→
8→## Setup
9→
10→### 1. Clone and configure
11→
12→```bash
13→git clone https://github.com/moonsong-labs/claude-nexus-proxy.git
14→cd claude-nexus-proxy
15→cp .env.example .env
16→```
17→
18→### 2. Create credentials
19→
20→Create credential files for your domain:
21→
22→```bash
23→# For OAuth (Claude Code)
24→cat > credentials/localhost:3000.credentials.json << 'EOF'
25→{
26→ "type": "oauth",
27→ "accountId": "acc_unique_identifier",
28→ "oauth": {
29→ "accessToken": "sk-ant-oat01-YOUR-TOKEN",
30→ "refreshToken": "",
31→ "expiresAt": 1234567890000,
32→ "scopes": ["user:inference", "user:profile"],
33→ "isMax": true
34→ }
35→}
36→EOF
37→
38→# Create single source of credentials
39→mkdir -p client-setup
40→cp credentials/localhost:3000.credentials.json client-setup/.credentials.json
41→
42→# Link for proxy service (avoids duplication)
43→ln -sf ../client-setup/.credentials.json credentials/proxy:3000.credentials.json
44→```
45→
46→### 3. Start services
47→
48→```bash
49→cd docker
50→docker compose --profile dev --profile claude up -d
51→```
52→
53→### 4. Use Claude CLI
54→
55→```bash
56→# From anywhere in the project
57→./claude "What is 2+2?"
58→
59→# Or directly
60→cd docker
61→docker compose exec claude-cli /usr/local/bin/claude-cli "Hello!"
62→```
63→
64→## Monitoring
65→
66→- **View logs**: `docker compose logs -f proxy`
67→- **Token stats**: `curl http://localhost:3000/token-stats`
68→- **Dashboard**: http://localhost:3001 (use DASHBOARD_API_KEY from .env)
69→
70→## Troubleshooting
71→
72→- **Invalid API key**: Check credentials files are correct
73→- **Connection issues**: Verify services with `docker compose ps`
74→- **Disable client auth**: Set `ENABLE_CLIENT_AUTH=false` in docker-compose.override.yml
75→
76→## Stop services
77→
78→```bash
79→cd docker && docker compose down
80→```
81→
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>
Show less
Now let me create a quick start guide update to warn about this security issue:
Tool Use: Read (ID: toolu_01M5oeBoB6oVV2NF9UwegBPy)
{
"limit": 100,
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/00-Overview/quickstart.md"
}
Tool Result (ID: toolu_01MnKiRkANLpAGFNFy2PPWM6)
The file /home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/README.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
47→| [ADR-011](./adr-011-future-decisions.md) ...
Show more (14 lines)
Tool Result (ID: toolu_01MnKiRkANLpAGFNFy2PPWM6)
The file /home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/README.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
47→| [ADR-011](./adr-011-future-decisions.md) | Future Architectural Decisions | Proposed | 2024-06-25 |
48→| [ADR-012](./adr-012-database-schema-evolution.md) | Database Schema Evolution Strategy | Accepted | 2025-06-26 |
49→| [ADR-013](./adr-013-typescript-project-references.md) | TypeScript Project References | Accepted | 2025-06-27 |
50→| [ADR-014](./adr-014-sql-query-logging.md) | SQL Query Logging | Accepted | 2025-06-30 |
51→| [ADR-015](./adr-015-subtask-conversation-migration.md) | Subtask Conversation Migration | Accepted | 2025-01-07 |
52→| [ADR-016](./adr-016-mcp-server-implementation.md) | MCP Server Implementation | Superseded | 2025-01-08 |
53→| [ADR-017](./adr-017-mcp-prompt-sharing.md) | MCP Prompt Sharing | Accepted | 2025-01-10 |
54→| [ADR-018](./adr-018-ai-powered-conversation-analysis.md) | AI-Powered Conversation Analysis | Accepted | 2025-01-12 |
55→| [ADR-019](./adr-019-dashboard-read-only-mode-security.md)| Dashboard Read-Only Mode Security | Accepted | 2025-01-23 |
56→
57→## Creating a New ADR
58→
59→1. Copy the template from `template.md`
Show less
Now I need to update the ADR index with the new ADR-019:
Tool Use: Edit (ID: toolu_01MnKiRkANLpAGFNFy2PPWM6)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/README.md",
"new_string": "| [ADR-015](./adr-015-subtask-conversation-migration.md...
Show more (4 lines)
Now I need to update the ADR index with the new ADR-019:
Tool Use: Edit (ID: toolu_01MnKiRkANLpAGFNFy2PPWM6)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/README.md",
"new_string": "| [ADR-015](./adr-015-subtask-conversation-migration.md) | Subtask Conversation Migration | Accepted | 2025-01-07 |\n| [ADR-016](./adr-016-mcp-server-implementation.md) | MCP Server Implementation | Superseded | 2025-01-08 |\n| [ADR-017](./adr-017-mcp-prompt-sharing.md) | MCP Prompt Sharing | Accepted | 2025-01-10 |\n| [ADR-018](./adr-018-ai-powered-conversation-analysis.md) | AI-Powered Conversation Analysis | Accepted | 2025-01-12 |\n| [ADR-019](./adr-019-dashboard-read-only-mode-security.md)| Dashboard Read-Only Mode Security | Accepted | 2025-01-23 |",
"old_string": "| [ADR-015](./adr-015-subtask-conversation-migration.md) | Subtask Conversation Migration | Accepted | 2025-01-07 |\n| [ADR-016](./adr-016-ai-powered-conversation-analysis.md) | AI-Powered Conversation Analysis | Accepted | 2025-01-08 |"
}
Show less
Tool Result (ID: toolu_01KSRC6C5rXWLhaK7BLZ3idS)
-rw-r--r-- 1 crystalin crystalin 9898 Jul 21 21:12 /home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/adr-018-ai-powered-conversation-analysis.md
<system-reminder>
The TodoWrite tool hasn't been used recently. If you're wo...
Show more (4 lines)
Tool Result (ID: toolu_01KSRC6C5rXWLhaK7BLZ3idS)
-rw-r--r-- 1 crystalin crystalin 9898 Jul 21 21:12 /home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/adr-018-ai-powered-conversation-analysis.md
<system-reminder>
The TodoWrite tool hasn't been used recently. If you're working on tasks that would benefit from tracking progress, consider using the TodoWrite tool to track progress. Only use it if it's relevant to the current work. This is just a gentle reminder - ignore if not applicable.
</system-reminder>
Show less
Let me check for ADR-018:
Tool Use: Bash (ID: toolu_01KSRC6C5rXWLhaK7BLZ3idS)
{
"command": "ls -la /home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/adr-018*.md 2>/dev/null || echo \"No ADR-018 found\"",
"description": "Check for ADR-018"
}
Tool Result (ID: toolu_013i66SAsue9VcaPfvjXVQGY)
-rw-r--r-- 1 crystalin crystalin 4180 Jul 21 21:12 /home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/adr-017-mcp-prompt-sharing.md
Let me check if there's an ADR-017 that I should be aware of:
Tool Use: Bash (ID: toolu_013i66SAsue9VcaPfvjXVQGY)
{
"command": "ls -la /home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/adr-017*.md 2>/dev/null || echo \"No ADR-017 found\"",
"description": "C...
Show more (3 lines)
Let me check if there's an ADR-017 that I should be aware of:
Tool Use: Bash (ID: toolu_013i66SAsue9VcaPfvjXVQGY)
{
"command": "ls -la /home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/adr-017*.md 2>/dev/null || echo \"No ADR-017 found\"",
"description": "Check for ADR-017"
}
Show less
Tool Result (ID: toolu_01WFSyD2BnWSoND6Zv93Hbs7)
1→# Architecture Decision Records
2→
3→This directory contains Architecture Decision Records (ADRs) for the Claude Nexus Proxy project.
4→
5→## What is an ADR?
6→
7→An Architecture Decision Record captures a...
Show more (85 lines)
Tool Result (ID: toolu_01WFSyD2BnWSoND6Zv93Hbs7)
1→# Architecture Decision Records
2→
3→This directory contains Architecture Decision Records (ADRs) for the Claude Nexus Proxy project.
4→
5→## What is an ADR?
6→
7→An Architecture Decision Record captures an important architectural decision made along with its context and consequences.
8→
9→## ADR Template
10→
11→All ADRs in this project follow this template:
12→
13→```markdown
14→# ADR-XXX: [Title]
15→
16→## Status
17→
18→[Proposed | Accepted | Deprecated | Superseded]
19→
20→## Context
21→
22→What is the issue that we're seeing that is motivating this decision or change?
23→
24→## Decision
25→
26→What is the change that we're proposing and/or doing?
27→
28→## Consequences
29→
30→What becomes easier or more difficult to do because of this change?
31→```
32→
33→## Current ADRs
34→
35→| ADR | Title | Status | Date |
36→| -------------------------------------------------------- | ----------------------------------- | -------- | ---------- |
37→| [ADR-001](./adr-001-monorepo-structure.md) | Monorepo Structure | Accepted | 2024-01-15 |
38→| [ADR-002](./adr-002-separate-docker-images.md) | Separate Docker Images | Accepted | 2024-01-20 |
39→| [ADR-003](./adr-003-conversation-tracking.md) | Conversation Tracking Design | Accepted | 2024-02-01 |
40→| [ADR-004](./adr-004-proxy-authentication.md) | Proxy-Level Authentication | Accepted | 2024-06-25 |
41→| [ADR-005](./adr-005-token-usage-tracking.md) | Comprehensive Token Usage Tracking | Accepted | 2024-06-25 |
42→| [ADR-006](./adr-006-long-running-requests.md) | Support for Long-Running Requests | Accepted | 2024-06-25 |
43→| [ADR-007](./adr-007-subtask-tracking.md) | Sub-task Detection and Tracking | Accepted | 2024-06-25 |
44→| [ADR-008](./adr-008-cicd-strategy.md) | CI/CD Strategy with GitHub Actions | Accepted | 2024-06-25 |
45→| [ADR-009](./adr-009-dashboard-architecture.md) | Dashboard Architecture with HTMX | Accepted | 2024-06-25 |
46→| [ADR-010](./adr-010-docker-cli-integration.md) | Docker-Based Claude CLI Integration | Accepted | 2024-06-25 |
47→| [ADR-011](./adr-011-future-decisions.md) | Future Architectural Decisions | Proposed | 2024-06-25 |
48→| [ADR-012](./adr-012-database-schema-evolution.md) | Database Schema Evolution Strategy | Accepted | 2025-06-26 |
49→| [ADR-013](./adr-013-typescript-project-references.md) | TypeScript Project References | Accepted | 2025-06-27 |
50→| [ADR-014](./adr-014-sql-query-logging.md) | SQL Query Logging | Accepted | 2025-06-30 |
51→| [ADR-015](./adr-015-subtask-conversation-migration.md) | Subtask Conversation Migration | Accepted | 2025-01-07 |
52→| [ADR-016](./adr-016-ai-powered-conversation-analysis.md) | AI-Powered Conversation Analysis | Accepted | 2025-01-08 |
53→
54→## Creating a New ADR
55→
56→1. Copy the template from `template.md`
57→2. Name it `adr-XXX-brief-description.md` where XXX is the next number
58→3. Fill in all sections
59→4. Update this README with the new ADR
60→5. Submit PR for review
61→
62→## Reviewing ADRs
63→
64→When reviewing an ADR, consider:
65→
66→- Is the context clearly explained?
67→- Are alternatives considered?
68→- Are trade-offs documented?
69→- Are the consequences realistic?
70→- Is the decision actionable?
71→
72→## Superseding ADRs
73→
74→When an ADR is superseded:
75→
76→1. Update the original ADR status to "Superseded by ADR-XXX"
77→2. Link to the new ADR
78→3. Explain in the new ADR why the original decision is being changed
79→
80→## References
81→
82→- [Documenting Architecture Decisions](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions) by Michael Nygard
83→- [ADR Tools](https://github.com/npryce/adr-tools)
84→- [MADR](https://adr.github.io/madr/) - Markdown Architectural Decision Records
85→
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>
Show less
Finally, let me update the ADR index to include the new ADR:
Tool Use: Read (ID: toolu_01WFSyD2BnWSoND6Zv93Hbs7)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/README.md"
}
Tool Result (ID: toolu_01PN7mUJFKBgwJtJLcQzKQiR)
The file /home/crystalin/projects/claude-nexus-proxy/.env.example has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
7→
8→# PostgreSQL connection string
9→DATABASE_URL=postgresql://user:pas...
Show more (11 lines)
Tool Result (ID: toolu_01PN7mUJFKBgwJtJLcQzKQiR)
The file /home/crystalin/projects/claude-nexus-proxy/.env.example has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
7→
8→# PostgreSQL connection string
9→DATABASE_URL=postgresql://user:password@localhost:5432/claude_nexus
10→
11→# Dashboard authentication key (generate with: openssl rand -base64 32)
12→# ⚠️ CRITICAL: Without this, dashboard runs WITHOUT authentication, exposing ALL data!
13→# NEVER leave this unset in production!
14→DASHBOARD_API_KEY=your-secure-dashboard-key-here
15→
16→# ===================
17→# Claude API Settings
18→# ===================
Show less
Tool Use: Edit (ID: toolu_01PN7mUJFKBgwJtJLcQzKQiR)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/.env.example",
"new_string": "# Dashboard authentication key (generate with: openssl rand -base64 32)\n# ⚠️ CRITICAL: Without this, dashboard runs WITHOUT authentication, ...
Show more (4 lines)
Tool Use: Edit (ID: toolu_01PN7mUJFKBgwJtJLcQzKQiR)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/.env.example",
"new_string": "# Dashboard authentication key (generate with: openssl rand -base64 32)\n# ⚠️ CRITICAL: Without this, dashboard runs WITHOUT authentication, exposing ALL data!\n# NEVER leave this unset in production!\nDASHBOARD_API_KEY=your-secure-dashboard-key-here",
"old_string": "# Dashboard authentication key (generate with: openssl rand -base64 32)\nDASHBOARD_API_KEY=your-secure-dashboard-key-here"
}
Show less
Tool Result (ID: toolu_0121d2pdGQLrcPWfyxQknBFf)
1→# Claude Nexus Proxy Configuration Example
2→# Copy this file to .env and update with your values
3→
4→# ===================
5→# Required Settings
6→# ===================
7→
8→# PostgreSQL connection ...
Show more (49 lines)
Tool Result (ID: toolu_0121d2pdGQLrcPWfyxQknBFf)
1→# Claude Nexus Proxy Configuration Example
2→# Copy this file to .env and update with your values
3→
4→# ===================
5→# Required Settings
6→# ===================
7→
8→# PostgreSQL connection string
9→DATABASE_URL=postgresql://user:password@localhost:5432/claude_nexus
10→
11→# Dashboard authentication key (generate with: openssl rand -base64 32)
12→DASHBOARD_API_KEY=your-secure-dashboard-key-here
13→
14→# ===================
15→# Claude API Settings
16→# ===================
17→
18→# API keys are managed through credential files in the credentials/ directory
19→# See credentials/README.md for setup instructions
20→
21→# Directory for domain credential files (default: ./credentials)
22→CREDENTIALS_DIR=./credentials
23→
24→# ===================
25→# Service Configuration
26→# ===================
27→
28→# Proxy service
29→PORT=3000
30→HOST=0.0.0.0
31→
32→# Dashboard service
33→DASHBOARD_PORT=3001
34→DASHBOARD_HOST=0.0.0.0
35→
36→# ===================
37→# Feature Flags
38→# ===================
39→
40→# Enable request/response storage (default: false)
41→STORAGE_ENABLED=true
42→
43→# Enable debug logging - masks sensitive data (default: false)
44→DEBUG=false
45→
46→# Enable SQL query logging (default: false)
47→# Shows all SQL queries in debug logs when running the application
48→DEBUG_SQL=false
49→
50→# Require client authentication (default: true)
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>
Show less
Now let me check if there's a .env.example file that needs updating:
Tool Use: Read (ID: toolu_0121d2pdGQLrcPWfyxQknBFf)
{
"limit": 50,
"file_path": "/home/crystalin/projects/claude-nexus-proxy/.env.example"
}
Tool Result (ID: toolu_016DojYQCR2hACNVRgd8zZrW)
The file /home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
480→
481→# Check proxy logs
482→docker logs proxy -...
Show more (64 lines)
Tool Result (ID: toolu_016DojYQCR2hACNVRgd8zZrW)
The file /home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
480→
481→# Check proxy logs
482→docker logs proxy --tail 100
483→
484→# Verify credentials
485→ls -la credentials/
486→```
487→
488→## Security Considerations
489→
490→### ⚠️ CRITICAL: Dashboard Authentication
491→
492→**Never deploy the dashboard without setting `DASHBOARD_API_KEY`!**
493→
494→When `DASHBOARD_API_KEY` is not set, the dashboard runs in "read-only mode" with NO authentication, exposing:
495→- All conversation histories
496→- Token usage and costs
497→- Account information
498→- AI analysis results
499→- Potentially sensitive customer data
500→
501→**Production Security Checklist:**
502→
503→```bash
504→# 1. ALWAYS set DASHBOARD_API_KEY (minimum 32 characters)
505→export DASHBOARD_API_KEY=$(openssl rand -base64 32)
506→
507→# 2. Verify it's set before deployment
508→if [ -z "$DASHBOARD_API_KEY" ]; then
509→ echo "ERROR: DASHBOARD_API_KEY not set!"
510→ exit 1
511→fi
512→
513→# 3. Never expose dashboard port directly to internet
514→# Use reverse proxy with additional authentication
515→# Block port 3001 at firewall level
516→
517→# 4. Test authentication is working
518→curl -I http://localhost:3001/dashboard
519→# Should return 302 redirect to login
520→```
521→
522→### Network Security
523→
524→1. **Firewall Rules**:
525→ - Only expose reverse proxy ports (80/443)
526→ - Block direct access to service ports (3000/3001)
527→ - Whitelist specific IPs if possible
528→
529→2. **Internal Network Only**:
530→ ```bash
531→ # Docker: Use internal network
532→ docker run --network internal ...
533→
534→ # Or bind to localhost only
535→ docker run -p 127.0.0.1:3001:3001 ...
536→ ```
537→
538→3. **Additional Authentication Layer**:
539→ - Consider basic auth at reverse proxy level
540→ - Use VPN for dashboard access
541→ - Implement IP whitelisting
542→
543→See the [Security Guide](../security.md) for comprehensive security information.
544→
Show less
Tool Use: Edit (ID: toolu_016DojYQCR2hACNVRgd8zZrW)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md",
"new_string": "# Verify credentials\nls -la credentials/\n```\n\n## Security Considerations\n\n### ⚠️ CRITICAL: Dashboard Authent...
Show more (4 lines)
Tool Use: Edit (ID: toolu_016DojYQCR2hACNVRgd8zZrW)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md",
"new_string": "# Verify credentials\nls -la credentials/\n```\n\n## Security Considerations\n\n### ⚠️ CRITICAL: Dashboard Authentication\n\n**Never deploy the dashboard without setting `DASHBOARD_API_KEY`!**\n\nWhen `DASHBOARD_API_KEY` is not set, the dashboard runs in \"read-only mode\" with NO authentication, exposing:\n- All conversation histories\n- Token usage and costs\n- Account information\n- AI analysis results\n- Potentially sensitive customer data\n\n**Production Security Checklist:**\n\n```bash\n# 1. ALWAYS set DASHBOARD_API_KEY (minimum 32 characters)\nexport DASHBOARD_API_KEY=$(openssl rand -base64 32)\n\n# 2. Verify it's set before deployment\nif [ -z \"$DASHBOARD_API_KEY\" ]; then\n echo \"ERROR: DASHBOARD_API_KEY not set!\"\n exit 1\nfi\n\n# 3. Never expose dashboard port directly to internet\n# Use reverse proxy with additional authentication\n# Block port 3001 at firewall level\n\n# 4. Test authentication is working\ncurl -I http://localhost:3001/dashboard\n# Should return 302 redirect to login\n```\n\n### Network Security\n\n1. **Firewall Rules**:\n - Only expose reverse proxy ports (80/443)\n - Block direct access to service ports (3000/3001)\n - Whitelist specific IPs if possible\n\n2. **Internal Network Only**:\n ```bash\n # Docker: Use internal network\n docker run --network internal ...\n \n # Or bind to localhost only\n docker run -p 127.0.0.1:3001:3001 ...\n ```\n\n3. **Additional Authentication Layer**:\n - Consider basic auth at reverse proxy level\n - Use VPN for dashboard access\n - Implement IP whitelisting\n\nSee the [Security Guide](../security.md) for comprehensive security information.",
"old_string": "# Verify credentials\nls -la credentials/\n```"
}
Show less
Tool Result (ID: toolu_01MCckXXrPRkHvCtF4dov5Qr)
docker service update --image claude-nexus-dashboard:new dashboard
Database Maintenance
# Vacuum and analyze
psql $DATABASE_URL -c "VACUUM ANALYZE;"
# Reindex for performance
psql $DATABASE_URL -c "REINDEX DATABASE claude_n...
Show more (41 lines)
Tool Result (ID: toolu_01MCckXXrPRkHvCtF4dov5Qr)
docker service update --image claude-nexus-dashboard:new dashboard
Database Maintenance
# Vacuum and analyze
psql $DATABASE_URL -c "VACUUM ANALYZE;"
# Reindex for performance
psql $DATABASE_URL -c "REINDEX DATABASE claude_nexus;"
Troubleshooting Production Issues
High Memory Usage
# Check memory usage
docker stats
# Limit container memory
docker run -m 1g claude-nexus-proxy
Slow Queries
# Enable slow query logging
SLOW_QUERY_THRESHOLD_MS=1000
# Check pg_stat_statements
SELECT query, mean_exec_time, calls
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;
Connection Issues
# Test database connection
psql $DATABASE_URL -c "SELECT 1;"
# Check proxy logs
docker logs proxy --tail 100
# Verify credentials
ls -la credentials/
Show less
Let me check the end of the file to see where to add the security section:
Tool Use: Bash (ID: toolu_01MCckXXrPRkHvCtF4dov5Qr)
{
"command": "tail -50 /home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md",
"description": "Check end of docker deplo...
Show more (3 lines)
Let me check the end of the file to see where to add the security section:
Tool Use: Bash (ID: toolu_01MCckXXrPRkHvCtF4dov5Qr)
{
"command": "tail -50 /home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md",
"description": "Check end of docker deployment guide"
}
Show less
Tool Result (ID: toolu_01HXGLRArVQjfYemvZJ1iT1n)
200→ proxy_set_header X-Real-IP $remote_addr;
201→ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
202→
203→ # For streaming responses
204→ proxy_buffering off;
205→ proxy_cache o...
Show more (105 lines)
Tool Result (ID: toolu_01HXGLRArVQjfYemvZJ1iT1n)
200→ proxy_set_header X-Real-IP $remote_addr;
201→ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
202→
203→ # For streaming responses
204→ proxy_buffering off;
205→ proxy_cache off;
206→ }
207→}
208→
209→# Dashboard
210→server {
211→ listen 443 ssl http2;
212→ server_name dashboard.yourdomain.com;
213→
214→ ssl_certificate /path/to/cert.pem;
215→ ssl_certificate_key /path/to/key.pem;
216→
217→ location / {
218→ proxy_pass http://dashboard_backend;
219→ proxy_http_version 1.1;
220→ proxy_set_header Host $host;
221→ proxy_set_header X-Real-IP $remote_addr;
222→ }
223→
224→ # SSE endpoint
225→ location /sse {
226→ proxy_pass http://dashboard_backend/sse;
227→ proxy_http_version 1.1;
228→ proxy_set_header Connection "";
229→ proxy_buffering off;
230→ proxy_cache off;
231→ }
232→}
233→```
234→
235→#### Caddy Configuration
236→
237→```caddyfile
238→api.yourdomain.com {
239→ reverse_proxy localhost:3000 {
240→ flush_interval -1
241→ }
242→}
243→
244→dashboard.yourdomain.com {
245→ reverse_proxy localhost:3001
246→}
247→```
248→
249→## Scaling
250→
251→### Horizontal Scaling
252→
253→1. **Proxy Service** - Stateless, scale freely:
254→
255→```bash
256→# Docker Swarm
257→docker service scale proxy=5
258→
259→# Kubernetes
260→kubectl scale deployment proxy --replicas=5
261→```
262→
263→2. **Dashboard Service** - Also stateless:
264→
265→```bash
266→docker service scale dashboard=3
267→```
268→
269→3. **Database** - Use read replicas for dashboard:
270→
271→```bash
272→# Primary for writes (proxy)
273→DATABASE_URL=postgresql://primary:5432/claude_nexus
274→
275→# Read replica for dashboard
276→DATABASE_URL=postgresql://replica:5432/claude_nexus
277→```
278→
279→### Performance Tuning
280→
281→1. **Connection Pooling**:
282→
283→```bash
284→DATABASE_URL=postgresql://...?pool_max=50&pool_idle_timeout=10000
285→```
286→
287→2. **Disable Non-Essential Features**:
288→
289→```bash
290→STORAGE_ENABLED=false # If not needed
291→DEBUG=false
292→COLLECT_TEST_SAMPLES=false
293→```
294→
295→3. **Optimize Dashboard**:
296→
297→```bash
298→DASHBOARD_CACHE_TTL=600 # 10-minute cache
299→```
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>
<system-reminder>
The TodoWrite tool hasn't been used recently. If you're working on tasks that would benefit from tracking progress, consider using the TodoWrite tool to track progress. Only use it if it's relevant to the current work. This is just a gentle reminder - ignore if not applicable.
</system-reminder>
Show less
Let me also add a security section to this deployment guide:
Tool Use: Read (ID: toolu_01HXGLRArVQjfYemvZJ1iT1n)
{
"limit": 100,
"offset": 200,
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md"
}
Tool Result (ID: toolu_014kiuBb7L1r9zzBvYvJwa6M)
The file /home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
45→ -e DATABASE_URL=$DATABASE_URL \
46→ -v $(pwd)/...
Show more (16 lines)
Tool Result (ID: toolu_014kiuBb7L1r9zzBvYvJwa6M)
The file /home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
45→ -e DATABASE_URL=$DATABASE_URL \
46→ -v $(pwd)/credentials:/app/credentials:ro \
47→ claude-nexus-proxy
48→
49→# Run dashboard
50→# ⚠️ CRITICAL: Always set DASHBOARD_API_KEY to prevent unauthorized access
51→docker run -d \
52→ --name claude-dashboard \
53→ -p 3001:3001 \
54→ -e DATABASE_URL=$DATABASE_URL \
55→ -e DASHBOARD_API_KEY=$DASHBOARD_API_KEY \
56→ claude-nexus-dashboard
57→```
58→
59→### 2. Bare Metal with Bun
60→
Show less
Let me add security warnings to the docker deployment guide:
Tool Use: Edit (ID: toolu_014kiuBb7L1r9zzBvYvJwa6M)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md",
"new_string": "# Run dashboard\n# ⚠️ CRITICAL: Always set DASH...
Show more (4 lines)
Let me add security warnings to the docker deployment guide:
Tool Use: Edit (ID: toolu_014kiuBb7L1r9zzBvYvJwa6M)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md",
"new_string": "# Run dashboard\n# ⚠️ CRITICAL: Always set DASHBOARD_API_KEY to prevent unauthorized access\ndocker run -d \\\n --name claude-dashboard \\\n -p 3001:3001 \\\n -e DATABASE_URL=$DATABASE_URL \\\n -e DASHBOARD_API_KEY=$DASHBOARD_API_KEY \\\n claude-nexus-dashboard",
"old_string": "# Run dashboard\ndocker run -d \\\n --name claude-dashboard \\\n -p 3001:3001 \\\n -e DATABASE_URL=$DATABASE_URL \\\n -e DASHBOARD_API_KEY=$DASHBOARD_API_KEY \\\n claude-nexus-dashboard"
}
Show less
Tool Result (ID: toolu_016kDhK7y2ptAhwmtAjoFipU)
1→# Deployment Guide
2→
3→This guide covers deploying Claude Nexus Proxy to production environments.
4→
5→## Deployment Options
6→
7→> **Note**: For AWS EC2 deployment with staging/production environments, s...
Show more (100 lines)
Tool Result (ID: toolu_016kDhK7y2ptAhwmtAjoFipU)
1→# Deployment Guide
2→
3→This guide covers deploying Claude Nexus Proxy to production environments.
4→
5→## Deployment Options
6→
7→> **Note**: For AWS EC2 deployment with staging/production environments, see [AWS Infrastructure Guide](./aws-infrastructure.md).
8→
9→### 1. Docker (Recommended)
10→
11→The project provides optimized Docker images for each service.
12→
13→#### Build Images
14→
15→```bash
16→# Build both images
17→./docker/build-images.sh
18→
19→# Or build individually
20→docker build -f docker/proxy/Dockerfile -t claude-nexus-proxy .
21→docker build -f docker/dashboard/Dockerfile -t claude-nexus-dashboard .
22→```
23→
24→#### Run with Docker Compose
25→
26→```bash
27→# Create .env file
28→cp .env.example .env
29→# Edit .env with production values
30→
31→# Start services
32→docker-compose up -d
33→
34→# View logs
35→docker-compose logs -f
36→```
37→
38→#### Run Standalone Containers
39→
40→```bash
41→# Run proxy
42→docker run -d \
43→ --name claude-proxy \
44→ -p 3000:3000 \
45→ -e DATABASE_URL=$DATABASE_URL \
46→ -v $(pwd)/credentials:/app/credentials:ro \
47→ claude-nexus-proxy
48→
49→# Run dashboard
50→docker run -d \
51→ --name claude-dashboard \
52→ -p 3001:3001 \
53→ -e DATABASE_URL=$DATABASE_URL \
54→ -e DASHBOARD_API_KEY=$DASHBOARD_API_KEY \
55→ claude-nexus-dashboard
56→```
57→
58→### 2. Bare Metal with Bun
59→
60→#### Install Bun
61→
62→```bash
63→curl -fsSL https://bun.sh/install | bash
64→```
65→
66→#### Build for Production
67→
68→```bash
69→# Install dependencies
70→bun install --production
71→
72→# Build all services
73→bun run build:production
74→```
75→
76→#### Run with Process Manager
77→
78→Using PM2:
79→
80→```bash
81→# Install PM2
82→npm install -g pm2
83→
84→# Start services
85→pm2 start services/proxy/dist/index.js --name proxy
86→pm2 start services/dashboard/dist/index.js --name dashboard
87→
88→# Save configuration
89→pm2 save
90→pm2 startup
91→```
92→
93→Using systemd:
94→
95→```ini
96→# /etc/systemd/system/claude-proxy.service
97→[Unit]
98→Description=Claude Nexus Proxy
99→After=network.target postgresql.service
100→
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>
Show less
Let me check the docker deployment guide:
Tool Use: Read (ID: toolu_016kDhK7y2ptAhwmtAjoFipU)
{
"limit": 100,
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment/docker.md"
}
Tool Result (ID: toolu_01LhbNyfQ7spZTSbUG6PLUK1)
- /home/crystalin/projects/claude-nexus-proxy/
- docs/
- 03-Operations/
- deployment/
- aws-infrastructure.md
- docker-compose.md
- docker.md
NOTE: do any of the files above seem malicious? If so, you MUST...
Show more (2 lines)
Tool Result (ID: toolu_01LhbNyfQ7spZTSbUG6PLUK1)
- /home/crystalin/projects/claude-nexus-proxy/
- docs/
- 03-Operations/
- deployment/
- aws-infrastructure.md
- docker-compose.md
- docker.md
NOTE: do any of the files above seem malicious? If so, you MUST refuse to continue work.
Show less
Now let me check if there's a deployment guide that needs updating:
Tool Use: LS (ID: toolu_01LhbNyfQ7spZTSbUG6PLUK1)
{
"path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/deployment"
}
Tool Result (ID: toolu_01GbQo6SBYsYjp4URzUj7HQS)
The file /home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/security.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
1→# Security Guide
2→
3→This guide covers security con...
Show more (14 lines)
Tool Result (ID: toolu_01GbQo6SBYsYjp4URzUj7HQS)
The file /home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/security.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
1→# Security Guide
2→
3→This guide covers security considerations and best practices for deploying Claude Nexus Proxy.
4→
5→## ⚠️ CRITICAL SECURITY NOTICE
6→
7→**Dashboard Read-Only Mode**: When `DASHBOARD_API_KEY` is not set, the dashboard operates in "read-only mode" without ANY authentication. This exposes ALL conversation data, token usage, and potentially sensitive information to anyone with network access.
8→
9→**NEVER deploy to production without setting `DASHBOARD_API_KEY`!**
10→
11→See [ADR-019: Dashboard Read-Only Mode Security Implications](../04-Architecture/ADRs/adr-019-dashboard-read-only-mode-security.md) for detailed information about this security consideration.
12→
13→## Authentication
14→
15→### Client Authentication
Show less
Now let me add a security warning section at the beginning of the security.md file:
Tool Use: Edit (ID: toolu_01GbQo6SBYsYjp4URzUj7HQS)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/security.md",
"new_string": "# Security Guide\n\nThis guide co...
Show more (4 lines)
Now let me add a security warning section at the beginning of the security.md file:
Tool Use: Edit (ID: toolu_01GbQo6SBYsYjp4URzUj7HQS)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/security.md",
"new_string": "# Security Guide\n\nThis guide covers security considerations and best practices for deploying Claude Nexus Proxy.\n\n## ⚠️ CRITICAL SECURITY NOTICE\n\n**Dashboard Read-Only Mode**: When `DASHBOARD_API_KEY` is not set, the dashboard operates in \"read-only mode\" without ANY authentication. This exposes ALL conversation data, token usage, and potentially sensitive information to anyone with network access. \n\n**NEVER deploy to production without setting `DASHBOARD_API_KEY`!**\n\nSee [ADR-019: Dashboard Read-Only Mode Security Implications](../04-Architecture/ADRs/adr-019-dashboard-read-only-mode-security.md) for detailed information about this security consideration.",
"old_string": "# Security Guide\n\nThis guide covers security considerations and best practices for deploying Claude Nexus Proxy."
}
Show less
Tool Result (ID: toolu_0133S2yVqQcvhQ2kFNAWo82x)
The file /home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/security.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
219→- [ ] Regular credential rotation
220→- [ ] Database backup...
Show more (42 lines)
Tool Result (ID: toolu_0133S2yVqQcvhQ2kFNAWo82x)
The file /home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/security.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
219→- [ ] Regular credential rotation
220→- [ ] Database backup encryption
221→- [ ] Security audit schedule
222→
223→## Common Vulnerabilities
224→
225→### 1. Exposed Dashboard (CRITICAL)
226→
227→**Risk**: Dashboard accessible without authentication exposes ALL conversation data
228→
229→**⚠️ CRITICAL SECURITY WARNING**:
230→When `DASHBOARD_API_KEY` is not set, the dashboard runs in "read-only mode" with NO authentication. This means:
231→- Anyone with network access can view ALL conversations
232→- All API requests and responses are visible
233→- Token usage, costs, and account information are exposed
234→- AI analysis results and insights are accessible
235→- This includes potentially sensitive customer data, API keys in conversations, and proprietary information
236→
237→**Impact**: Complete data exposure, privacy breach, potential compliance violations
238→
239→**Mitigation**:
240→
241→- **ALWAYS** set `DASHBOARD_API_KEY` in production
242→- Use strong, unique keys (minimum 32 characters)
243→- Restrict dashboard to internal network only
244→- Never expose dashboard port (3001) to the internet
245→- Consider using a reverse proxy with additional authentication
246→- For local development only, use read-only mode behind a firewall
247→
248→**Checking for Vulnerability**:
249→```bash
250→# If this returns empty, your dashboard is UNSECURED
251→echo $DASHBOARD_API_KEY
252→
253→# Check if dashboard is publicly accessible
254→curl http://your-server:3001/dashboard
255→# If you see the dashboard without login, it's exposed
256→```
257→
258→### 2. Credential Leakage
259→
260→**Risk**: Credentials in logs or error messages
Show less
Now let me update the security.md file to add more detailed warnings about read-only mode:
Tool Use: Edit (ID: toolu_0133S2yVqQcvhQ2kFNAWo82x)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/security.md",
"new_string": "## Common Vulnerabilities\...
Show more (4 lines)
Now let me update the security.md file to add more detailed warnings about read-only mode:
Tool Use: Edit (ID: toolu_0133S2yVqQcvhQ2kFNAWo82x)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/security.md",
"new_string": "## Common Vulnerabilities\n\n### 1. Exposed Dashboard (CRITICAL)\n\n**Risk**: Dashboard accessible without authentication exposes ALL conversation data\n\n**⚠️ CRITICAL SECURITY WARNING**: \nWhen `DASHBOARD_API_KEY` is not set, the dashboard runs in \"read-only mode\" with NO authentication. This means:\n- Anyone with network access can view ALL conversations\n- All API requests and responses are visible\n- Token usage, costs, and account information are exposed\n- AI analysis results and insights are accessible\n- This includes potentially sensitive customer data, API keys in conversations, and proprietary information\n\n**Impact**: Complete data exposure, privacy breach, potential compliance violations\n\n**Mitigation**:\n\n- **ALWAYS** set `DASHBOARD_API_KEY` in production\n- Use strong, unique keys (minimum 32 characters)\n- Restrict dashboard to internal network only\n- Never expose dashboard port (3001) to the internet\n- Consider using a reverse proxy with additional authentication\n- For local development only, use read-only mode behind a firewall\n\n**Checking for Vulnerability**:\n```bash\n# If this returns empty, your dashboard is UNSECURED\necho $DASHBOARD_API_KEY\n\n# Check if dashboard is publicly accessible\ncurl http://your-server:3001/dashboard\n# If you see the dashboard without login, it's exposed\n```",
"old_string": "## Common Vulnerabilities\n\n### 1. Exposed Dashboard\n\n**Risk**: Dashboard accessible without authentication\n\n**Mitigation**:\n\n- Always set `DASHBOARD_API_KEY`\n- Use strong, unique keys\n- Restrict dashboard to internal network"
}
Show less
Tool Result (ID: toolu_01RSwaFB2Q4dc4Ww4QArUvCF)
The file /home/crystalin/projects/claude-nexus-proxy/README.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
140→ "messages": [{"role": "user", "content": "Hello!"}]
141→ }'
142→```
1...
Show more (18 lines)
Tool Result (ID: toolu_01RSwaFB2Q4dc4Ww4QArUvCF)
The file /home/crystalin/projects/claude-nexus-proxy/README.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
140→ "messages": [{"role": "user", "content": "Hello!"}]
141→ }'
142→```
143→
144→### Dashboard
145→
146→Access the dashboard at `http://localhost:3001` with your `DASHBOARD_API_KEY`.
147→
148→**⚠️ Security Warning**: If `DASHBOARD_API_KEY` is not set, the dashboard runs in read-only mode without any authentication, exposing all conversation data. This should NEVER be used in production. See the [Security Guide](docs/03-Operations/security.md) for details.
149→
150→Features:
151→
152→- Real-time request monitoring
153→- Conversation visualization with branching
154→- Token usage analytics
<system-reminder>
The TodoWrite tool hasn't been used recently. If you're working on tasks that would benefit from tracking progress, consider using the TodoWrite tool to track progress. Only use it if it's relevant to the current work. This is just a gentle reminder - ignore if not applicable.
</system-reminder>
Show less
Tool Use: Edit (ID: toolu_01RSwaFB2Q4dc4Ww4QArUvCF)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/README.md",
"new_string": "### Dashboard\n\nAccess the dashboard at `http://localhost:3001` with your `DASHBOARD_API_KEY`.\n\n**⚠️ Security Warning**: If `DASHBOARD_API_KE...
Show more (4 lines)
Tool Use: Edit (ID: toolu_01RSwaFB2Q4dc4Ww4QArUvCF)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/README.md",
"new_string": "### Dashboard\n\nAccess the dashboard at `http://localhost:3001` with your `DASHBOARD_API_KEY`.\n\n**⚠️ Security Warning**: If `DASHBOARD_API_KEY` is not set, the dashboard runs in read-only mode without any authentication, exposing all conversation data. This should NEVER be used in production. See the [Security Guide](docs/03-Operations/security.md) for details.\n\nFeatures:",
"old_string": "### Dashboard\n\nAccess the dashboard at `http://localhost:3001` with your `DASHBOARD_API_KEY`.\n\nFeatures:"
}
Show less
Tool Result (ID: toolu_01JujrDtNGZyzekfcRLkFiBS)
The file /home/crystalin/projects/claude-nexus-proxy/README.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
91→```bash
92→# Database
93→DATABASE_URL=postgresql://user:password@localhost:...
Show more (12 lines)
Tool Result (ID: toolu_01JujrDtNGZyzekfcRLkFiBS)
The file /home/crystalin/projects/claude-nexus-proxy/README.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
91→```bash
92→# Database
93→DATABASE_URL=postgresql://user:password@localhost:5432/claude_nexus
94→
95→# Dashboard Authentication
96→# ⚠️ CRITICAL SECURITY WARNING: Without this key, the dashboard runs in read-only mode
97→# with NO authentication, exposing ALL conversation data to anyone with network access!
98→# NEVER deploy to production without setting this!
99→DASHBOARD_API_KEY=your-secure-key
100→
101→# Optional Features
102→STORAGE_ENABLED=true
103→DEBUG=false
Show less
Now let me update the main README.md to add security warnings:
Tool Use: Edit (ID: toolu_01JujrDtNGZyzekfcRLkFiBS)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/README.md",
"new_string": "# Dashboard Authentication\n# ⚠️ CRITICAL SECURITY WARNING: Without this ke...
Show more (4 lines)
Now let me update the main README.md to add security warnings:
Tool Use: Edit (ID: toolu_01JujrDtNGZyzekfcRLkFiBS)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/README.md",
"new_string": "# Dashboard Authentication\n# ⚠️ CRITICAL SECURITY WARNING: Without this key, the dashboard runs in read-only mode\n# with NO authentication, exposing ALL conversation data to anyone with network access!\n# NEVER deploy to production without setting this!\nDASHBOARD_API_KEY=your-secure-key",
"old_string": "# Dashboard Authentication\nDASHBOARD_API_KEY=your-secure-key"
}
Show less
Tool Result (ID: toolu_01RLhWdvZurA7rx7WbyAaGbk)
The file /home/crystalin/projects/claude-nexus-proxy/CLAUDE.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
369→- Failed query errors with details
370→
371→## Environment Variables
372→
...
Show more (9 lines)
Tool Result (ID: toolu_01RLhWdvZurA7rx7WbyAaGbk)
The file /home/crystalin/projects/claude-nexus-proxy/CLAUDE.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
369→- Failed query errors with details
370→
371→## Environment Variables
372→
373→**Essential:**
374→
375→- `DATABASE_URL` - PostgreSQL connection
376→- `DASHBOARD_API_KEY` - Dashboard authentication (⚠️ **CRITICAL**: Without this, dashboard runs in read-only mode with NO authentication)
377→
378→**Optional:**
379→
380→- `DEBUG` - Enable debug logging
Show less
Tool Use: Edit (ID: toolu_01RLhWdvZurA7rx7WbyAaGbk)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/CLAUDE.md",
"new_string": "**Essential:**\n\n- `DATABASE_URL` - PostgreSQL connection\n- `DASHBOARD_API_KEY` - Dashboard authentication (⚠️ **CRITICAL**: Without this, das...
Show more (4 lines)
Tool Use: Edit (ID: toolu_01RLhWdvZurA7rx7WbyAaGbk)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/CLAUDE.md",
"new_string": "**Essential:**\n\n- `DATABASE_URL` - PostgreSQL connection\n- `DASHBOARD_API_KEY` - Dashboard authentication (⚠️ **CRITICAL**: Without this, dashboard runs in read-only mode with NO authentication)",
"old_string": "**Essential:**\n\n- `DATABASE_URL` - PostgreSQL connection\n- `DASHBOARD_API_KEY` - Dashboard authentication"
}
Show less
Tool Result (ID: toolu_01USgMjd1yMUgWj4yqsjB6QN)
The file /home/crystalin/projects/claude-nexus-proxy/CLAUDE.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
49→- Request/response storage
50→- Slack notifications
51→- AI-powered convers...
Show more (14 lines)
Tool Result (ID: toolu_01USgMjd1yMUgWj4yqsjB6QN)
The file /home/crystalin/projects/claude-nexus-proxy/CLAUDE.md has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
49→- Request/response storage
50→- Slack notifications
51→- AI-powered conversation analysis (Phase 2 - Prompt Engineering with full env var support)
52→
53→**Dashboard Service** (`services/dashboard/`)
54→
55→- Monitoring UI
56→- Analytics and usage charts
57→- Request history browser
58→- SSE for live updates
59→- **⚠️ SECURITY WARNING**: Read-only mode (when `DASHBOARD_API_KEY` is not set) exposes all data without authentication. See [ADR-019](docs/04-Architecture/ADRs/adr-019-dashboard-read-only-mode-security.md)
60→
61→## Development
62→
63→```bash
Show less
Now let me update the CLAUDE.md file to include security warnings:
Tool Use: Edit (ID: toolu_01USgMjd1yMUgWj4yqsjB6QN)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/CLAUDE.md",
"new_string": "**Dashboard Service** (`services/dashboard/`)\n\n- Monitoring UI\n- Ana...
Show more (4 lines)
Now let me update the CLAUDE.md file to include security warnings:
Tool Use: Edit (ID: toolu_01USgMjd1yMUgWj4yqsjB6QN)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/CLAUDE.md",
"new_string": "**Dashboard Service** (`services/dashboard/`)\n\n- Monitoring UI\n- Analytics and usage charts\n- Request history browser\n- SSE for live updates\n- **⚠️ SECURITY WARNING**: Read-only mode (when `DASHBOARD_API_KEY` is not set) exposes all data without authentication. See [ADR-019](docs/04-Architecture/ADRs/adr-019-dashboard-read-only-mode-security.md)",
"old_string": "**Dashboard Service** (`services/dashboard/`)\n\n- Monitoring UI\n- Analytics and usage charts\n- Request history browser\n- SSE for live updates"
}
Show less
Tool Result (ID: toolu_01MuaQ7JmWcptGbBDZokeSmw)
File created successfully at: /home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/adr-019-dashboard-read-only-mode-security.md
Now I'll create a comprehensive update to the documentation reflecting the security findings about read-only mode. Let me start with creating an ADR documenting this decision:
Tool Use: Write (ID: toolu_01MuaQ7JmWcptGbBDZokeSmw)
{
"content": "# ADR-019: Dashboard Read-Only Mode ...
Show more (4 lines)
Now I'll create a comprehensive update to the documentation reflecting the security findings about read-only mode. Let me start with creating an ADR documenting this decision:
Tool Use: Write (ID: toolu_01MuaQ7JmWcptGbBDZokeSmw)
{
"content": "# ADR-019: Dashboard Read-Only Mode Security Implications\n\n## Status\n\nAccepted\n\n## Context\n\nThe Claude Nexus Proxy dashboard was modified to support a \"read-only mode\" that allows access without authentication when `DASHBOARD_API_KEY` is not set. This was implemented to simplify development and quick deployments, but it introduces significant security concerns that need to be documented and addressed.\n\n### Current Implementation\n\nWhen `DASHBOARD_API_KEY` is not set in the environment:\n- The dashboard operates in \"read-only mode\" (`isReadOnly = true`)\n- All authentication checks are bypassed\n- Anyone with network access to the dashboard can view all data\n- This includes sensitive information such as:\n - All API requests and responses\n - Conversation histories with potentially sensitive content\n - Token usage statistics and costs\n - Account identifiers and usage patterns\n - AI analysis results and insights\n\n## Decision Drivers\n\n- **Developer Experience**: Need for quick local development without authentication setup\n- **Security**: Protecting sensitive conversation data and usage information\n- **Deployment Safety**: Preventing accidental exposure of data in production\n- **Transparency**: Clear communication about security implications\n- **Backward Compatibility**: Supporting existing deployments that rely on read-only mode\n\n## Considered Options\n\n1. **Remove Read-Only Mode Entirely**\n - Description: Require `DASHBOARD_API_KEY` in all cases\n - Pros: \n - Eliminates security risk completely\n - Forces secure configuration\n - Simpler security model\n - Cons: \n - Breaks existing deployments\n - Complicates local development\n - More setup friction\n\n2. **Keep Read-Only Mode with Clear Warnings**\n - Description: Maintain current behavior but add prominent security warnings\n - Pros:\n - Preserves backward compatibility\n - Maintains developer convenience\n - Clear about security implications\n - Cons:\n - Security risk remains\n - Users may ignore warnings\n - Potential for misconfiguration\n\n3. **Read-Only Mode for Local Development Only**\n - Description: Enable read-only mode only when explicitly running in development mode\n - Pros:\n - Balances security and convenience\n - Safe by default in production\n - Developer-friendly\n - Cons:\n - Requires additional configuration\n - May confuse users about when auth is required\n\n4. **Implement IP-Based Restrictions for Read-Only Mode**\n - Description: Allow read-only mode but restrict to localhost/private IPs\n - Pros:\n - Safer than unrestricted access\n - Still convenient for local development\n - Cons:\n - Can be bypassed with proxies\n - Complex to implement correctly\n - False sense of security\n\n## Decision\n\nWe will **keep read-only mode with clear warnings** (Option 2) for now, but with the following immediate actions:\n\n1. Add prominent security warnings in all documentation\n2. Display security warnings in the dashboard UI when in read-only mode\n3. Log warnings at startup when read-only mode is active\n4. Plan for deprecation in a future major version\n\n### Implementation Details\n\n1. **Documentation Updates**:\n - Add security warnings to README.md\n - Update CLAUDE.md with security implications\n - Enhance security.md with detailed warnings\n - Add warnings to deployment guides\n\n2. **UI Warnings**:\n ```typescript\n // Display banner when in read-only mode\n if (isReadOnly) {\n showWarningBanner('Dashboard is in read-only mode without authentication. Do not use in production!')\n }\n ```\n\n3. **Startup Warnings**:\n ```typescript\n if (!process.env.DASHBOARD_API_KEY) {\n console.warn('⚠️ WARNING: Dashboard running in READ-ONLY MODE without authentication!')\n console.warn('⚠️ This exposes all conversation data to anyone with network access.')\n console.warn('⚠️ Set DASHBOARD_API_KEY environment variable to enable authentication.')\n }\n ```\n\n## Consequences\n\n### Positive\n\n- Maintains backward compatibility\n- Preserves developer convenience for local development\n- Clear communication reduces risk of accidental exposure\n- Provides migration path for existing users\n\n### Negative\n\n- Security vulnerability remains until deprecated\n- Risk of users ignoring warnings\n- Potential for data exposure if deployed incorrectly\n- Technical debt that needs future resolution\n\n### Security Implications\n\n**Critical**: Running the dashboard without `DASHBOARD_API_KEY` exposes:\n- All conversation histories\n- Token usage and costs\n- Account information\n- AI analysis results\n- Request/response payloads\n\nThis mode should **NEVER** be used in production or any environment accessible from the internet.\n\n## Future Recommendations\n\n1. **Phase 1** (Current): Add warnings and documentation\n2. **Phase 2** (Next Minor Version): Add deprecation warnings\n3. **Phase 3** (Next Major Version): Remove read-only mode or restrict to explicit development mode\n4. **Alternative**: Implement a separate \"demo mode\" with synthetic data for testing\n\n## References\n\n- [Security Guide](../../03-Operations/security.md)\n- [Dashboard Architecture (ADR-009)](./adr-009-dashboard-architecture.md)\n- Original PR: feat: add read-only mode support for dashboard without API key",
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/adr-019-dashboard-read-only-mode-security.md"
}
Show less
Tool Result (ID: toolu_017RD3eqxVioGY64A7FkT2dR)
1→# Security Guide
2→
3→This guide covers security considerations and best practices for deploying Claude Nexus Proxy.
4→
5→## Authentication
6→
7→### Client Authentication
8→
9→The proxy supports ...
Show more (303 lines)
Tool Result (ID: toolu_017RD3eqxVioGY64A7FkT2dR)
1→# Security Guide
2→
3→This guide covers security considerations and best practices for deploying Claude Nexus Proxy.
4→
5→## Authentication
6→
7→### Client Authentication
8→
9→The proxy supports multiple authentication layers:
10→
11→1. **Client API Keys** - For authenticating clients to the proxy
12→2. **Claude API Keys** - For authenticating the proxy to Claude
13→3. **OAuth Tokens** - Alternative to API keys with auto-refresh
14→
15→#### Client Authentication Setup
16→
17→```bash
18→# Generate secure client API key
19→bun run auth:generate-key
20→# Output: cnp_live_1a2b3c4d5e6f...
21→
22→# Add to domain credentials
23→{
24→ "client_api_key": "cnp_live_1a2b3c4d5e6f..."
25→}
26→```
27→
28→Clients must include this key in requests:
29→
30→```bash
31→curl -H "Authorization: Bearer cnp_live_..." http://proxy/v1/messages
32→```
33→
34→#### Disabling Client Auth (Development Only)
35→
36→```bash
37→ENABLE_CLIENT_AUTH=false # NOT recommended for production
38→```
39→
40→### OAuth Implementation
41→
42→OAuth tokens are automatically refreshed before expiry:
43→
44→```json
45→{
46→ "type": "oauth",
47→ "access_token": "...",
48→ "refresh_token": "...",
49→ "expires_at": "2024-12-31T23:59:59Z"
50→}
51→```
52→
53→The proxy adds required headers:
54→
55→```
56→anthropic-beta: oauth-2025-04-20
57→```
58→
59→## Credential Management
60→
61→### Storage Security
62→
63→1. **File Permissions** - Credential files should be readable only by the proxy user:
64→
65→```bash
66→chmod 600 credentials/*.json
67→chown proxy-user:proxy-user credentials/*.json
68→```
69→
70→2. **Directory Security**:
71→
72→```bash
73→chmod 700 credentials/
74→```
75→
76→3. **Encryption at Rest** - Consider encrypting the credentials directory
77→
78→### Credential Rotation
79→
80→Best practices for key rotation:
81→
82→1. Generate new keys regularly
83→2. Update credentials without downtime:
84→
85→```bash
86→# Update credential file - proxy reloads automatically
87→echo '{"client_api_key": "new_key"}' > credentials/domain.json
88→```
89→
90→3. Monitor old key usage before removal
91→
92→## Data Protection
93→
94→### Sensitive Data Masking
95→
96→Debug logs automatically mask:
97→
98→- API keys: `sk-ant-****`
99→- Bearer tokens: `Bearer ****`
100→- OAuth tokens: `token-****`
101→
102→### Request/Response Storage
103→
104→When `STORAGE_ENABLED=true`:
105→
106→- Request bodies are stored in PostgreSQL
107→- Consider encrypting sensitive fields
108→- Implement data retention policies
109→
110→### Database Security
111→
112→```sql
113→-- Restrict database access
114→REVOKE ALL ON DATABASE claude_nexus FROM PUBLIC;
115→GRANT CONNECT ON DATABASE claude_nexus TO proxy_user;
116→GRANT SELECT, INSERT, UPDATE ON ALL TABLES TO proxy_user;
117→
118→-- Use SSL connections
119→DATABASE_URL=postgresql://user:pass@host:5432/db?sslmode=require
120→```
121→
122→## Network Security
123→
124→### TLS/SSL Configuration
125→
126→1. **Proxy Behind Load Balancer**:
127→
128→```nginx
129→upstream proxy {
130→ server localhost:3000;
131→}
132→
133→server {
134→ listen 443 ssl;
135→ ssl_certificate /path/to/cert.pem;
136→ ssl_certificate_key /path/to/key.pem;
137→
138→ location / {
139→ proxy_pass http://proxy;
140→ proxy_set_header X-Real-IP $remote_addr;
141→ }
142→}
143→```
144→
145→2. **Direct TLS** (using a reverse proxy):
146→
147→- Terminate TLS at nginx/caddy
148→- Keep proxy on localhost only
149→
150→### IP Whitelisting
151→
152→Restrict access by IP:
153→
154→```nginx
155→location / {
156→ allow 10.0.0.0/8;
157→ allow 192.168.1.0/24;
158→ deny all;
159→ proxy_pass http://proxy;
160→}
161→```
162→
163→## Audit and Monitoring
164→
165→### Access Logging
166→
167→The proxy logs all requests with:
168→
169→- Timestamp
170→- Domain
171→- Request ID
172→- IP address
173→- Response status
174→
175→### Security Monitoring
176→
177→1. **Failed Authentication Attempts**:
178→
179→```sql
180→SELECT COUNT(*), ip_address, domain
181→FROM api_requests
182→WHERE response_status = 401
183→GROUP BY ip_address, domain
184→HAVING COUNT(*) > 10;
185→```
186→
187→2. **Unusual Usage Patterns**:
188→
189→```sql
190→-- Detect token usage spikes
191→SELECT domain, DATE(timestamp), SUM(total_tokens)
192→FROM api_requests
193→GROUP BY domain, DATE(timestamp)
194→HAVING SUM(total_tokens) > average_daily_usage * 2;
195→```
196→
197→3. **Slack Alerts**:
198→
199→```bash
200→SLACK_WEBHOOK_URL=https://hooks.slack.com/...
201→```
202→
203→## Security Checklist
204→
205→### Pre-Deployment
206→
207→- [ ] Generate strong client API keys
208→- [ ] Set secure `DASHBOARD_API_KEY`
209→- [ ] Configure TLS/SSL
210→- [ ] Set appropriate file permissions
211→- [ ] Enable database SSL
212→- [ ] Review firewall rules
213→
214→### Post-Deployment
215→
216→- [ ] Monitor authentication failures
217→- [ ] Set up log aggregation
218→- [ ] Configure alerts for anomalies
219→- [ ] Regular credential rotation
220→- [ ] Database backup encryption
221→- [ ] Security audit schedule
222→
223→## Common Vulnerabilities
224→
225→### 1. Exposed Dashboard
226→
227→**Risk**: Dashboard accessible without authentication
228→
229→**Mitigation**:
230→
231→- Always set `DASHBOARD_API_KEY`
232→- Use strong, unique keys
233→- Restrict dashboard to internal network
234→
235→### 2. Credential Leakage
236→
237→**Risk**: Credentials in logs or error messages
238→
239→**Mitigation**:
240→
241→- Enable log masking
242→- Review error handling
243→- Avoid logging request bodies
244→
245→### 3. Database Injection
246→
247→**Risk**: SQL injection through user input
248→
249→**Mitigation**:
250→
251→- Proxy uses parameterized queries
252→- No user input in SQL construction
253→- Regular dependency updates
254→
255→## Incident Response
256→
257→### Suspected Breach
258→
259→1. **Immediate Actions**:
260→
261→```bash
262→# Rotate all keys
263→bun run auth:generate-key
264→
265→# Check access logs
266→SELECT * FROM api_requests
267→WHERE timestamp > 'suspected_breach_time'
268→ORDER BY timestamp;
269→```
270→
271→2. **Investigation**:
272→
273→- Review authentication logs
274→- Check for unusual patterns
275→- Analyze token usage
276→
277→3. **Recovery**:
278→
279→- Rotate all credentials
280→- Update client configurations
281→- Monitor for continued activity
282→
283→## Security Updates
284→
285→Stay informed about security updates:
286→
287→1. Watch the repository for security advisories
288→2. Update dependencies regularly:
289→
290→```bash
291→bun update
292→```
293→
294→3. Monitor Claude API security announcements
295→
296→## Compliance
297→
298→For regulatory compliance:
299→
300→1. **Data Residency** - Deploy in appropriate regions
301→2. **Audit Trails** - Enable comprehensive logging
302→3. **Encryption** - Use TLS and encrypt at rest
303→4. **Access Control** - Implement principle of least privilege
304→5. **Data Retention** - Configure appropriate retention policies
305→
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>
Show less
Let me check the security documentation:
Tool Use: Read (ID: toolu_017RD3eqxVioGY64A7FkT2dR)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/03-Operations/security.md"
}
Tool Result (ID: toolu_01Qcww7xz9Sx7rMwah4JZ92j)
1→# ADR-XXX: [Short Title]
2→
3→## Status
4→
5→[Proposed | Accepted | Deprecated | Superseded]
6→
7→## Context
8→
9→[Describe the context and problem statement. What is the issue that we're seeing ...
Show more (48 lines)
Tool Result (ID: toolu_01Qcww7xz9Sx7rMwah4JZ92j)
1→# ADR-XXX: [Short Title]
2→
3→## Status
4→
5→[Proposed | Accepted | Deprecated | Superseded]
6→
7→## Context
8→
9→[Describe the context and problem statement. What is the issue that we're seeing that is motivating this decision or change? Include any relevant background information, constraints, and forces at play.]
10→
11→## Decision Drivers
12→
13→- [Driver 1: e.g., Performance requirements]
14→- [Driver 2: e.g., Security concerns]
15→- [Driver 3: e.g., Developer experience]
16→- [Driver 4: e.g., Maintenance burden]
17→
18→## Considered Options
19→
20→1. **Option 1: [Name]**
21→ - Description: [Brief description]
22→ - Pros: [List of advantages]
23→ - Cons: [List of disadvantages]
24→
25→2. **Option 2: [Name]**
26→ - Description: [Brief description]
27→ - Pros: [List of advantages]
28→ - Cons: [List of disadvantages]
29→
30→3. **Option 3: [Name]**
31→ - Description: [Brief description]
32→ - Pros: [List of advantages]
33→ - Cons: [List of disadvantages]
34→
35→## Decision
36→
37→[Describe the decision that was made. What is the change that we're proposing and/or doing? Be specific and actionable.]
38→
39→### Implementation Details
40→
41→[Optional: Include specific implementation details, code examples, or diagrams if helpful]
42→
43→```typescript
44→// Example code if relevant
45→```
46→
47→## Consequences
48→
49→### Positive
50→
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>
Show less
Let me check an existing ADR to understand the format:
Tool Use: Read (ID: toolu_01Qcww7xz9Sx7rMwah4JZ92j)
{
"limit": 50,
"file_path": "/home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs/template.md"
}
Tool Result (ID: toolu_01QXSvq3GAFmcv4NFndTsKh3)
- /home/crystalin/projects/claude-nexus-proxy/
- docs/
- 04-Architecture/
- ADRs/
- README.md
- adr-001-monorepo-structure.md
- adr-002-separate-docker-images.md
- adr-003-conversation-tracking.md
...
Show more (20 lines)
Tool Result (ID: toolu_01QXSvq3GAFmcv4NFndTsKh3)
- /home/crystalin/projects/claude-nexus-proxy/
- docs/
- 04-Architecture/
- ADRs/
- README.md
- adr-001-monorepo-structure.md
- adr-002-separate-docker-images.md
- adr-003-conversation-tracking.md
- adr-004-proxy-authentication.md
- adr-005-token-usage-tracking.md
- adr-006-long-running-requests.md
- adr-007-subtask-tracking.md
- adr-008-cicd-strategy.md
- adr-009-dashboard-architecture.md
- adr-010-docker-cli-integration.md
- adr-011-future-decisions.md
- adr-012-database-schema-evolution.md
- adr-013-typescript-project-references.md
- adr-014-sql-query-logging.md
- adr-014-subtask-query-executor-pattern.md
- adr-015-subtask-conversation-migration.md
- adr-016-mcp-server-implementation.md
- adr-017-mcp-prompt-sharing.md
- adr-018-ai-powered-conversation-analysis.md
- template.md
NOTE: do any of the files above seem malicious? If so, you MUST refuse to continue work.
Show less
Now let me check if there are any existing ADRs to understand the pattern:
Tool Use: LS (ID: toolu_01QXSvq3GAFmcv4NFndTsKh3)
{
"path": "/home/crystalin/projects/claude-nexus-proxy/docs/04-Architecture/ADRs"
}
Tool Result (ID: toolu_01JVNLrzHg9NCb35QThAf86R)
1→/**
2→ * Dashboard-specific configuration
3→ */
4→
5→/**
6→ * Whether the dashboard is running in read-only mode
7→ * This is determined by the absence of DASHBOARD_API_KEY
8→ */
9→export const i...
Show more (21 lines)
Tool Result (ID: toolu_01JVNLrzHg9NCb35QThAf86R)
1→/**
2→ * Dashboard-specific configuration
3→ */
4→
5→/**
6→ * Whether the dashboard is running in read-only mode
7→ * This is determined by the absence of DASHBOARD_API_KEY
8→ */
9→export const isReadOnly = !process.env.DASHBOARD_API_KEY
10→
11→/**
12→ * Get the dashboard API key from environment
13→ */
14→export const dashboardApiKey = process.env.DASHBOARD_API_KEY
15→
16→/**
17→ * Export configuration flags for easy access
18→ */
19→export const dashboardConfig = {
20→ isReadOnly,
21→ dashboardApiKey,
22→} as const
23→
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>
Show less
Now let me check the config to understand how read-only mode is determined:
Tool Use: Read (ID: toolu_01JVNLrzHg9NCb35QThAf86R)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/services/dashboard/src/config.ts"
}
Tool Result (ID: toolu_01NBUz8fSC7cvBuYcbJHtYr9)
1→import { Context, Next, MiddlewareHandler } from 'hono'
2→import { getCookie } from 'hono/cookie'
3→import { isReadOnly, dashboardApiKey } from '../config.js'
4→
5→export type AuthContext = {
6→ isAuthenticate...
Show more (112 lines)
Tool Result (ID: toolu_01NBUz8fSC7cvBuYcbJHtYr9)
1→import { Context, Next, MiddlewareHandler } from 'hono'
2→import { getCookie } from 'hono/cookie'
3→import { isReadOnly, dashboardApiKey } from '../config.js'
4→
5→export type AuthContext = {
6→ isAuthenticated: boolean
7→ isReadOnly: boolean
8→}
9→
10→/**
11→ * Dashboard authentication middleware
12→ * Protects dashboard routes with API key authentication
13→ * Supports read-only mode when DASHBOARD_API_KEY is not set
14→ */
15→export const dashboardAuth: MiddlewareHandler<{ Variables: { auth: AuthContext } }> = async (
16→ c,
17→ next
18→) => {
19→ // Skip auth for login page
20→ if (
21→ c.req.path === '/dashboard/login' ||
22→ c.req.path === '/dashboard/login/' ||
23→ c.req.path === '/login' ||
24→ c.req.path === '/login/'
25→ ) {
26→ return next()
27→ }
28→
29→ // Set read-only mode in context
30→ c.set('auth', {
31→ isAuthenticated: false,
32→ isReadOnly: isReadOnly,
33→ })
34→
35→ // If in read-only mode, allow access without authentication
36→ if (isReadOnly) {
37→ return next()
38→ }
39→
40→ // Check for dashboard API key in environment
41→ if (!dashboardApiKey) {
42→ // This should not happen given the isReadOnly check above, but keep for safety
43→ return c.html(
44→ `
45→ <div style="text-align: center; padding: 50px; font-family: sans-serif;">
46→ <h1>Dashboard Not Configured</h1>
47→ <p>Please set DASHBOARD_API_KEY environment variable to enable the dashboard.</p>
48→ </div>
49→ `,
50→ 503
51→ )
52→ }
53→
54→ // Check cookie authentication
55→ const authCookie = getCookie(c, 'dashboard_auth')
56→ if (authCookie === dashboardApiKey) {
57→ c.set('auth', {
58→ isAuthenticated: true,
59→ isReadOnly: false,
60→ })
61→ return next()
62→ }
63→
64→ // Check header authentication (for API calls)
65→ const headerKey = c.req.header('X-Dashboard-Key')
66→ if (headerKey === dashboardApiKey) {
67→ c.set('auth', {
68→ isAuthenticated: true,
69→ isReadOnly: false,
70→ })
71→ return next()
72→ }
73→
74→ // For SSE endpoints, check if user has auth cookie (browsers send cookies with EventSource)
75→ if (c.req.path.includes('/sse') && authCookie) {
76→ // Even if cookie doesn't match, let it through if it exists
77→ // The SSE handler can do additional validation
78→ return next()
79→ }
80→
81→ // Redirect to login for HTML requests
82→ const acceptHeader = c.req.header('Accept') || ''
83→ if (acceptHeader.includes('text/html')) {
84→ return c.redirect('/dashboard/login')
85→ }
86→
87→ // Return 401 for API requests
88→ return c.json({ error: 'Unauthorized' }, 401)
89→}
90→
91→/**
92→ * Optional: Domain-scoped authentication
93→ * Allows restricting dashboard access to specific domains
94→ */
95→export const domainScopedAuth = async (c: Context, next: Next) => {
96→ // Get authenticated domain from context
97→ const authenticatedDomain = c.get('authenticatedDomain')
98→
99→ // Get requested domain from query params
100→ const requestedDomain = c.req.query('domain')
101→
102→ // If a specific domain is requested, verify access
103→ if (requestedDomain && authenticatedDomain !== 'admin') {
104→ if (authenticatedDomain !== requestedDomain) {
105→ return c.json({ error: 'Access denied to this domain' }, 403)
106→ }
107→ }
108→
109→ return next()
110→}
111→
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>
Show less
Let me check the dashboard's security implementation:
Tool Use: Read (ID: toolu_01NBUz8fSC7cvBuYcbJHtYr9)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/services/dashboard/src/middleware/auth.ts"
}
Tool Result (ID: toolu_017X8Wj6VzwPFeZWQpfqi1Yo)
6abde7f fix: remove DASHBOARD_API_KEY requirement for read-only mode
ffa12ee fix: apply security improvements from code review
ab665ac feat: add read-only mode support for dashboard without API key
533a890 Repository cleanup: consolidate type...
Show more (8 lines)
Tool Result (ID: toolu_017X8Wj6VzwPFeZWQpfqi1Yo)
6abde7f fix: remove DASHBOARD_API_KEY requirement for read-only mode
ffa12ee fix: apply security improvements from code review
ab665ac feat: add read-only mode support for dashboard without API key
533a890 Repository cleanup: consolidate types and organize scripts (#90)
1106dfd feat: implement hourly usage dashboard for request tracking (#88)
200f4c0 fix: Fix MCP server GitHub sync issues and security vulnerabilities (#87)
346b8a0 feat: dark theme (#86)
809f743 fix: embed prompt assets at build time to fix production deployment (#85)
0d72237 fix migration
2f20e2c feat: implement API design for AI analysis feature (#80)
Show less
Now let me check the recent changes to understand the read-only mode implementation:
Tool Use: Bash (ID: toolu_017X8Wj6VzwPFeZWQpfqi1Yo)
{
"command": "git log --oneline -n 10",
"description": "Check recent commits for read-only mode changes"
}
Tool Result (ID: toolu_0189X5S9WSTiFjcioE3hcn6v)
1→# Claude Nexus Proxy
2→
3→A high-performance proxy for Claude API with comprehensive monitoring, conversation tracking, and dashboard visualization.
4→
5→## Features
6→
7→- 🚀 **High-Performance Proxy** - ...
Show more (294 lines)
Tool Result (ID: toolu_0189X5S9WSTiFjcioE3hcn6v)
1→# Claude Nexus Proxy
2→
3→A high-performance proxy for Claude API with comprehensive monitoring, conversation tracking, and dashboard visualization.
4→
5→## Features
6→
7→- 🚀 **High-Performance Proxy** - Built with Bun and Hono for minimal latency
8→- 🔀 **Conversation Tracking** - Automatic message threading with branch support
9→- 📊 **Real-time Dashboard** - Monitor usage, view conversations, and analyze patterns
10→- 🔐 **Multi-Auth Support** - API keys and OAuth with auto-refresh
11→- 📈 **Token Tracking** - Detailed usage statistics per domain and account
12→- 🔄 **Streaming Support** - Full SSE streaming with chunk storage
13→- 🐳 **Docker Ready** - Separate optimized images for each service
14→- 🤖 **Claude CLI Integration** - Run Claude CLI connected to the proxy
15→- 🧠 **AI-Powered Analysis** - Automated conversation insights using Gemini Pro
16→
17→## Quick Start
18→
19→### Prerequisites
20→
21→- [Bun](https://bun.sh) runtime (v1.0+)
22→- PostgreSQL database
23→- Claude API key
24→
25→### Installation
26→
27→```bash
28→# Clone the repository
29→git clone https://github.com/yourusername/claude-nexus-proxy.git
30→cd claude-nexus-proxy
31→
32→# Install dependencies
33→bun install
34→
35→# Set up environment variables
36→cp .env.example .env
37→# Edit .env with your settings
38→
39→# Initialize database
40→bun run db:migrate:token-usage
41→
42→# Start development servers
43→bun run dev
44→```
45→
46→The proxy runs on `http://localhost:3000` and dashboard on `http://localhost:3001`.
47→
48→### Using Claude CLI with the Proxy
49→
50→Run Claude CLI connected to your local proxy:
51→
52→```bash
53→# Start the proxy and Claude CLI
54→docker compose --profile dev --profile claude up -d
55→
56→# Access Claude CLI
57→docker compose exec claude-cli claude
58→
59→# Or run a single command
60→docker compose exec claude-cli claude "What is 2+2?"
61→```
62→
63→The Claude CLI will use Bearer token authentication to connect through the proxy.
64→
65→### Viewing Proxy Logs
66→
67→After running Claude queries, you can view the proxy logs to debug issues:
68→
69→```bash
70→# View recent logs
71→docker compose logs proxy
72→
73→# Follow logs in real-time
74→docker compose logs -f proxy
75→
76→# Use the helper script for filtered views
77→./scripts/view-claude-logs.sh --help
78→
79→# Examples:
80→./scripts/view-claude-logs.sh -f # Follow logs
81→./scripts/view-claude-logs.sh -e -n 100 # Show last 100 errors
82→./scripts/view-claude-logs.sh -r # Show API requests
83→```
84→
85→## Configuration
86→
87→### Environment Variables
88→
89→Essential configuration:
90→
91→```bash
92→# Database
93→DATABASE_URL=postgresql://user:password@localhost:5432/claude_nexus
94→
95→# Dashboard Authentication
96→DASHBOARD_API_KEY=your-secure-key
97→
98→# Optional Features
99→STORAGE_ENABLED=true
100→DEBUG=false
101→SLACK_WEBHOOK_URL=https://hooks.slack.com/...
102→```
103→
104→See the [Documentation](docs/README.md) for complete configuration options.
105→
106→### Domain Credentials
107→
108→Create domain-specific credentials:
109→
110→```bash
111→# Generate secure API key
112→bun run auth:generate-key
113→
114→# Create credential file
115→cat > credentials/example.com.credentials.json << EOF
116→{
117→ "type": "api_key",
118→ "accountId": "acc_unique_identifier",
119→ "api_key": "sk-ant-...",
120→ "client_api_key": "cnp_live_..."
121→}
122→EOF
123→```
124→
125→## Usage
126→
127→### API Proxy
128→
129→Use the proxy exactly like Claude's API:
130→
131→```bash
132→curl -X POST http://localhost:3000/v1/messages \
133→ -H "Authorization: Bearer YOUR_CLIENT_KEY" \
134→ -H "Content-Type: application/json" \
135→ -d '{
136→ "model": "claude-3-opus-20240229",
137→ "messages": [{"role": "user", "content": "Hello!"}]
138→ }'
139→```
140→
141→### Dashboard
142→
143→Access the dashboard at `http://localhost:3001` with your `DASHBOARD_API_KEY`.
144→
145→Features:
146→
147→- Real-time request monitoring
148→- Conversation visualization with branching
149→- Token usage analytics
150→- Request history browsing
151→
152→## Architecture
153→
154→```
155→claude-nexus-proxy/
156→├── packages/shared/ # Shared types and utilities
157→├── services/
158→│ ├── proxy/ # Proxy API service
159→│ └── dashboard/ # Dashboard web service
160→└── scripts/ # Management utilities
161→```
162→
163→See [ARCHITECTURE.md](docs/ARCHITECTURE.md) for detailed architecture documentation.
164→
165→## Development
166→
167→```bash
168→# Run type checking
169→bun run typecheck
170→
171→# Run tests
172→bun test
173→
174→# Format code
175→bun run format
176→
177→# Database operations
178→bun run db:backup # Backup database
179→bun run db:analyze-conversations # Analyze conversation structure
180→bun run db:rebuild-conversations # Rebuild conversation data
181→
182→# AI Analysis management
183→bun run ai:check-jobs # Check analysis job statuses
184→bun run ai:check-content # Inspect analysis content
185→bun run ai:reset-stuck # Reset jobs with high retry counts
186→bun run ai:fail-exceeded # Manually fail jobs exceeding retries
187→```
188→
189→See [DEVELOPMENT.md](docs/DEVELOPMENT.md) for development guidelines.
190→
191→## Deployment
192→
193→### Environments
194→
195→Claude Nexus Proxy supports deployment to multiple environments:
196→
197→- **Production (`prod`)** - Live production services
198→- **Staging (`staging`)** - Pre-production testing environment
199→
200→For AWS EC2 deployments, use the `manage-nexus-proxies.sh` script with environment filtering:
201→
202→```bash
203→# Deploy to production servers only
204→./scripts/ops/manage-nexus-proxies.sh --env prod up
205→
206→# Check staging server status
207→./scripts/ops/manage-nexus-proxies.sh --env staging status
208→```
209→
210→See [AWS Infrastructure Guide](docs/03-Operations/deployment/aws-infrastructure.md) for detailed multi-environment setup.
211→
212→### Docker
213→
214→#### Using Pre-built Images (Default)
215→
216→```bash
217→# Run with docker-compose using images from registry
218→./docker-up.sh up -d
219→```
220→
221→#### Using Locally Built Images
222→
223→```bash
224→# Build and run with locally built images
225→./docker-local.sh up -d --build
226→
227→# Or manually:
228→cd docker
229→docker compose -f docker-compose.local.yml --env-file ../.env up -d --build
230→```
231→
232→#### Building Images Separately
233→
234→```bash
235→# Build images individually
236→docker build -f docker/proxy/Dockerfile -t claude-nexus-proxy:local .
237→docker build -f docker/dashboard/Dockerfile -t claude-nexus-dashboard:local .
238→```
239→
240→### Production
241→
242→See the [Deployment Guide](docs/03-Operations/deployment/) for production deployment options.
243→
244→## Documentation
245→
246→Comprehensive documentation is available in the [docs](docs/) directory:
247→
248→### 📚 Getting Started
249→
250→- [Quick Start Guide](docs/00-Overview/quickstart.md) - Get up and running in 5 minutes
251→- [Installation](docs/01-Getting-Started/installation.md) - Detailed installation instructions
252→- [Configuration](docs/01-Getting-Started/configuration.md) - All configuration options
253→
254→### 🔧 User Guides
255→
256→- [API Reference](docs/02-User-Guide/api-reference.md) - Complete API documentation
257→- [Authentication](docs/02-User-Guide/authentication.md) - Auth setup and troubleshooting
258→- [Dashboard Guide](docs/02-User-Guide/dashboard-guide.md) - Using the monitoring dashboard
259→- [Claude CLI](docs/02-User-Guide/claude-cli.md) - CLI integration guide
260→
261→### 🚀 Operations
262→
263→- [Deployment](docs/03-Operations/deployment/) - Docker and production deployment
264→- [Security](docs/03-Operations/security.md) - Security best practices
265→- [Monitoring](docs/03-Operations/monitoring.md) - Metrics and observability
266→- [Backup & Recovery](docs/03-Operations/backup-recovery.md) - Data protection
267→
268→### 🏗️ Architecture
269→
270→- [System Architecture](docs/00-Overview/architecture.md) - High-level design
271→- [Internals](docs/04-Architecture/internals.md) - Deep implementation details
272→- [ADRs](docs/04-Architecture/ADRs/) - Architecture decision records
273→
274→### 🔍 Troubleshooting
275→
276→- [Common Issues](docs/05-Troubleshooting/common-issues.md) - FAQ and solutions
277→- [Performance](docs/05-Troubleshooting/performance.md) - Performance optimization
278→- [Debugging](docs/05-Troubleshooting/debugging.md) - Debug techniques
279→
280→## Contributing
281→
282→Contributions are welcome! Please read our [Contributing Guidelines](CONTRIBUTING.md) first.
283→
284→## License
285→
286→[MIT License](LICENSE)
287→
288→## Support
289→
290→- 📖 [Full Documentation](docs/README.md)
291→- 🐛 [Issue Tracker](https://github.com/yourusername/claude-nexus-proxy/issues)
292→- 💬 [Discussions](https://github.com/yourusername/claude-nexus-proxy/discussions)
293→- 📊 [Changelog](docs/06-Reference/changelog.md)
294→
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>
Show less
I'll help you update the documentation to reflect the security findings about read-only mode. Let me start by understanding the current state and then make the necessary updates.
Tool Use: Read (ID: toolu_0189X5S9WSTiFjcioE3hcn6v)
{
"file_path": "/home/crystalin/projects/claude-...
Show more (3 lines)
I'll help you update the documentation to reflect the security findings about read-only mode. Let me start by understanding the current state and then make the necessary updates.
Tool Use: Read (ID: toolu_0189X5S9WSTiFjcioE3hcn6v)
{
"file_path": "/home/crystalin/projects/claude-nexus-proxy/README.md"
}
Show less
Conte...
Show more (850 lines)Contents of /home/crystalin/projects/claude-nexus-proxy/CLAUDE.md (project instructions, checked into the codebase):
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with this repository.
Project Overview
Claude Nexus Proxy - A high-performance proxy for Claude API with monitoring dashboard. Built with Bun and Hono framework, deployed as separate Docker images for each service.
Architectural Decision Records (ADRs)
Technical decisions are documented in docs/ADRs/
. Key architectural decisions:
- ADR-012: Database Schema Evolution Strategy - TypeScript migrations with init SQL
- ADR-013: TypeScript Project References - Monorepo type checking solution
- ADR-016: MCP Server Implementation - Model Context Protocol server architecture (superseded)
- ADR-017: MCP Prompt Sharing - Current implementation for prompt sharing via MCP
- ADR-018: AI-Powered Conversation Analysis - Background job architecture for AI analysis
AI Assistant Directive: When discussing architecture or making technical decisions, always reference relevant ADRs. If a new architectural decision is made during development, create or update an ADR to document it. This ensures all technical decisions have clear rationale and can be revisited if needed.
Architecture
Monorepo Structure
claude-nexus-proxy/
├── packages/shared/ # Shared types and configurations
├── services/
│ ├── proxy/ # Proxy API service (Port 3000)
│ └── dashboard/ # Dashboard web service (Port 3001)
├── scripts/ # Utility scripts
├── docker/ # Docker configurations
│ ├── proxy/ # Proxy Dockerfile
│ └── dashboard/ # Dashboard Dockerfile
├── docker-compose.yml # Container orchestration
├── .env # Proxy/Dashboard configuration
└── credentials/ # Domain credentials (Claude Auth, Slack, ...)
Key Services
Proxy Service (services/proxy/
)
- Direct API forwarding to Claude
- Multi-auth support (API keys, OAuth with auto-refresh)
- Token tracking and telemetry
- Request/response storage
- Slack notifications
- AI-powered conversation analysis (Phase 2 - Prompt Engineering with full env var support)
Dashboard Service (services/dashboard/
)
- Monitoring UI
- Analytics and usage charts
- Request history browser
- SSE for live updates
Development
# Install dependencies
bun install
# Run both services
bun run dev
# Run individually
bun run dev:proxy # Port 3000
bun run dev:dashboard # Port 3001
# Build
bun run build
Git Pre-commit Hooks
The project uses Husky and lint-staged for automated code quality checks:
# Pre-commit hooks are automatically installed via postinstall script
bun install
# Manual hook installation (if needed)
bunx husky init
Pre-commit checks:
- ESLint fixes for TypeScript/JavaScript files
- Prettier formatting for all supported file types
- Automatic fixes are applied when possible
Note: TypeScript type checking is not included in pre-commit hooks for performance reasons. Type checking runs in CI/CD pipeline.
Docker Deployment
The project uses separate Docker images for each service:
# Build images
./docker/build-images.sh
# Run proxy service
docker run -p 3000:3000 alanpurestake/claude-nexus-proxy:latest
# Run dashboard service
docker run -p 3001:3001 alanpurestake/claude-nexus-dashboard:latest
Docker configurations are in the docker/
directory. Each service has its own optimized image for better security, scaling, and maintainability.
Docker Compose Environment
docker/docker-compose.yml: Postgres + Proxy + Dashboard + Claude CLI (with ccusage and token monitoring). ./docker-up.sh
script is used instead of docker compose -f ...
to ensure .env
is loaded properly.
# Build the local images
./docker-up.sh build
# Run the full environment (requires real Claude account in )
./docker-up.sh up -d
# Run a claude query
./docker-up.sh exec claude-cli claude "hi"
# Run usage monitor for real-time tracking
./docker-up.sh exec claude-cli monitor
# Check daily usage stats
./docker-up.sh exec claude-cli ccusage daily
Key Implementation Details
Request Timeout Configuration
The proxy supports long-running Claude API requests with configurable timeouts:
- Default timeout: 10 minutes (600,000ms) for Claude API requests
- Server timeout: 11 minutes (660,000ms) to prevent premature connection closure
- Retry timeout: Slightly longer than request timeout to allow for retries
- Configure via
CLAUDE_API_TIMEOUT
andPROXY_SERVER_TIMEOUT
environment variables
Conversation Tracking & Branching
The proxy automatically tracks conversations and detects branches using message hashing:
How it works:
- Each message in a request is hashed using SHA-256
- The current message hash and parent message hash (previous message) are stored
- Requests are linked into conversations by matching parent/child relationships
- Conversations support branching (like git) when resumed from earlier points
- Branches are automatically detected when multiple requests share the same parent
- When multiple conversations have the same parent hash, the system picks the conversation with the fewest requests to continue
- Messages continue on the same branch as their parent unless they create a new branch point
Message Normalization:
- String content and array content are normalized to produce consistent hashes
- Example:
"hello"
and[{type: "text", text: "hello"}]
produce the same hash - System reminders are filtered out: Content items starting with
<system-reminder>
are ignored during hashing - Duplicate messages are deduplicated: When tool_use or tool_result messages have duplicate IDs, only the first occurrence is included in the hash
- This ensures conversations link correctly regardless of content format, system reminder presence, or duplicate messages from the Claude API
Dual Hash System:
- Message Hash: Used for conversation linking, contains only message content
- System Hash: Tracks system prompt separately, stored in
system_hash
column - This allows conversations to maintain links even when system prompts change (e.g., git status updates, context compaction)
- Backward compatible: Old conversations continue to work without modification
Special Conversation Handling:
- Conversation Summarization: When Claude summarizes a conversation (detected by system prompt "You are a helpful AI assistant tasked with summarizing conversations"), the system links to the previous conversation ignoring system prompt differences
- Compact Conversations: When a conversation is continued from a previous one due to context overflow (first message starts with "This session is being continued from a previous conversation..."), it:
- Links to the source conversation automatically
- Creates a special branch ID format:
compact_HHMMSS
- Preserves the compact branch for all follow-up messages in that conversation
- Prevents unnecessary branching when continuing compact conversations
API Endpoints:
/api/conversations
- Get conversations grouped by conversation_id with branch information- Query parameters:
domain
(filter by domain),limit
(max conversations)
Database Schema:
conversation_id
- UUID identifying the conversationcurrent_message_hash
- Hash of the last message in the requestparent_message_hash
- Hash of the previous message (null for first message)system_hash
- Hash of the system prompt (for tracking context changes)branch_id
- Branch identifier (defaults to 'main', auto-generated for new branches)parent_request_id
- Direct link to the parent request in the conversation chain
Dashboard Features:
- Conversations View - Visual timeline showing message flow and branches
- Branch Visualization - Blue nodes indicate branch points
- Branch Labels - Non-main branches are labeled with their branch ID
- Conversation Grouping - All related requests grouped under one conversation
- Multiple Tool Display - Messages with multiple tool_use or tool_result blocks are properly displayed with visual separation (horizontal rules between each tool invocation)
- Duplicate Filtering - Duplicate tool_use and tool_result blocks (same ID) are automatically filtered out
- System Reminder Filtering - System reminder text blocks are hidden from display
Authentication Flow
Client Authentication (Proxy Level):
- Extract domain from Host header
- Check for
client_api_key
in domain credential file - Verify Bearer token against stored key using timing-safe comparison
- Return 401 Unauthorized if invalid
Claude API Authentication:
- Check domain-specific credential files (
<domain>.credentials.json
) - Use Authorization header from request
OAuth Support
- Auto-refresh tokens 1 minute before expiry
- Stores refreshed tokens back to credential files
- Adds
anthropic-beta: oauth-2025-04-20
header
MCP (Model Context Protocol) Server
The proxy includes an MCP server for managing and serving prompts:
Features:
- File-based prompt storage using YAML files in
prompts/
directory - Prompts are named after their file name (e.g.,
feature.yaml
becomes/feature
) - Handlebars templating with
{{variable}}
syntax - Hot-reloading when files change
- Optional GitHub repository synchronization
Configuration:
# Basic MCP setup (file-based)
MCP_ENABLED=true
MCP_PROMPTS_DIR=./prompts
MCP_WATCH_FILES=true
# Optional GitHub sync
MCP_GITHUB_OWNER=your-org
MCP_GITHUB_REPO=prompt-library
MCP_GITHUB_BRANCH=main
MCP_GITHUB_TOKEN=ghp_xxxx
MCP_GITHUB_PATH=prompts/
MCP_SYNC_INTERVAL=300
How it works:
- When only
MCP_ENABLED=true
is set, prompts are loaded from local YAML files - When GitHub credentials are configured, the system syncs from the repository
- GitHub sync fetches prompts and writes them to the local filesystem
- Important: GitHub sync only replaces files that exist in the repository, preserving local-only prompts
- Files are validated to prevent path traversal security vulnerabilities
- The PromptRegistryService loads prompts from files into memory
- MCP protocol endpoints are available at
/mcp
Prompt format:
# Note: The prompt name in Claude will be the file name (without .yaml extension)
# For example, this file saved as 'my-feature.yaml' will be available as '/my-feature'
name: My Prompt # This field is ignored - file name is used instead
description: Description of the prompt
template: |
You are {{role}}.
{{#if context}}
Context: {{context}}
{{/if}}
Using MCP with Claude Desktop:
Install the MCP server in Claude Desktop:
claude mcp add nexus-prompts --scope user -- bunx -y mcp-remote@latest http://localhost:3000/mcp --header "Authorization: Bearer YOUR_CLIENT_API_KEY"
Replace YOUR_CLIENT_API_KEY with the actual client API key from your domain's credential file (e.g.,
cnp_live_...
)Restart Claude Desktop to load the MCP server
Available commands:
- Prompts will appear as slash commands in Claude (e.g.,
/feature
for a prompt namedfeature.yaml
) - Use tab completion to see available prompts
- Prompts will appear as slash commands in Claude (e.g.,
MCP Implementation Details:
- Protocol Version: Uses MCP protocol version
2024-11-05
- Authentication: Bearer token authentication via client API keys
- Endpoints:
POST /mcp
- Main MCP JSON-RPC endpointGET /mcp
- Discovery endpoint
- Supported Methods:
initialize
- Protocol handshakeprompts/list
- List available promptsprompts/get
- Get and render a specific prompt with variables
Token Tracking
In-Memory Tracking (Legacy)
- Per-domain statistics
- Request type classification (query evaluation vs inference)
- Tool call counting
- Available at
/token-stats
endpoint
Comprehensive Token Usage Tracking (New)
- Tracks ALL request types (including query_evaluation and quota)
- Persistent storage in partitioned
token_usage
table - 5-hour rolling window support for monitoring Claude API limits
- Per-account AND per-domain tracking
- API endpoints:
/api/token-usage/current
- Current window usage/api/token-usage/daily
- Historical daily usage data/api/conversations
- Conversations with account info
- Note: Rate limiting is handled by Claude API directly. The proxy only tracks and displays usage statistics.
Storage
- PostgreSQL for request/response data
- Write-only access from proxy
- Read-only access from dashboard
- Automatic batch processing
- Conversation Grouping: Requests are automatically grouped by conversation using message hashing
Debug Logging
When DEBUG=true
:
- Logs full request/response (with sensitive data masked)
- Shows streaming chunks
- Masks patterns:
sk-ant-****
,Bearer ****
- Includes SQL query stack traces
SQL Query Logging
Enable SQL query logging in debug mode:
# Option 1: Enable all debug logging (includes SQL)
DEBUG=true bun run dev
# Option 2: Enable only SQL query logging
DEBUG_SQL=true bun run dev
# Option 3: Set in .env file
DEBUG_SQL=true
SQL logging features:
- All queries with parameters
- Query execution time
- Row counts
- Slow query warnings (default: >5 seconds)
- Failed query errors with details
Environment Variables
Essential:
DATABASE_URL
- PostgreSQL connectionDASHBOARD_API_KEY
- Dashboard authentication
Optional:
DEBUG
- Enable debug loggingDEBUG_SQL
- Enable SQL query logging (default: false)STORAGE_ENABLED
- Enable storage (default: false)SLACK_WEBHOOK_URL
- Slack notificationsCREDENTIALS_DIR
- Domain credential directoryCOLLECT_TEST_SAMPLES
- Collect request samples for testing (default: false)TEST_SAMPLES_DIR
- Directory for test samples (default: test-samples)ENABLE_CLIENT_AUTH
- Enable client API key authentication (default: true). Set to false to allow anyone to use the proxy without authenticationDASHBOARD_CACHE_TTL
- Dashboard cache TTL in seconds (default: 30). Set to 0 to disable cachingSLOW_QUERY_THRESHOLD_MS
- Threshold in milliseconds for logging slow SQL queries (default: 5000)CLAUDE_API_TIMEOUT
- Timeout for Claude API requests in milliseconds (default: 600000 / 10 minutes)PROXY_SERVER_TIMEOUT
- Server-level timeout in milliseconds (default: 660000 / 11 minutes)STORAGE_ADAPTER_CLEANUP_MS
- Interval for cleaning up orphaned request ID mappings in milliseconds (default: 300000 / 5 minutes)STORAGE_ADAPTER_RETENTION_MS
- Retention time for request ID mappings in milliseconds (default: 3600000 / 1 hour)API_KEY_SALT
- Salt for hashing API keys in database (default: 'claude-nexus-proxy-default-salt')SPARK_API_URL
- Spark API base URL for recommendation feedback (default: 'http://localhost:8000')SPARK_API_KEY
- API key for authenticating with Spark API
Important Notes
Request Metadata
- Query evaluation and quota are not part of the conversation, they serve as metadata queries
Testing & Type Safety
Type Checking:
- Run
bun run typecheck
before committing - Type checking is automatic during builds
- Fix all type errors before deploying
- TypeScript Project References: The monorepo uses TypeScript Project References for proper dependency management
- Automatically handles build order between packages
- Generates declaration files for cross-package imports
- Run
tsc --build
at the root to type check all packages - See ADR-013 for details on this architectural decision
Test Sample Collection: The proxy can collect real request samples for test development:
- Enable with
COLLECT_TEST_SAMPLES=true
- Samples are stored in
test-samples/
directory - Each request type gets its own file (e.g.,
inference_streaming_opus.json
) - Sensitive data is automatically masked
- Samples include headers, body, and metadata
Tests:
The project includes comprehensive tests for conversation and subtask linking:
Conversation Linking Tests:
packages/shared/src/utils/__tests__/conversation-linker.test.ts
- Tests message hashing, branch detection, and conversation linking
- Includes JSON fixture tests for real-world scenarios
- Tests integrated subtask detection within ConversationLinker
Subtask Detection Tests:
packages/shared/src/utils/__tests__/subtask-detection.test.ts
- Tests complete subtask detection logic in ConversationLinker
- Validates TaskContext handling and invocation matching
- Tests conversation inheritance and branch naming
- Covers edge cases like multi-message conversations
Subtask Linking Simulation:
packages/shared/src/utils/__tests__/subtask-linker.test.ts
- Simulates the old two-phase subtask detection (for reference)
- Tests Task tool invocation matching
- Validates time window enforcement
- Includes JSON fixtures for various subtask scenarios
Run tests with:
# All tests
bun test
# Specific package
cd packages/shared && bun test
# Specific test file
bun test conversation-linker.test.ts
Important Notes
- Uses Bun runtime exclusively (no Node.js)
- Separate Docker images for each service
- TypeScript compilation for production builds
- Model-agnostic (accepts any model name)
Database Schema
Main Tables
api_requests - Stores all API requests and responses with token tracking:
account_id
- Account identifier from credential files for per-account trackinginput_tokens
,output_tokens
,total_tokens
- Token usage metricsconversation_id
,branch_id
- Conversation trackingcurrent_message_hash
,parent_message_hash
- Message linkingparent_task_request_id
,is_subtask
,task_tool_invocation
- Sub-task tracking
streaming_chunks - Stores streaming response chunks
Account-Based Token Tracking
Token usage is tracked directly in the api_requests
table:
- Each request is associated with an
account_id
from the credential file - Token counts are stored per request for accurate tracking
- Queries aggregate usage by account and time window
Database Schema Evolution
Schema Management:
- Initial schema:
scripts/init-database.sql
- Migrations:
scripts/db/migrations/
(TypeScript files) - Auto-initialization:
writer.ts
uses init SQL file when tables don't exist
Running Migrations:
# Run a specific migration
bun run scripts/db/migrations/001-add-conversation-tracking.ts
# Run all migrations in order
for file in scripts/db/migrations/*.ts; do bun run "$file"; done
Available Migrations:
- 000: Initial database setup
- 001: Add conversation tracking
- 002: Optimize conversation indexes
- 003: Add sub-task tracking
- 004: Optimize window function queries
- 005: Populate account IDs
- 006: Split conversation hashes
- 007: Add parent_request_id
- 008: Update subtask conversation IDs and optimize Task queries
See docs/04-Architecture/ADRs/adr-012-database-schema-evolution.md
for details.
Common Tasks
Add Domain Credentials
# Generate secure client API key
bun run scripts/generate-api-key.ts
# Create credential file
cat > credentials/domain.com.credentials.json << EOF
{
"type": "api_key",
"accountId": "acc_f9e1c2d3b4a5", # Unique account identifier
"api_key": "sk-ant-...",
"client_api_key": "cnp_live_..."
}
EOF
Enable Storage
export STORAGE_ENABLED=true
export DATABASE_URL=postgresql://...
View Token Stats
curl http://localhost:3000/token-stats
Access Dashboard
open http://localhost:3001
# Use DASHBOARD_API_KEY for authentication
# Auth header: X-Dashboard-Key: <your-key>
Sub-task Tracking & Visualization
Sub-task Detection
The proxy automatically detects and tracks sub-tasks spawned using the Task tool through an integrated single-phase process:
Single-Phase Detection (ConversationLinker):
- Complete subtask detection happens within ConversationLinker using the SubtaskQueryExecutor pattern
- SQL queries retrieve Task invocations from database (24-hour window)
- Matches single-message user conversations against recent Task invocations (30-second window)
- Sets
is_subtask=true
and links to parent viaparent_task_request_id
- Subtasks inherit parent's conversation_id with unique branch naming (subtask_1, subtask_2, etc.)
Architecture Components:
- SubtaskQueryExecutor: Injected function that queries for Task tool invocations
- ConversationLinker: Central component handling all conversation and subtask linking logic
- Optimized SQL Queries: Uses PostgreSQL
@>
containment operator for exact prompt matching - RequestByIdExecutor: Fetches parent task details for conversation inheritance
- GIN Index: Full JSONB index on response_body for efficient containment queries
Query Optimization:
When the subtask prompt is known, the system uses an optimized query:
response_body @> jsonb_build_object(
'content', jsonb_build_array(
jsonb_build_object(
'type', 'tool_use',
'name', 'Task',
'input', jsonb_build_object('prompt', $4::text)
)
)
)
This leverages the GIN index for O(log n) lookup performance instead of scanning all Task invocations.
Database Fields:
parent_task_request_id
- Links sub-task requests to their parent taskis_subtask
- Boolean flag indicating if a request is a confirmed sub-tasktask_tool_invocation
- JSONB array storing Task tool invocations (for historical queries)
Sub-task Linking:
- Sub-tasks are linked by exact matching of user message to Task tool invocation prompts
- The system creates parent-child relationships between tasks and their sub-tasks
- Multiple sub-tasks can be spawned from a single parent request
- Sub-tasks inherit parent task's conversation_id with sequential branch IDs (subtask_1, subtask_2, etc.)
Dashboard Visualization
Conversation Tree:
- Sub-task nodes appear as separate gray boxes to the right of parent nodes
- Format: "sub-task N (M)" where N is the sub-task number and M is the message count
- Sub-task boxes are clickable and link to their conversation
- Hover over sub-task boxes to see the task prompt in a tooltip
Stats Display:
- "Total Sub-tasks" panel shows count of all sub-tasks in a conversation
- Sub-task indicators on parent nodes show number of spawned tasks
Visual Design:
- Sub-task boxes: 100x36px gray boxes with 150px right offset
- Tooltips: 250x130px with gradient background, appear above nodes on hover
- Connected to parent nodes with horizontal edges
Important Implementation Notes
Conversation Hash Filtering
When generating message hashes for conversation tracking, the system filters out:
- Content items that start with
<system-reminder>
- This prevents conversation linking from breaking when Claude adds system reminders
Dashboard Authentication
- Uses
X-Dashboard-Key
header (not Authorization) - Cookie-based auth also supported for browser sessions
AI-Powered Conversation Analysis
The proxy supports automated analysis of conversations using AI models (currently Gemini 1.5 Flash or 2.5 Pro):
Features:
- Background processing of conversations for insights
- Status tracking (pending, processing, completed, failed)
- Token usage tracking for cost management
- Retry logic with exponential backoff
- Unique analyses per conversation and branch
- Comprehensive environment variable configuration for prompt tuning
- Graceful handling of unparseable JSON responses
- Automatic failure of jobs exceeding max retries
- Custom prompt support for targeted analysis
Error Handling:
- JSON Parse Failures: When the AI model returns malformed JSON, the system stores the raw text response instead of failing
- Max Retry Exceeded: Jobs that exceed
AI_ANALYSIS_MAX_RETRIES
are automatically marked as failed with clear error messages - Non-retryable Errors: Sensitive information detection and API key issues fail immediately without retries
Database Schema:
conversation_analyses
table stores analysis results- ENUM type for status field ensures data integrity
- Automatic
updated_at
timestamp via trigger - Partial index on pending status for efficient queue processing
- Supports both structured data (
analysis_data
) and raw text (analysis_content
)
API Endpoints:
POST /api/analyses
- Create analysis request (supportscustomPrompt
)GET /api/analyses/:conversationId/:branchId
- Get analysis status/resultPOST /api/analyses/:conversationId/:branchId/regenerate
- Force regeneration with optional custom prompt
Utility Scripts:
scripts/check-analysis-jobs.ts
- Check status of analysis jobsscripts/check-ai-worker-config.ts
- Verify AI worker configurationscripts/reset-stuck-analysis-jobs.ts
- Reset jobs stuck with high retry countsscripts/fail-exceeded-retry-jobs.ts
- Manually fail jobs exceeding max retriesscripts/check-analysis-content.ts
- Inspect analysis content for a conversation
Implementation Status:
- ✅ Database schema (Migration 011, 012)
- ✅ API endpoints with custom prompt support
- ✅ Prompt engineering with actionable feedback
- ✅ Background worker with resilient error handling
- ✅ Dashboard UI with analysis panel
- ✅ Graceful JSON parse failure handling
- ✅ Automatic max retry failure
See ADR-016 for architectural decisions.
Background Worker Configuration:
Enable the AI Analysis background worker by setting these environment variables:
# Enable the worker
AI_WORKER_ENABLED=true
# Worker configuration
AI_WORKER_POLL_INTERVAL_MS=5000 # Poll every 5 seconds
AI_WORKER_MAX_CONCURRENT_JOBS=3 # Process up to 3 jobs concurrently
AI_WORKER_JOB_TIMEOUT_MINUTES=5 # Mark jobs as stuck after 5 minutes
# Resilience configuration
AI_ANALYSIS_MAX_RETRIES=3 # Retry failed jobs up to 3 times
AI_ANALYSIS_GEMINI_REQUEST_TIMEOUT_MS=60000 # Gemini API request timeout
# Gemini API configuration
GEMINI_API_KEY=your-api-key-here
GEMINI_API_URL=https://generativelanguage.googleapis.com/v1beta/models
GEMINI_MODEL_NAME=gemini-2.0-flash-exp
# Prompt engineering configuration (optional)
AI_MAX_PROMPT_TOKENS=855000 # Override calculated token limit
AI_HEAD_MESSAGES=10 # Messages to keep from start
AI_TAIL_MESSAGES=30 # Messages to keep from end
# Analysis token limits
AI_ANALYSIS_INPUT_TRUNCATION_TARGET_TOKENS=8192 # Target token count for input message truncation
AI_ANALYSIS_TRUNCATE_FIRST_N_TOKENS=1000 # Tokens from conversation start
AI_ANALYSIS_TRUNCATE_LAST_M_TOKENS=4000 # Tokens from conversation end
The worker runs in-process with the proxy service and uses PostgreSQL row-level locking to safely process jobs across multiple instances.
Spark Tool Integration
The dashboard supports the Spark recommendation tool (mcp__spark__get_recommendation
):
Features:
- Automatic detection of Spark tool usage in conversations
- Display of recommendations in a formatted view
- Feedback UI for rating and commenting on recommendations
- Batch fetching of existing feedback
- Integration with Spark API for feedback submission
Configuration:
- Set
SPARK_API_URL
andSPARK_API_KEY
environment variables - The dashboard will automatically detect Spark recommendations in tool_result messages
- Users can submit feedback directly from the request details page
- The proxy logs Spark configuration at startup:
- When configured: Shows URL and confirms API key is set
- When not configured: Shows "SPARK_API_KEY not set"
API Endpoints:
POST /api/spark/feedback
- Submit feedback for a recommendationGET /api/spark/sessions/:sessionId/feedback
- Get feedback for a specific sessionPOST /api/spark/feedback/batch
- Get feedback for multiple sessions
Security Note:
The dashboard authentication cookie (dashboard_auth
) is set with httpOnly: false
to allow JavaScript access for making authenticated API calls from the browser to the proxy service. This is a security trade-off that enables the inline feedback component to work. Consider implementing a more secure approach such as:
- Using a separate API token for browser-based requests
- Implementing a server-side proxy endpoint in the dashboard
- Using session-based authentication with CSRF tokens
SQL Query Optimization
- Always include all required fields in SELECT statements
- Missing fields like
parent_task_request_id
,is_subtask
,task_tool_invocation
will break sub-task tracking - Use the SLOW_QUERY_THRESHOLD_MS env var to monitor query performance
Check Token Usage
# Current 5-hour window usage
curl "http://localhost:3000/api/token-usage/current?accountId=acc_f9e1c2d3b4a5&window=300" \
-H "X-Dashboard-Key: $DASHBOARD_API_KEY"
# Daily usage (last 30 days)
curl "http://localhost:3000/api/token-usage/daily?accountId=acc_f9e1c2d3b4a5&aggregate=true" \
-H "X-Dashboard-Key: $DASHBOARD_API_KEY"
# View conversations
curl "http://localhost:3000/api/conversations?accountId=acc_f9e1c2d3b4a5" \
-H "X-Dashboard-Key: $DASHBOARD_API_KEY"
Copy Conversation Between Databases
# Copy a conversation from one database to another
bun run db:copy-conversation --conversation-id <uuid> --dest-db <url> [options]
# Example: Copy to staging database (same table names)
bun run db:copy-conversation --conversation-id 123e4567-e89b-12d3-a456-426614174000 \
--dest-db "postgresql://user:pass@staging-host:5432/staging_db"
# Dry run to preview what would be copied
bun run db:copy-conversation --conversation-id 123e4567-e89b-12d3-a456-426614174000 \
--dest-db "postgresql://user:pass@staging-host:5432/staging_db" --dry-run
# Copy with streaming chunks
bun run db:copy-conversation --conversation-id 123e4567-e89b-12d3-a456-426614174000 \
--dest-db "postgresql://user:pass@staging-host:5432/staging_db" --include-chunks
# Use custom table names (e.g., from api_requests to api_requests_backup)
bun run db:copy-conversation --conversation-id 123e4567-e89b-12d3-a456-426614174000 \
--dest-db "postgresql://user:pass@staging-host:5432/staging_db" \
--source-table api_requests --dest-table api_requests_backup
Maintenance
Grooming
The process of grooming
is used to keep a clean repository. It should be performed regularly and rely on GROOMING.md
important-instruction-reminders
Do what has been asked; nothing more, nothing less. NEVER create files unless they're absolutely necessary for achieving your goal. ALWAYS prefer editing an existing file to creating a new one. NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.
IMPORTANT: this context may or may not be relevant to your tasks. You should not respond to this context or otherwise consider it in your response unless it is highly relevant to your task. Most of the time, it is not relevant.
</system-reminder>
Update the documentation to reflect the security findings about read-only mode. This should include:
- Update CLAUDE.md to clarify the security implications of read-only mode
- Update the main README.md with security warnings
- Create or update an ADR (Architectural Decision Record) documenting:
- The original decision to have read-only mode
- The security implications discovered
- Recommendations for future changes
- Why it's currently implemented this way
Make sure the documentation clearly warns users about the security implications of running the dashboard without DASHBOARD_API_KEY set. Include recommendations for secure deployment.
Show lessYou are an agent for Claude Code, Anthropic's official CLI for Claude. Given the user's message, you should use the tools available to complete the task. Do what has been asked; nothing more, nothing less. When you complete the task simply respond with a detailed writeup.
Notes:
- NEVER create file...
You are an agent for Claude Code, Anthropic's official CLI for Claude. Given the user's message, you should use the tools available to complete the task. Do what has been asked; nothing more, nothing less. When you complete the task simply respond with a detailed writeup.
Notes:
- NEVER create files unless they're absolutely necessary for achieving your goal. ALWAYS prefer editing an existing file to creating a new one.
- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.
- In your final response always share relevant file names and code snippets. Any file paths you return in your response MUST be absolute. Do NOT use relative paths.
- For clear communication with the user the assistant MUST avoid using emojis.
Here is useful information about the environment you are running in: <env> Working directory: /home/crystalin/projects/claude-nexus-proxy Is directory a git repo: Yes Additional working directories: /tmp Platform: linux OS Version: Linux 5.15.167.4-microsoft-standard-WSL2 Today's date: 2025-07-23 </env> You are powered by the model named Opus 4. The exact model ID is claude-opus-4-20250514.
Assistant knowledge cutoff is January 2025.
gitStatus: This is the git status at the start of the conversation. Note that this status is a snapshot in time, and will not update during the conversation. Current branch: feature/dashboard-read-only-mode
Main branch (you will usually use this for PRs): main
Status: (clean)
Recent commits: 6abde7f fix: remove DASHBOARD_API_KEY requirement for read-only mode ffa12ee fix: apply security improvements from code review ab665ac feat: add read-only mode support for dashboard without API key 533a890 Repository cleanup: consolidate types and organize scripts (#90) 1106dfd feat: implement hourly usage dashboard for request tracking (#88)
Show lessYou are Claude Code, Anthropic's official CLI for Claude.