A collaborative threat modeling server built with Go.
Try it yourself at https://www.tmi.dev
API server online at https://api.tmi.dev
API clients available at https://github.com/ericfitz/tmi-clients
TMI (Threat Modeling Improved) is a server based web application enabling collaborative threat modeling with support for:
- Real-time collaborative diagram editing via WebSockets
- Role-based access control (reader, writer, owner)
- OAuth authentication with JWT
- RESTful API with OpenAPI 3.0 specification
- MCP integration (planned)
The associated Angular/Typescript front-end web application is called TMI-UX.
For detailed setup instructions, see Development Setup Guide.
- Go 1.24+
- Docker Desktop (for database & Redis containers)
- Make (for build automation)
git clone https://github.com/ericfitz/tmi.git
cd tmi
make start-devThe complete development environment (server + database + Redis) will start automatically on port 8080.
api/- API types and handlerscmd/server/- Server entry point and configurationtmi-api-v1_0.md- API documentationdocs/reference/apis/tmi-openapi.json- OpenAPI specification
The project uses strongly-typed concurrent maps for in-memory storage:
// Store provides thread-safe storage for a specific entity type
type Store[T any] struct {
data map[string]T
mutex sync.RWMutex
}
// DiagramStore stores diagrams by UUID
var DiagramStore = NewStore[api.Diagram]()
// ThreatModelStore stores threat models by UUID
var ThreatModelStore = NewStore[api.ThreatModel]()Benefits of this approach:
- Type safety with generics
- Concurrency protection with mutexes
- Clear separation between different entity stores
- Easy to replace with a database implementation later
This pattern is used for all entity types (diagrams, threat models, threats) and provides:
- CRUD operations
- Atomic updates
- Support for filtering and queries
Comprehensive documentation is organized by audience:
- Setup Guide - Local development environment
- Testing Guide - Comprehensive testing documentation
- Client Integration - API and WebSocket integration
- Deployment Guide - Production deployment
- Database Operations - Database management
- Container Security - Secure containerization
See docs/README.md for the complete documentation catalog organized by role and topic.
make start-dev # Start complete dev environment
make build-server # Build production binary
make test-unit # Run unit tests
make test-integration-new # Run integration tests (server must be running)
make cats-fuzz # Run security fuzzing
make lint # Run code lintingServer configuration can be set via environment variables or using a .env file:
- Copy the
.env.examplefile to.env - Modify the values as needed
- Start the server, which will automatically load the
.envfile
You can also specify a custom .env file with:
./bin/tmiserver --env=/path/to/custom.envAvailable configuration options:
| Variable | Default | Description |
|---|---|---|
| SERVER_PORT | 8080 | HTTP/HTTPS server port |
| SERVER_INTERFACE | 0.0.0.0 | Network interface to listen on |
| SERVER_READ_TIMEOUT | 5s | HTTP read timeout |
| SERVER_WRITE_TIMEOUT | 10s | HTTP write timeout |
| SERVER_IDLE_TIMEOUT | 60s | HTTP idle timeout |
| LOG_LEVEL | info | Logging level (debug, info, warn, error) |
| TLS_ENABLED | false | Enable HTTPS/TLS |
| TLS_CERT_FILE | Path to TLS certificate file | |
| TLS_KEY_FILE | Path to TLS private key file | |
| TLS_SUBJECT_NAME | [hostname] | Subject name for certificate validation |
| TLS_HTTP_REDIRECT | true | Redirect HTTP to HTTPS when TLS is enabled |
| JWT_SECRET | secret | JWT signing secret (change for production!) |
| JWT_EXPIRES_IN | 24h | JWT expiration |
| OAUTH_URL | https://oauth-provider.com/oauth2 | OAuth provider URL |
| OAUTH_SECRET | OAuth client secret | |
| DB_URL | localhost | Database URL |
| DB_USERNAME | Database username | |
| DB_PASSWORD | Database password | |
| DB_NAME | tmi | Database name |
| ENV | development | Environment (development or production) |
When TLS is enabled (TLS_ENABLED=true), clients should connect using secure WebSocket URLs:
- Use
wss://instead ofws://for WebSocket connections - Example:
wss://your-server.com:8080/ws/diagrams/123
When TLS is disabled, use standard WebSocket URLs:
- Example:
ws://your-server.com:8080/ws/diagrams/123
You can use the /api/server-info endpoint to get the correct WebSocket base URL automatically.
See license.txt