Local Development Environment Setup
This guide walks you through configuring a complete CitadelMesh development environment optimized for productivity.
Development Tools Installation
.NET Development
Install .NET 8.0 SDK
macOS (Homebrew):
brew install dotnet@8
Windows (winget):
winget install Microsoft.DotNet.SDK.8
Linux (Ubuntu/Debian):
wget https://dot.net/v1/dotnet-install.sh
chmod +x dotnet-install.sh
./dotnet-install.sh --version 8.0
Verify:
dotnet --version
# Output: 8.0.x
Install Aspire Workload
Aspire is CitadelMesh's orchestration engine:
dotnet workload update
dotnet workload install aspire
Verify:
dotnet workload list
# Should show: aspire 8.x.x
Python Development
Install Python 3.12+
macOS (Homebrew):
brew install python@3.12
Windows (winget):
winget install Python.Python.3.12
Linux (pyenv recommended):
curl https://pyenv.run | bash
pyenv install 3.12
pyenv global 3.12
Create Virtual Environment
cd /path/to/CitadelMesh/src/agents
# Create virtual environment
python3.12 -m venv .venv
# Activate
source .venv/bin/activate # macOS/Linux
.venv\Scripts\activate # Windows
# Install dependencies
pip install --upgrade pip
pip install -r requirements.txt
Expected packages:
langgraph>=0.0.32- Agent state machineslangchain>=0.1.0- LLM orchestrationopentelemetry-api>=1.15.0- Observabilitystructlog>=22.1.0- Structured loggingnats-py>=2.6.0- Event bus clientprotobuf>=6.32.0- Protocol buffersgrpcio>=1.75.0- gRPC communication
Node.js Development (MCP Adapters)
Install Node.js 20+
macOS (Homebrew):
brew install node@20
Windows (winget):
winget install OpenJS.NodeJS.LTS
Linux (nvm recommended):
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install 20
nvm use 20
Install MCP Dependencies
cd /path/to/CitadelMesh/mcp-servers/ecostruxure-ebo
npm install
Expected packages:
@modelcontextprotocol/sdk- MCP protocol implementationzod- Runtime type validationtypescript- Type safety
Docker Desktop
Install Docker
macOS:
brew install --cask docker
# Launch Docker Desktop from Applications
Windows: Download from docker.com/products/docker-desktop
Linux:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Log out and back in
Verify:
docker --version
docker compose version
Configure Resources (Recommended):
- CPUs: 4+
- Memory: 8GB+
- Disk: 50GB+
Configuration Files
1. Environment Variables
Create .env in the project root:
cd /path/to/CitadelMesh
.env file:
# Infrastructure
ASPIRE_DASHBOARD_PORT=5000
NATS_URL=nats://localhost:4222
REDIS_URL=redis://localhost:6379
POSTGRES_URL=postgresql://postgres:citadel123@localhost:5432/citadel-db
# Security & Identity
OPA_URL=http://localhost:8181
SPIRE_SERVER_ADDRESS=localhost:8081
SPIRE_AGENT_SOCKET=/run/spire/sockets/agent.sock
# Observability
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
JAEGER_UI_URL=http://localhost:16686
# Development
CITADEL_ENV=development
LOG_LEVEL=DEBUG
ENABLE_MOCK_MODE=true
# Agent Configuration
AGENT_RUNTIME=python
ENABLE_SAFETY_CHECKS=true
ENABLE_TELEMETRY=true
# MCP Servers
MCP_ECOSTRUXURE_URL=http://localhost:3001
MCP_SECURITY_EXPERT_URL=http://localhost:3002
2. .NET Configuration
src/CitadelMesh.AppHost/appsettings.Development.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Aspire": "Debug"
}
},
"AllowedHosts": "*",
"Dashboard": {
"Port": 5000,
"EnableAuthentication": false
}
}
src/microservices/CitadelMesh.Safety/appsettings.Development.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"CitadelMesh": "Debug"
}
},
"OPA": {
"BaseUrl": "http://localhost:8181",
"PolicyPath": "v1/data/citadel",
"Timeout": 5000
}
}
3. Python Configuration
src/agents/.env:
# Agent Runtime
NATS_URL=nats://localhost:4222
OPA_URL=http://localhost:8181
SPIFFE_ID=spiffe://citadel.local/agent/security
# Logging
LOG_LEVEL=INFO
LOG_FORMAT=json
# Telemetry
OTEL_SERVICE_NAME=citadel-agent
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
4. Docker Compose Override
For local development, create docker-compose.override.yml:
version: '3.9'
services:
opa:
volumes:
- ./policies:/policies:rw # Read-write for hot reload
environment:
- OPA_LOG_LEVEL=debug
nats:
ports:
- "8222:8222" # Monitoring UI
IDE Setup
Visual Studio Code (Recommended)
Install Extensions
# Install via command palette (Cmd/Ctrl + Shift + P)
code --install-extension ms-dotnettools.csdevkit
code --install-extension ms-python.python
code --install-extension ms-azuretools.vscode-docker
code --install-extension redhat.vscode-yaml
code --install-extension tsandall.opa
Workspace Settings
Create .vscode/settings.json:
{
"dotnet.defaultSolution": "CitadelMesh.sln",
"python.defaultInterpreterPath": "${workspaceFolder}/src/agents/.venv/bin/python",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.provider": "black",
"editor.formatOnSave": true,
"files.associations": {
"*.rego": "rego"
},
"opa.path": "/usr/local/bin/opa",
"opa.checkOnSave": true
}
Launch Configurations
Create .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Aspire AppHost",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/CitadelMesh.AppHost/bin/Debug/net8.0/CitadelMesh.AppHost.dll",
"args": [],
"cwd": "${workspaceFolder}/src/CitadelMesh.AppHost",
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": "Python: Security Agent",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/src/agents/security/demo_security_agent.py",
"console": "integratedTerminal",
"env": {
"PYTHONPATH": "${workspaceFolder}/src"
}
},
{
"name": "Node: MCP Server",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/mcp-servers/ecostruxure-ebo/dist/index.js",
"preLaunchTask": "npm: build - mcp-servers/ecostruxure-ebo",
"outFiles": ["${workspaceFolder}/mcp-servers/ecostruxure-ebo/dist/**/*.js"]
}
]
}
Visual Studio 2022 (Windows/Mac)
-
Open
CitadelMesh.sln -
Right-click solution → Manage NuGet Packages
-
Install Aspire packages:
Aspire.Hosting.AppHostAspire.Hosting.RedisAspire.Hosting.PostgreSQL
-
Set
CitadelMesh.AppHostas startup project -
Press F5 to run
Development Workflow
1. Start Infrastructure
# Option A: Using Aspire (Recommended)
cd src/CitadelMesh.AppHost
dotnet run
# Option B: Using Docker Compose
docker compose -f docker-compose-spire.yml up -d
2. Develop Agents
cd src/agents
source .venv/bin/activate
# Run agent in dev mode
python security/security_agent.py
3. Develop MCP Adapters
cd mcp-servers/ecostruxure-ebo
# Watch mode (auto-rebuild on change)
npm run dev
# In another terminal, test the server
node dist/index.js
4. Edit OPA Policies
# Policies are hot-reloaded automatically
vim policies/security.rego
# Validate policy
opa test policies/security.rego policies/security_test.rego
5. View Logs and Traces
- Aspire Dashboard: https://localhost:5000/console
- Jaeger UI: http://localhost:16686
- NATS Monitoring: http://localhost:8222
Troubleshooting
Issue: Port Conflicts
Error: Failed to bind to address https://localhost:5000
Solution:
# Find process using port 5000
lsof -ti:5000 | xargs kill -9 # macOS/Linux
netstat -ano | findstr :5000 # Windows
# Or change port in appsettings.Development.json
Issue: Python Import Errors
Error: ModuleNotFoundError: No module named 'citadel'
Solution:
# Ensure PYTHONPATH is set
export PYTHONPATH=/path/to/CitadelMesh/src
# Or add to .env file
Issue: Docker Containers Not Starting
Error: Cannot connect to Docker daemon
Solution:
# Start Docker Desktop
open -a Docker # macOS
# Wait for Docker to fully start (check system tray icon)
# Verify
docker ps
Issue: OPA Policies Not Loading
Error: Policy bundle not found
Solution:
# Check OPA logs
docker logs citadel-opa
# Verify policy syntax
opa check policies/*.rego
# Manually load bundle
curl -X PUT http://localhost:8181/v1/policies/citadel/security \
-H 'Content-Type: text/plain' \
-d @policies/security.rego
Issue: SPIRE Identity Issues
Error: Failed to attest workload
Solution:
# Restart SPIRE agent
docker restart citadel-spire-agent
# Register workload manually
docker exec citadel-spire-server \
/opt/spire/bin/spire-server entry create \
-spiffeID spiffe://citadel.local/agent/security \
-parentID spiffe://citadel.local/agent \
-selector unix:uid:1000
Issue: .NET Build Failures
Error: The workload 'aspire' is not installed
Solution:
dotnet workload update
dotnet workload install aspire
dotnet restore
dotnet build
Development Best Practices
1. Hot Reload Workflow
- .NET: Hot reload enabled by default in Aspire
- Python: Use
watchdogfor auto-restart:pip install watchdog[watchmedo]
watchmedo auto-restart --pattern="*.py" -- python agent.py - OPA: Policies auto-reload when files change
2. Testing Locally
# Run unit tests
dotnet test # .NET tests
pytest src/agents/tests # Python tests
npm test # MCP adapter tests
# Integration tests
./scripts/integration-test.sh
3. Clean Rebuild
# Clean all build artifacts
dotnet clean
rm -rf src/agents/.venv
rm -rf mcp-servers/*/node_modules
# Full rebuild
dotnet restore && dotnet build
pip install -r src/agents/requirements.txt
cd mcp-servers/ecostruxure-ebo && npm install
Next Steps
- Master the Aspire Dashboard - Full observability guide
- Docker Compose Alternative - Simpler deployment
- Write Your First Policy - OPA fundamentals
- Create an Agent - Build custom agents
Environment Checklist
Before proceeding, ensure:
- .NET 8.0 SDK installed and verified
- Python 3.12+ with virtual environment configured
- Node.js 20+ for MCP development
- Docker Desktop running with 8GB+ memory
- All
.envfiles created - IDE configured with extensions
- Aspire dashboard accessible at https://localhost:5000
- OPA policies loading successfully
Environment ready! Continue to Aspire Dashboard Guide.