Local Development
This guide walks through everything needed to run the opensecstack ecosystem on your local machine — cloning the repo, starting the full stack or a single platform with hot-reload, working without Docker, and configuring your editor for Go, Rust, TypeScript, and Python.
Prerequisites
Install the following tools before cloning the repo. For full environment requirements and alternative install paths see Installation.
| Tool | Version | Purpose |
|---|---|---|
| Go | 1.22+ | Backend services, CLI |
| Rust (stable) | 1.76+ | Parsers, analysers, crypto |
| Node.js LTS | 20+ | React dashboards |
| Python | 3.12+ | Reports, data processing |
| Docker | 24+ | Local stack and test targets |
| Docker Compose | 2.24+ | Orchestration (included with Docker Desktop) |
| golangci-lint | latest | Go linting |
| cargo-nextest | latest | Faster Rust tests (cargo install cargo-nextest) |
Cloning the repo
git clone https://github.com/opensecstack/opensecstack cd opensecstack
The repository is a monorepo. Each of the 11 platforms lives in its own top-level directory (apiguard/, nis2compass/, etc.). Shared SDK contracts are in sdk/, CITADEL governance in .citadel/, and the ecosystem website in website/. For a map of how all components relate, see the Architecture overview.
Full-stack hot-reload workflow
The dev Docker Compose file mounts source directories as volumes so that most code changes are picked up without rebuilding the container image.
"cm"># From the repo root — starts all services make dev "cm"># Verify the API is up curl http://localhost:8080/api/v1/health "cm"># → {"status":"ok"} "cm"># Open the dashboard "cm"># http://localhost:3000
Hot-reload behaviour per language:
| Language | Tool | Behaviour |
|---|---|---|
| Go | air | Automatic live reload on file save |
| React / TypeScript | Vite HMR | Instant in-browser hot module replacement |
| Rust | — | Compiled language — run cargo build manually after changes |
The full stack starts: APIGuard API on port 8080, Dashboard on port 3000, PostgreSQL on 5432, and Redis on 6379.
Running a single platform
You do not need to start the entire stack to work on one platform. Each platform directory contains its own Makefile and .env.example.
"cm"># Example: APIGuard only cd apiguard cp .env.example .env "cm"># Edit with your values make dev
Replace apiguard with the directory name of the platform you are working on (e.g. nis2compass, threatflow, opencsirt).
Running without Docker
If you prefer to run services directly on the host, start PostgreSQL and Redis first (or run only those two containers), then launch each component individually.
"cm"># 1. Start PostgreSQL and Redis via Docker (or use local installs) docker run -d --name pg -p 5432:5432 \ -e POSTGRES_USER=opensecstack \ -e POSTGRES_PASSWORD=changeme \ -e POSTGRES_DB=opensecstack \ postgres:16-alpine docker run -d --name redis -p 6379:6379 redis:7-alpine "cm"># 2. Run database migrations cd apiguard && make migrate "cm"># 3. Start the Go API server cd apiguard && go run ./cmd/ "cm"># 4. Start the React dashboard (separate terminal) cd apiguard/web && npm install && npm run dev "cm"># 5. Build Rust components cd apiguard/rust && cargo build --release
Environment variables
Copy .env.example to .env in the platform directory. The following variables are required for APIGuard; every platform has its own set documented in platform/docs/configuration.md.
| Variable | Required | Description |
|---|---|---|
APIGUARD_DB_URL | Yes | PostgreSQL connection string |
APIGUARD_JWT_SECRET | Yes | JWT signing key (minimum 32 characters) |
APIGUARD_PORT | No | HTTP listen port (default 8080) |
CITADEL_API_URL and CITADEL_API_KEY. Leave these unset (or set CITADEL_DRY_RUN=true) for local development without a running CITADEL instance. See CITADEL Integration for details.Common dev tasks
"cm"># Run all tests make test "cm"># Run linters make lint "cm"># Format code make fmt "cm"># Run a sample scan against VAmPI (APIGuard) cd apiguard && make scan-example "cm"># Start test targets (VAmPI, crAPI) cd apiguard && docker compose -f docker-compose.test.yml up -d
IDE setup
VS Code (recommended)
The fastest path is the built-in Dev Container: open the opensecstack/ folder in VS Code and click "Reopen in Container" when prompted. All tools are pre-installed.
For a manual setup, install these extensions:
| Extension | ID | Purpose |
|---|---|---|
| Go | golang.go | Go language support, debugging, testing |
| rust-analyzer | rust-lang.rust-analyzer | Rust language support, completion, Clippy |
| Python | ms-python.python | Python language support |
| ESLint | dbaeumer.vscode-eslint | JavaScript / TypeScript linting |
| Prettier | esbenp.prettier-vscode | Code formatting (React / TS) |
| Docker | ms-azuretools.vscode-docker | Docker file support |
| Even Better TOML | tamasfe.even-better-toml | Cargo.toml support |
| CodeLLDB | vadimcn.vscode-lldb | Rust debugging |
Recommended .vscode/settings.json:
{
"go.lintTool": "golangci-lint",
"go.lintFlags": ["--fast"],
"rust-analyzer.check.command": "clippy",
"rust-analyzer.cargo.features": "all",
"[go]": { "editor.defaultFormatter": "golang.go" },
"[rust]": { "editor.defaultFormatter": "rust-lang.rust-analyzer" },
"[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[typescriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[python]": { "editor.defaultFormatter": "ms-python.python" }
}JetBrains (GoLand / RustRover)
- GoLand: open
apiguard/as a Go project, install the Rust plugin, enable golangci-lint under Settings → Go → Linters. - RustRover: open
apiguard/rust/as a Rust project, install the Go plugin, enable Clippy on save under Settings → Languages & Frameworks → Rust. - Both IDEs: enable "Format on save", connect the Database tool to
localhost:5432with credentials from.env, and connect Docker integration to the local daemon.
Troubleshooting
| Problem | Solution |
|---|---|
| Port 5432 already in use | Stop local PostgreSQL: sudo systemctl stop postgresql |
| Port 8080 already in use | Set APIGUARD_PORT to a free port in .env |
| Docker out of disk space | docker system prune -a |
| Rust build fails | rustup update stable |
| Go module issues | go mod tidy |