# Sequential Thinking Age Wrapper - Deployment Guide ## Overview This guide covers deploying the Sequential Thinking Age-Encrypted Wrapper to Docker Swarm with full security enabled. ## Prerequisites - Docker Swarm cluster initialized - `chorus-overlay` network created - Traefik reverse proxy configured - KACHING authentication service available ## Architecture ``` Client → Traefik (HTTPS) → SeqThink Wrapper (JWT + Age Encryption) → MCP Server (loopback) ``` **Security Layers**: 1. **TLS**: Traefik terminates HTTPS 2. **JWT**: KACHING token validation 3. **Age Encryption**: End-to-end encrypted payloads ## Step 1: Generate Age Keys Generate a key pair for encryption: ```bash # Generate age identity (private key) age-keygen -o seqthink_age.key # Extract recipient (public key) age-keygen -y seqthink_age.key > seqthink_age.pub ``` **Output**: ``` seqthink_age.key: # created: 2025-10-13T08:00:00+11:00 # public key: age1abcd... AGE-SECRET-KEY-1ABCD... seqthink_age.pub: age1abcd... ``` ## Step 2: Create Docker Secrets Store the age keys as Docker secrets: ```bash # Create identity secret docker secret create seqthink_age_identity seqthink_age.key # Create recipient secret docker secret create seqthink_age_recipients seqthink_age.pub # Verify secrets docker secret ls | grep seqthink ``` **Expected Output**: ``` seqthink_age_identity seqthink_age_recipients ``` ## Step 3: Build Docker Image Build the wrapper image: ```bash cd /home/tony/chorus/project-queues/active/CHORUS # Build image docker build -f deploy/seqthink/Dockerfile -t anthonyrawlins/seqthink-wrapper:latest . # Tag with version docker tag anthonyrawlins/seqthink-wrapper:latest anthonyrawlins/seqthink-wrapper:0.1.0 # Push to registry docker push anthonyrawlins/seqthink-wrapper:latest docker push anthonyrawlins/seqthink-wrapper:0.1.0 ``` ## Step 4: Deploy to Swarm Deploy the service: ```bash cd deploy/seqthink # Deploy stack docker stack deploy -c docker-compose.swarm.yml seqthink # Check service status docker service ls | grep seqthink # Check logs docker service logs -f seqthink_seqthink-wrapper ``` **Expected Log Output**: ``` 🚀 Starting Sequential Thinking Age Wrapper ⏳ Waiting for MCP server... ✅ MCP server ready Policy enforcement enabled jwks_url: https://auth.kaching.services/jwks required_scope: sequentialthinking.run Fetching JWKS JWKS cached successfully key_count: 2 Encryption enabled - using encrypted endpoint 🔐 Wrapper listening addr: :8443 encryption_enabled: true policy_enabled: true ``` ## Step 5: Verify Deployment Check service health: ```bash # Check replicas docker service ps seqthink_seqthink-wrapper # Test health endpoint curl -f http://localhost:8443/health # Expected: OK # Test readiness curl -f http://localhost:8443/ready # Expected: READY # Check metrics curl http://localhost:8443/metrics | grep seqthink ``` ## Step 6: Test with JWT Token Get a KACHING JWT token and test the API: ```bash # Set your JWT token export JWT_TOKEN="eyJhbGciOiJSUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ..." # Test unauthorized (should fail) curl -X POST https://seqthink.chorus.services/mcp/tool \ -H "Content-Type: application/age" \ -d "test" # Expected: 401 Unauthorized # Test authorized (should succeed) curl -X POST https://seqthink.chorus.services/mcp/tool \ -H "Authorization: Bearer $JWT_TOKEN" \ -H "Content-Type: application/age" \ -d "$(echo '{"tool":"test","payload":{}}' | age -r $(cat seqthink_age.pub))" \ --output encrypted_response.age # Decrypt response age -d -i seqthink_age.key encrypted_response.age ``` ## Configuration Reference ### Environment Variables | Variable | Required | Default | Description | |----------|----------|---------|-------------| | `PORT` | No | `8443` | HTTP server port | | `MCP_LOCAL` | No | `http://127.0.0.1:8000` | MCP server URL (loopback) | | `LOG_LEVEL` | No | `info` | Logging level (debug, info, warn, error) | | `MAX_BODY_MB` | No | `4` | Maximum request body size in MB | | `AGE_IDENT_PATH` | **Yes** | - | Path to age identity (private key) | | `AGE_RECIPS_PATH` | **Yes** | - | Path to age recipients (public key) | | `KACHING_JWKS_URL` | **Yes** | - | KACHING JWKS endpoint | | `REQUIRED_SCOPE` | **Yes** | `sequentialthinking.run` | Required JWT scope | ### Docker Secrets | Secret Name | Purpose | Content | |-------------|---------|---------| | `seqthink_age_identity` | Age private key | `AGE-SECRET-KEY-1...` | | `seqthink_age_recipients` | Age public key | `age1...` | ### Network Ports | Port | Protocol | Purpose | |------|----------|---------| | `8443` | HTTP | Wrapper API | | `8000` | HTTP | MCP server (internal loopback only) | ## Scaling Scale the service: ```bash # Scale up docker service scale seqthink_seqthink-wrapper=5 # Scale down docker service scale seqthink_seqthink-wrapper=2 ``` ## Updates Rolling update: ```bash # Build new version docker build -f deploy/seqthink/Dockerfile -t anthonyrawlins/seqthink-wrapper:0.2.0 . docker push anthonyrawlins/seqthink-wrapper:0.2.0 # Update service docker service update \ --image anthonyrawlins/seqthink-wrapper:0.2.0 \ seqthink_seqthink-wrapper # Monitor rollout docker service ps seqthink_seqthink-wrapper ``` ## Rollback If update fails: ```bash # Automatic rollback (configured in stack) # Or manual rollback: docker service rollback seqthink_seqthink-wrapper ``` ## Monitoring ### Prometheus Metrics Available at `http://localhost:8443/metrics`: ``` seqthink_requests_total seqthink_errors_total seqthink_decrypt_failures_total seqthink_encrypt_failures_total seqthink_policy_denials_total seqthink_request_duration_seconds ``` ### Health Checks - **Liveness**: `GET /health` - Returns 200 if wrapper is running - **Readiness**: `GET /ready` - Returns 200 if MCP server is ready ### Logs View logs: ```bash # All replicas docker service logs seqthink_seqthink-wrapper # Follow logs docker service logs -f seqthink_seqthink-wrapper # Specific replica docker service logs seqthink_seqthink-wrapper. ``` ## Troubleshooting ### Issue: Policy Enforcement Disabled **Symptoms**: ``` Policy enforcement disabled - no JWKS URL or required scope configured ``` **Solution**: - Verify `KACHING_JWKS_URL` and `REQUIRED_SCOPE` are set - Check environment variables: `docker service inspect seqthink_seqthink-wrapper` ### Issue: JWKS Fetch Failed **Symptoms**: ``` Failed to pre-fetch JWKS, will retry on first request ``` **Solution**: - Check KACHING service is accessible - Verify JWKS URL is correct - Check network connectivity ### Issue: Decryption Failed **Symptoms**: ``` Failed to decrypt request seqthink_decrypt_failures_total increasing ``` **Solution**: - Verify age keys match between client and server - Check client is using correct public key - Ensure secrets are correctly mounted ### Issue: MCP Server Not Ready **Symptoms**: ``` ❌ MCP server not ready timeout waiting for MCP server ``` **Solution**: - Check MCP server is starting correctly - Review entrypoint.sh logs - Verify Python dependencies installed ## Security Considerations 1. **Key Rotation**: Periodically rotate age keys: ```bash # Generate new keys age-keygen -o seqthink_age_new.key age-keygen -y seqthink_age_new.key > seqthink_age_new.pub # Update secrets (requires service restart) docker secret rm seqthink_age_identity docker secret create seqthink_age_identity seqthink_age_new.key ``` 2. **JWT Token Expiration**: Tokens should have short expiration times (1 hour recommended) 3. **Network Isolation**: MCP server only accessible on loopback (127.0.0.1) 4. **TLS**: Always use HTTPS in production (via Traefik) 5. **Rate Limiting**: Consider adding rate limiting at Traefik level ## Development Mode For testing without security: ```yaml environment: # Disable encryption AGE_IDENT_PATH: "" AGE_RECIPS_PATH: "" # Disable policy KACHING_JWKS_URL: "" REQUIRED_SCOPE: "" ``` **WARNING**: Only use in development environments! ## Production Checklist - [ ] Age keys generated and stored as Docker secrets - [ ] KACHING JWKS URL configured and accessible - [ ] Docker image built and pushed to registry - [ ] Service deployed to swarm - [ ] Health checks passing - [ ] Metrics endpoint accessible - [ ] JWT tokens validated successfully - [ ] End-to-end encryption verified - [ ] Logs show no errors - [ ] Monitoring alerts configured - [ ] Backup of age keys stored securely - [ ] Documentation updated with deployment details ## Support For issues or questions: - Check logs: `docker service logs seqthink_seqthink-wrapper` - Review metrics: `curl http://localhost:8443/metrics` - Consult implementation docs in `/home/tony/chorus/project-queues/active/CHORUS/docs/`