A stateless, API-driven Dungeons & Dragons management platform for nerds who demand proper architecture.
dnddoss is a modern D&D campaign management system built with zero compromises on technical excellence. Completely stateless, fully API-driven, and OIDC-native from the ground up, this is D&D tooling for engineers who believe authentication should be done right and state should live where it belongs (not in your server's memory).
- Stateless Architecture: No session cookies, no server-side state. JWT-based authentication all the way down.
- API-First Design: Every feature exposed via RESTful APIs. The UI is just another client.
- OIDC Native: OpenID Connect authentication baked into the core. Bring your own IdP.
- Local-First: Designed for self-hosting. Your data, your infrastructure, your rules.
- Create and manage D&D characters with full stat tracking
- Character sheets with complete attribute management
- Class, race, background, and equipment tracking
- Leveling and experience progression
- Inventory and spell management
- Create custom terrain and battle maps
- Grid-based map builder with token support
- Fog of war and dynamic reveal mechanics
- Terrain effects and environmental modifiers
- Import/export map templates
- Reusable character templates
- Monster and NPC templates
- Campaign templates for quick starts
- Encounter templates with CR balancing
- Custom homebrew content templates
- Multi-campaign support per user
- Invite system for players
- Role-based permissions (DM, Player, Observer)
- Session notes and timeline tracking
- Shared party inventory
- Generate invite codes for campaigns
- Email-based invitations with OIDC pre-auth
- Pending invitation management
- Player approval workflows
┌─────────────┐
│ OIDC IdP │ (Authentik, Keycloak, Auth0, etc.)
└──────┬──────┘
│
▼ JWT tokens
┌─────────────────────────────────┐
│ dnddoss API Server │
│ (Stateless, token validation) │
└────────┬────────────────────────┘
│
┌────┴────┬─────────┬──────────┐
▼ ▼ ▼ ▼
┌────────┐ ┌──────┐ ┌──────┐ ┌──────────┐
│ Web UI │ │ CLI │ │Mobile│ │ 3rd Party│
└────────┘ └──────┘ └──────┘ └──────────┘
Backend:
- Language: [Go/Rust/Node.js - choose your weapon]
- Database: PostgreSQL with JSONB for flexible character data
- Authentication: OIDC with JWT validation
- API: RESTful with OpenAPI 3.0 spec
Frontend:
- Framework: [React/Vue/Svelte - modern SPA]
- State Management: API-driven, no local state beyond cache
- Auth: OIDC Authorization Code Flow with PKCE
- OIDC-compliant Identity Provider (Authentik, Keycloak, etc.)
- PostgreSQL 14+
- Docker & Docker Compose (optional but recommended)
# Clone the repository
git clone https://github.com/yourusername/dnddoss.git
cd dnddoss
# Copy environment template
cp .env.example .env
# Configure OIDC settings
nano .env
# Start services
docker-compose up -d# OIDC Configuration
OIDC_ISSUER_URL=https://auth.example.com/application/o/dnddoss/
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
OIDC_REDIRECT_URI=http://localhost:3000/callback
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/dnddoss
# API Server
API_PORT=8080
API_HOST=0.0.0.0
JWT_AUDIENCE=dnddoss-api# Install dependencies
make install
# Run database migrations
make migrate
# Start API server
make run-api
# Start frontend (separate terminal)
make run-webConfigure your OIDC provider with:
- Redirect URIs:
http://localhost:3000/callback(dev),https://yourdomain.com/callback(prod) - Scopes:
openid,profile,email - Grant Types: Authorization Code with PKCE
- Token Endpoint Auth: Client Secret Post
Full API documentation available at /api/docs when running the server.
# All requests require Bearer token
curl -H "Authorization: Bearer ${JWT_TOKEN}" \
https://api.dnddoss.local/api/v1/characterscurl -X POST https://api.dnddoss.local/api/v1/characters \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "Thorin Stonehammer",
"race": "dwarf",
"class": "fighter",
"level": 1,
"attributes": {
"strength": 16,
"dexterity": 12,
"constitution": 15,
"intelligence": 10,
"wisdom": 13,
"charisma": 8
}
}'curl -X POST https://api.dnddoss.local/api/v1/campaigns \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "The Frozen Wastes",
"description": "A perilous journey through the northern tundra",
"is_public": false
}'curl -X POST https://api.dnddoss.local/api/v1/campaigns/{id}/invites \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"role": "player",
"expires_in_hours": 168
}'dnddoss/
├── api/ # API server code
│ ├── handlers/ # HTTP request handlers
│ ├── middleware/ # Auth, CORS, logging
│ ├── models/ # Data models
│ └── routes/ # Route definitions
├── web/ # Frontend application
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── pages/ # Page components
│ │ ├── api/ # API client
│ │ └── auth/ # OIDC authentication
│ └── public/
├── db/
│ ├── migrations/ # Database migrations
│ └── seeds/ # Test data
├── docs/ # Additional documentation
└── docker-compose.yml
# Backend tests
make test-api
# Frontend tests
make test-web
# Integration tests
make test-integrationdocker build -t dnddoss:latest .
docker run -p 8080:8080 \
-e OIDC_ISSUER_URL=https://auth.example.com \
-e DATABASE_URL=postgresql://... \
dnddoss:latestExample Caddy configuration:
dnddoss.yourdomain.com {
reverse_proxy localhost:8080
encode gzip
header {
Strict-Transport-Security "max-age=31536000;"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
}
}- All authentication via OIDC - no custom auth logic
- JWT tokens validated on every request
- RBAC enforced at API level
- SQL injection prevention via parameterized queries
- CORS configured for known origins only
- Rate limiting on all endpoints
- No PII stored without encryption at rest
This is a personal/local project, but PRs are welcome if you're into that sort of thing.
- Write tests for new features
- Follow existing code style
- Update API documentation
- No breaking changes without version bump
- Dice rolling API with probability calculations
- Real-time map updates via WebSocket
- AI-powered NPC dialogue generation
- Voice chat integration
- Mobile apps (iOS/Android)
- Campaign analytics dashboard
- Homebrew content marketplace
- Integration with D&D Beyond for character import
[Choose your license - MIT, GPL, Apache 2.0, etc.]
Built by nerds, for nerds. May your rolls be high and your sessions be legendary.
Note: This is an API-first platform. If you're looking for a GUI-only tool, this probably isn't for you. But if you want to curl your way through a campaign while SSHed into your homelab, you're in the right place.