Development Setup
This guide walks you through setting up a complete Voidkey development environment.
Prerequisites
Section titled “Prerequisites”Required Software
Section titled “Required Software”- Node.js 18+ and npm 9+
- Go 1.21+
- Docker and Docker Compose
- Git
- Make (optional but recommended)
Recommended Tools
Section titled “Recommended Tools”- VS Code or similar IDE with TypeScript support
- Postman or similar for API testing
- jq for JSON manipulation
- direnv for environment management
Repository Setup
Section titled “Repository Setup”1. Clone the Repository
Section titled “1. Clone the Repository”git clone https://github.com/voidkey-oss/voidkey.gitcd voidkey2. Repository Structure
Section titled “2. Repository Structure”voidkey/├── broker-core/ # TypeScript core library├── broker-server/ # NestJS HTTP server├── cli/ # Go CLI client├── sandbox/ # Docker development environment├── docs/ # Documentation (Astro)├── scripts/ # Development scripts└── CLAUDE.md # AI assistant instructionsDevelopment Environment
Section titled “Development Environment”1. Start the Sandbox
Section titled “1. Start the Sandbox”The sandbox provides a complete local environment:
cd sandboxdocker-compose up -d
# Wait for services to be readydocker-compose ps
# View logsdocker-compose logs -fThis starts:
- Keycloak on
http://localhost:8080- Admin:
admin/admin - Test realm with pre-configured clients
- Admin:
- MinIO on
http://localhost:9000- Console:
http://localhost:9001 - Root:
minioadmin/minioadmin
- Console:
2. Environment Variables
Section titled “2. Environment Variables”Create a .env file in the root:
# Development environmentNODE_ENV=developmentLOG_LEVEL=debug
# Broker configurationBROKER_CLIENT_SECRET=dev-secret-12345CONFIG_PATH=./sandbox/config/dev-config.yaml
# URLsVOIDKEY_BROKER_URL=http://localhost:3000KEYCLOAK_URL=http://localhost:8080MINIO_URL=http://localhost:9000Component Development
Section titled “Component Development”broker-core Development
Section titled “broker-core Development”cd broker-core
# Install dependenciesnpm install
# Run in watch modenpm run dev
# Run tests in watch modenpm run test:watch
# Buildnpm run build
# Type checkingnpm run type-checkCore Development Tasks
Section titled “Core Development Tasks”Adding a new IdP Provider:
- Create provider file:
import { IdpProvider, TokenClaims } from '../interfaces';
export class MyIdpProvider implements IdpProvider { constructor(private config: MyIdpConfig) {}
async validateToken(token: string): Promise<TokenClaims> { // Implementation }
async getPublicKeys(): Promise<JWKSet> { // Implementation }}- Add tests:
describe('MyIdpProvider', () => { it('should validate tokens', async () => { // Test implementation });});- Register provider:
export { MyIdpProvider } from './my-idp.provider';broker-server Development
Section titled “broker-server Development”cd broker-server
# Install dependenciesnpm install
# Run development servernpm run dev
# The server will reload automatically on changes# API available at http://localhost:3000Server Development Tasks
Section titled “Server Development Tasks”Adding a new endpoint:
- Create DTO:
import { IsString, IsArray } from 'class-validator';
export class MyEndpointDto { @IsString() someField: string;
@IsArray() @IsString({ each: true }) items: string[];}- Update controller:
@Post('my-endpoint')async myEndpoint(@Body() dto: MyEndpointDto) { return this.credentialsService.processMyEndpoint(dto);}- Add service method:
async processMyEndpoint(dto: MyEndpointDto) { // Implementation}CLI Development
Section titled “CLI Development”cd cli
# Get dependenciesgo mod download
# Run during developmentgo run main.go mint --keys TEST_KEY
# Run testsgo test ./...
# Build binarygo build -o voidkey main.go
# Run built binary./voidkey --helpCLI Development Tasks
Section titled “CLI Development Tasks”Adding a new command:
- Create command file:
package cmd
import ( "github.com/spf13/cobra")
func newMyCommand() *cobra.Command { cmd := &cobra.Command{ Use: "mycommand", Short: "Description of my command", RunE: func(cmd *cobra.Command, args []string) error { // Implementation return nil }, }
cmd.Flags().StringP("option", "o", "", "Option description")
return cmd}- Register command:
func init() { rootCmd.AddCommand(newMyCommand())}Testing
Section titled “Testing”Unit Tests
Section titled “Unit Tests”Each component has its own test suite:
# broker-corecd broker-corenpm testnpm run test:coverage
# broker-servercd broker-servernpm testnpm run test:cov
# CLIcd cligo test ./... -vgo test -cover ./...Integration Tests
Section titled “Integration Tests”Run integration tests against the sandbox:
# Start sandbox firstcd sandboxdocker-compose up -d
# Run integration testscd ../broker-servernpm run test:integration
# Or specific test filenpm test -- --testPathPattern=integrationE2E Tests
Section titled “E2E Tests”Full end-to-end test script:
#!/bin/bash# Start all servicescd sandbox && docker-compose up -dcd ../broker-server && npm run dev &SERVER_PID=$!
# Wait for servicessleep 10
# Get test tokenTOKEN=$(curl -s -X POST \ "http://localhost:8080/realms/client/protocol/openid-connect/token" \ -d "client_id=test-client" \ -d "username=test-user" \ -d "password=test-password" \ -d "grant_type=password" | jq -r '.access_token')
# Test CLIcd ../cligo run main.go mint --token "$TOKEN" --keys MINIO_TEST
# Cleanupkill $SERVER_PIDcd ../sandbox && docker-compose downDevelopment Workflow
Section titled “Development Workflow”1. Feature Development
Section titled “1. Feature Development”# Create feature branchgit checkout -b feature/my-feature
# Make changes and testnpm test
# Commit with conventional commitsgit commit -m "feat: add support for X"
# Push and create PRgit push -u origin feature/my-feature2. Debugging
Section titled “2. Debugging”VS Code Launch Configuration:
{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Debug Broker Server", "runtimeExecutable": "npm", "runtimeArgs": ["run", "start:debug"], "cwd": "${workspaceFolder}/broker-server", "console": "integratedTerminal" }, { "type": "go", "request": "launch", "name": "Debug CLI", "program": "${workspaceFolder}/cli/main.go", "args": ["mint", "--keys", "TEST_KEY"], "env": { "VOIDKEY_BROKER_URL": "http://localhost:3000", "VOIDKEY_OIDC_TOKEN": "test-token" } } ]}Debug Logging:
// Enable debug logsimport { Logger } from '@nestjs/common';
const logger = new Logger('MyClass');logger.debug('Debug message', { data });3. Code Quality
Section titled “3. Code Quality”Linting:
# TypeScriptcd broker-corenpm run lintnpm run lint:fix
# Gocd cligolangci-lint runFormatting:
# TypeScript (Prettier)npm run format
# Gogo fmt ./...Common Development Tasks
Section titled “Common Development Tasks”Adding Configuration Options
Section titled “Adding Configuration Options”- Update configuration interface:
export interface BrokerConfig { newOption?: string;}- Add validation:
if (config.newOption && !isValidOption(config.newOption)) { throw new Error('Invalid newOption');}- Update example config:
newOption: "example-value"Testing with Different IdPs
Section titled “Testing with Different IdPs”Auth0 Setup:
# Use Auth0 instead of Keycloakexport BROKER_IDP_ISSUER="https://dev-xxx.auth0.com/"export BROKER_IDP_CLIENT_ID="your-client-id"export BROKER_IDP_CLIENT_SECRET="your-client-secret"GitHub Actions Local:
# Use act to run GitHub Actions locallyact -s GITHUB_TOKEN=your-tokenPerformance Profiling
Section titled “Performance Profiling”# Node.js profilingnode --inspect broker-server/dist/main.js
# Go profilinggo test -cpuprofile cpu.prof -memprofile mem.prof ./...go tool pprof cpu.profTroubleshooting
Section titled “Troubleshooting”Common Issues
Section titled “Common Issues”Port conflicts:
# Check what's using portslsof -i :3000 # Broker serverlsof -i :8080 # Keycloaklsof -i :9000 # MinIO
# Change ports in docker-compose.yml if neededModule resolution errors:
# Clear node_modules and reinstallrm -rf node_modules package-lock.jsonnpm install
# Link local packagescd broker-core && npm linkcd ../broker-server && npm link @voidkey/broker-coreDocker issues:
# Reset Docker environmentdocker-compose down -vdocker system prune -fdocker-compose up --buildDebug Commands
Section titled “Debug Commands”# Check service healthcurl http://localhost:3000/health
# Test Keycloak connectioncurl http://localhost:8080/realms/broker/.well-known/openid-configuration
# Test MinIOcurl http://localhost:9000/minio/health/live
# View all logsdocker-compose logs -f --tail=100Next Steps
Section titled “Next Steps”- Testing Guide - Writing and running tests
- Contributing Guide - Contribution guidelines
- API Development - API development guide
- Deployment Guide - Deploy your changes