Architecture Overview
This document provides a high-level overview of the Heimdall platform architecture.
System Architecture
┌──────────────────────────────────────────────────────────────────────────────────┐
│ Internet │
├──────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Client │ │ Backend │ │ ID │ │ Policies │ │ Docs │ │
│ │ Apps │ │ (Next.js)│ │ (Next.js)│ │ (Next.js)│ │(Docusaur)│ │
│ │ (REST/WS)│ │ :3001 │ │ :3002 │ │ :3004 │ │ :3003 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────────┘ └──────────┘ │
│ │ │ │ │
│ │ HTTPS │ HTTPS │ HTTPS │
│ │ WebSocket │ GraphQL │ OAuth │
│ │ │ REST │ │
│ │ │ │ │
│ ┌────┴─────────────┴─────────────┴──────────────────────────────────────┐ │
│ │ Load Balancer │ │
│ │ (nginx / cloud LB) │ │
│ └───────────────────────────────┬────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────┐ ┌─────────────┐│ ┌─────────────┐ │
│ │ Discord Bot │ │ Twitch Bot ││ │ YouTube Bot │ │
│ │ (Rust) │ │ (Rust) ││ │ (Rust) │ ◄── Bots (Rust) │
│ │ :3006 │ │ :3007 ││ │ :3008 │ GraphQL, REST, WS │
│ └──────┬──────┘ └──────┬──────┘│ └──────┬──────┘ │
│ │ │ │ │ │
│ └────────────────┼───────┼─────────┘ │
│ │ │ │
│ ┌───────────────────────┴───────┴───────────────────────────────────────┐ │
│ │ Rust API Binary (platform/api) │ │
│ │ (Actix-web Server) │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────────────────┐ │ │
│ │ │ 18 Modular Crates (crates/) │ │ │
│ │ │ │ │ │
│ │ │ heimdall-rest heimdall-graphql heimdall-websocket │ │ │
│ │ │ heimdall-auth heimdall-db heimdall-cache │ │ │
│ │ │ heimdall-audit heimdall-audit-logger heimdall-email │ │ │
│ │ │ heimdall-config heimdall-common heimdall-api │ │ │
│ │ │ heimdall-geoip heimdall-integrations heimdall-proto │ │ │
│ │ │ heimdall-storage heimdall-scheduler heimdall-telemetry │ │ │
│ │ └────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └───────────────────────┬────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────┴─────────────────────────────────────────┐ │
│ │ Data Layer │ │
│ │ │ │
│ │ ┌─────────────────────┐ ┌─────────────────────┐ ┌──────────┐│ │
│ │ │ PostgreSQL │ │ TimescaleDB │ │ Redis ││ │
│ │ │ (Primary Store) │ │ (Time-Series DB) │ │ (Cache) ││ │
│ │ │ │ │ │ │ ││ │
│ │ │ - Users │ │ - AuditEvent │ │ - Session││ │
│ │ │ - GPS Data │ │ (hypertable) │ │ - Perms ││ │
│ │ │ - API Keys │ │ - Time-based │ │ - Rate ││ │
│ │ │ - Roles/Permissions │ │ partitioning │ │ - Pub/Sub││ │
│ │ │ - OAuth Clients │ │ - Automatic data │ │ ││ │
│ │ │ - 2FA Secrets │ │ retention │ │ ││ │
│ │ │ - Data Exports │ │ - GeoIP enrichment │ │ ││ │
│ │ └─────────────────────┘ └─────────────────────┘ └──────────┘│ │
│ │ │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────────────────┘
Modular Crate Architecture
The backend was split from a monolithic platform/api/ into 18 independent crates under crates/. The platform/api/ binary is now pure glue code (just main.rs, lib.rs, and bin/) that wires the crates together via Actix-web.
Crate Dependency Layers
┌──────────────────┐
│ platform/api │ (binary — pure glue)
│ main.rs, lib.rs │
└────────┬─────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
┌─────────┴────────┐ ┌─────┴─────┐ ┌─────────┴────────┐
│ heimdall-rest │ │ heimdall- │ │ heimdall- │
│ (REST handlers, │ │ graphql │ │ websocket │
│ routes, OAuth, │ │ (types, │ │ (WS server, │
│ middleware) │ │ resolvers,│ │ sessions, │
│ │ │ schema) │ │ message types) │
└────────┬─────────┘ └─────┬─────┘ └────────┬─────────┘
│ │ │
└──────────────────┼───────────────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
┌─────────┴─────┐ ┌───────┴──────┐ ┌───────┴────────┐
│ heimdall-auth │ │ heimdall- │ │ heimdall- │
│ (JWT, RBAC, │ │ audit-logger │ │ integrations │
│ TOTP, crypto)│ │ (AuditLogger │ │ (Twitch/YT/ │
│ │ │ + GeoIP) │ │ Kick/Trovo) │
└───────┬───────┘ └──────┬───────┘ └───────┬────────┘
│ │ │
└─────────────────┼───────────────────┘
│
┌────────────────────────┼───────────────────────────┐
│ │ │ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐ ┌───┴──────┐ ┌───────┴───────┐
│heimdall-│ │heimdall-│ │heimdall-│ │heimdall- │ │ heimdall- │
│ db │ │ cache │ │ email │ │ geoip │ │ storage │
│(models, │ │(Redis │ │(SMTP + │ │(MaxMind │ │(S3 client, │
│ queries)│ │ client) │ │ sailfish│ │ GeoLite2)│ │ file upload) │
└────┬────┘ └────┬────┘ │ tmpl) │ └──────────┘ └───────────────┘
│ │ └────────┘
│ │
┌────┴───────────┴──────────────────────────────────────┐
│ Foundation layer │
│ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │
│ │ heimdall- │ │ heimdall- │ │ heimdall- │ │
│ │ config │ │ common │ │ telemetry │ │
│ │ (4-tier │ │ (errors, │ │ (tracing, │ │
│ │ config) │ │ pagination,│ │ Sentry) │ │
│ │ │ │ responses) │ │ │ │
│ └────────────┘ └────────────┘ └────────────────────┘ │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │
│ │ heimdall- │ │ heimdall- │ │ heimdall- │ │
│ │ api │ │ audit │ │ scheduler │ │
│ │ (CORS, │ │ (event │ │ (background │ │
│ │ health, │ │ types & │ │ jobs, cron) │ │
│ │ helpers) │ │ constants) │ │ │ │
│ └────────────┘ └────────────┘ └────────────────────┘ │
│ │
│ ┌────────────┐ │
│ │ heimdall- │ │
│ │ proto │ │
│ │ (protobuf │ │
│ │ WS types) │ │
│ └────────────┘ │
└────────────────────────────────────────────────────────┘
Crate Summary
| Crate | Location | Purpose |
|---|---|---|
| heimdall-config | crates/heimdall-config/ | 4-tier config loading: default.toml -> {env}.toml -> local.toml -> HEIMDALL__* env vars |
| heimdall-common | crates/heimdall-common/ | Shared error types, pagination, response wrappers |
| heimdall-db | crates/heimdall-db/ | Database pool management, domain models, SQL queries |
| heimdall-cache | crates/heimdall-cache/ | Redis client wrapper (sessions, permissions, rate limiting) |
| heimdall-telemetry | crates/heimdall-telemetry/ | Tracing subscriber and Sentry initialization |
| heimdall-api | crates/heimdall-api/ | Actix-web infrastructure: CORS, health, response helpers |
| heimdall-audit | crates/heimdall-audit/ | Shared audit event types and constants |
| heimdall-audit-logger | crates/heimdall-audit-logger/ | AuditLogger service (writes to TimescaleDB + GeoIP enrichment) |
| heimdall-auth | crates/heimdall-auth/ | JWT, OAuth, RBAC, TOTP/2FA, crypto utilities |
| heimdall-email | crates/heimdall-email/ | SMTP email service with Sailfish templates + rust-i18n |
| heimdall-geoip | crates/heimdall-geoip/ | MaxMind GeoLite2 IP-to-location lookup |
| heimdall-integrations | crates/heimdall-integrations/ | Platform OAuth: Twitch, YouTube, Kick, Trovo token management |
| heimdall-rest | crates/heimdall-rest/ | REST handlers, routes, OAuth endpoints, middleware |
| heimdall-graphql | crates/heimdall-graphql/ | GraphQL types, resolvers, and schema (async-graphql) |
| heimdall-websocket | crates/heimdall-websocket/ | WebSocket server, session management, channel pub/sub |
| heimdall-scheduler | crates/heimdall-scheduler/ | Background jobs and scheduled tasks |
| heimdall-proto | crates/heimdall-proto/ | Protobuf definitions for WebSocket communication |
| heimdall-storage | crates/heimdall-storage/ | S3-compatible storage client and file upload |
How the API Binary Wires Everything
The platform/api/ binary contains only main.rs, lib.rs, and bin/ scripts. It:
- Loads configuration via
heimdall-config - Initializes telemetry via
heimdall-telemetry - Creates database pools via
heimdall-db - Creates Redis client via
heimdall-cache - Injects services as
web::Data<T>into Actix-web (no globalAppStatestruct) - Registers routes from
heimdall-rest::routesandheimdall-graphql - Starts the WebSocket server from
heimdall-websocket - Starts background jobs from
heimdall-scheduler
Services are injected individually via web::Data<T> (e.g., web::Data<PgPool>, web::Data<RedisClient>, web::Data<GeoIpReader>), or via ServiceContext for handlers that need multiple services.
Build System
All crates are built via Bazel with BuildBuddy remote cache for fast CI builds. Standard cargo build also works for local development.
Component Overview
Rust API (platform/api)
The core backend service, handling all API requests. This is a thin binary that wires together the 18 modular crates.
Technology Stack:
- Framework: Actix-web 4
- Database: SQLx with PostgreSQL (primary) + TimescaleDB (time-series)
- GraphQL: async-graphql
- OpenAPI: utoipa with Swagger UI
- Caching: Redis (via
heimdall-cache) - GeoIP: MaxMind GeoLite2 (via
heimdall-geoip)
Responsibilities:
- REST API endpoints (via
heimdall-rest) - GraphQL queries and mutations (via
heimdall-graphql) - WebSocket connections for real-time updates (via
heimdall-websocket) - Authentication and authorization (via
heimdall-auth) - Rate limiting (via
heimdall-rest::middleware) - Data persistence (via
heimdall-db)
Backend (platform/backend)
Administrative interface for platform management.
Technology Stack:
- Framework: Next.js 16 (App Router)
- Language: TypeScript
- Styling: TailwindCSS 4
- Auth: NextAuth.js 5
- GraphQL: Apollo Client
Responsibilities:
- Admin dashboard
- GPS data visualization
- User management
- Role management
- API key management
- Developer tools (OAuth apps)
ID (platform/id)
Identity and authentication service with GDPR compliance.
Technology Stack:
- Framework: Next.js 16 (App Router)
- Language: TypeScript
- Styling: TailwindCSS 4
- Auth: NextAuth.js 5
- i18n: next-intl
Responsibilities:
- User registration and login
- Two-factor authentication (TOTP)
- OAuth 2.0 provider functionality
- Account management
- Account linking (multiple providers)
- Connected apps management
- GDPR data export
- Account deletion with grace period
- Session management
Policies (platform/policies)
Legal, privacy, and compliance content.
Technology Stack:
- Framework: Next.js 16 (App Router)
- Language: TypeScript
- Styling: TailwindCSS 4
- i18n: next-intl
Responsibilities:
- Privacy policy
- Terms of service
- Cookie policy
- Security information
- FAQ
Documentation (platform/docs)
This documentation site.
Technology Stack:
- Framework: Docusaurus 3
- Language: TypeScript/MDX
Discord Bot (platform/discord_bot)
Discord integration bot for the Heimdall platform.
Technology Stack:
- Framework: Poise (on Serenity-rs)
- Language: Rust 2024 edition
- API Communication: GraphQL, REST, WebSocket (Protobuf)
- i18n: rust-i18n
Responsibilities:
- Slash commands and prefix commands
- RBAC permission checking via Heimdall API
- Audit event logging to Heimdall
- Real-time event notifications via WebSocket
- Moderation commands (warn, kick, ban, mute)
- Admin settings management
Twitch Bot (platform/twitch_bot)
Twitch integration bot for the Heimdall platform.
Technology Stack:
- Framework: twitch-irc (Rust)
- Language: Rust 2024 edition
- API Communication: GraphQL, REST, WebSocket (Protobuf)
Responsibilities:
- Chat commands
- Stream event handling
- Audit event logging to Heimdall
- Real-time notifications
Data Flow
REST API Request Flow
Client Request
│
▼
┌─────────────┐
│ CORS │ (heimdall-api)
│ Middleware │
└──────┬──────┘
│
▼
┌─────────────┐
│ Logger │ (heimdall-telemetry)
│ Middleware │
└──────┬──────┘
│
▼
┌─────────────┐
│ Auth │ (heimdall-rest::middleware)
│ Middleware │
└──────┬──────┘
│
▼
┌─────────────┐
│ Rate Limit │ (heimdall-rest::middleware)
│ Middleware │
└──────┬──────┘
│
▼
┌─────────────┐
│ Handler │ (heimdall-rest::handlers)
│ Function │
└──────┬──────┘
│
▼
┌─────────────┐
│ Database │ (heimdall-db)
│ Query │
└──────┬──────┘
│
▼
Response
WebSocket Connection Flow
Client Connect
│
▼
┌─────────────┐
│ WebSocket │ (heimdall-websocket::route)
│ Upgrade │
└──────┬──────┘
│
▼
┌─────────────┐
│ State │
│ Manager │──────┐
└──────┬──────┘ │
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Connection │ │ Channel │
│ Handler │ │ Manager │
└──────┬──────┘ └──────┬──────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Subscribe/ │ │ Publish │
│ Unsubscribe │ │ Updates │
└─────────────┘ └─────────────┘
Database Architecture
Heimdall uses a dual-database architecture:
- PostgreSQL (Primary) - Core application data (users, sessions, API keys, etc.)
- TimescaleDB (Time-Series) - Audit events stored in a hypertable with automatic time-based partitioning
This separation provides:
- Optimized time-series queries for audit logs with automatic compression
- Independent scaling for OLTP vs analytics workloads
- GeoIP enrichment for security monitoring (country, city, region)
- Automatic data retention policies for compliance
Core Tables (PostgreSQL)
-- Users (managed by Heimdall ID)
User
├── id (UUID)
├── twitch_id
├── username
├── email
├── avatar_url
├── created_at
└── updated_at
-- Sessions (NextAuth)
Session
├── id (UUID)
├── user_id → User
├── session_token
├── expires
└── created_at
-- API Keys
ApiKey
├── id (UUID)
├── key (hashed)
├── name
├── description
├── user_id → User (optional)
├── scopes[]
├── is_active
├── expires_at
├── last_used_at
└── created_at
-- Roles
Role
├── id (UUID)
├── name (unique)
├── description
├── is_system
└── created_at
-- Permissions
Permission
├── id (UUID)
├── resource
├── action
├── description
└── created_at
-- GPS Data
GpsData
├── id (UUID)
├── latitude
├── longitude
├── altitude
├── speed
├── timestamp
└── created_at
-- Settings
Setting
├── key (primary)
├── value (JSON)
├── is_public
└── updated_at
-- OAuth Clients
OAuthClient
├── id (UUID)
├── client_id
├── client_secret (hashed)
├── name
├── redirect_uris[]
├── user_id → User
└── created_at
Audit Events (TimescaleDB)
Audit events are stored in a TimescaleDB hypertable with automatic time-based partitioning and GeoIP enrichment:
-- Audit Events (TimescaleDB Hypertable)
AuditEvent
├── id (UUID)
├── user_id (optional, can be Heimdall UUID or external ID like Discord snowflake)
├── event_type (string)
├── resource_type (optional)
├── resource_id (optional)
├── actor_id (optional, for admin actions)
├── ip_address (optional)
├── user_agent (optional)
├── description (optional)
├── metadata (JSONB)
├── status (success/failure)
├── error_message (optional)
├── country_code (ISO 3166-1 alpha-2, auto-enriched from IP)
├── country_name (auto-enriched from IP)
├── city (auto-enriched from IP)
├── region (auto-enriched from IP)
├── source_service (optional)
├── is_reported (boolean, for suspicious activity reports)
└── created_at (partitioning key)
Key Features:
- Hypertable: Automatic time-based partitioning (7-day chunks)
- GeoIP Enrichment: Country, city, region automatically added from IP address
- Compression: Automatic compression after 30 days
- Retention: Configurable data retention policies
Audit Event Types
| Event Type | Description |
|---|---|
| Authentication | |
login | User signed in |
login_failed | Sign-in attempt failed |
logout | User signed out |
password_changed | Password was changed |
password_reset_requested | Password reset requested |
| Two-Factor Auth | |
2fa_enabled | 2FA was enabled |
2fa_disabled | 2FA was disabled |
2fa_verified | 2FA code verified |
2fa_backup_codes_regenerated | Backup codes regenerated |
| Sessions | |
session_created | New session created |
session_revoked | Session was revoked |
all_sessions_revoked | All other sessions revoked |
| Account | |
user_created | Account created |
user_updated | Profile updated |
user_deleted | Account deleted |
deletion_scheduled | Account deletion scheduled |
deletion_cancelled | Scheduled deletion cancelled |
| Account Links | |
account_linked | Platform account linked |
account_unlinked | Platform account unlinked |
account_reconnected | Platform account reconnected |
primary_account_changed | Primary account changed |
| OAuth | |
consent_granted | OAuth consent given |
consent_revoked | OAuth consent revoked |
token_created | OAuth token created |
token_revoked | OAuth token revoked |
client_created | OAuth client created |
client_updated | OAuth client updated |
client_deleted | OAuth client deleted |
client_secret_regenerated | OAuth client secret regenerated |
| API Keys | |
api_key_created | API key was created |
api_key_updated | API key was updated |
api_key_revoked | API key was revoked |
| Admin | |
user_banned | User was banned |
user_unbanned | User was unbanned |
role_assigned | Role assigned to user |
role_removed | Role removed from user |
permission_changed | Permission changed |
| Data | |
data_exported | GDPR data export completed |
activity_reported | Suspicious activity reported |
| Bot Events | |
bot_command_executed | Bot command executed |
bot_config_changed | Bot configuration changed |
bot_moderation_action | Bot moderation action |
bot_guild_configured | Discord guild configured |
| Integrations | |
integration_connected | Platform integration connected |
integration_reconnected | Integration re-authorized |
integration_disconnected | Integration disconnected |
integration_token_refreshed | Token automatically refreshed |
integration_status_updated | Integration status updated |
Source Services
The source_service field tracks which application created the audit event:
| Source Service | Description |
|---|---|
api | Direct API access |
id | Heimdall ID webapp |
backend | Backend dashboard |
policies | Policies webapp |
discord_bot | Discord bot |
twitch_bot | Twitch bot |
Junction Tables
UserRole (user_id, role_id)
ApiKeyRole (api_key_id, role_id)
RolePermission (role_id, permission_id)
LinkedAccount (user_id, provider, provider_account_id)
Deployment Architecture
Development
┌───────────────────────────────────────────────────────────────────────────┐
│ Local Development │
├───────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ API │ │Backend │ │ ID │ │ Docs │ │Policies│ │
│ │ :3000 │ │ :3001 │ │ :3002 │ │ :3003 │ │ :3004 │ │
│ └───┬────┘ └───┬────┘ └───┬────┘ └────────┘ └────────┘ │
│ │ │ │ │
│ └───────────┼───────────┘ │
│ │ │
│ ┌───────────────┼───────────────────────────────────────┐ │
│ │ │ │ │
│ │ ┌────────────┴────────────┐ ┌────────────────────┐ │ │
│ │ │ Discord Bot │ │ Twitch Bot │ │ │
│ │ │ :3006 │ │ :3007 │ │ Rust Bots │
│ │ └────────────┬────────────┘ └─────────┬──────────┘ │ │
│ │ └──────────────┬──────────┘ │ │
│ └──────────────────────────────┼────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────┴────────────────────────────────┐ │
│ │ Docker Compose │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌─────────┐ │ │
│ │ │ PostgreSQL │ │TimescaleDB │ │ Redis │ │ MailDev │ │ │
│ │ │ :5432 │ │ :5433 │ │ :6379 │ │ :1080 │ │ │
│ │ └────────────┘ └────────────┘ └────────────┘ └─────────┘ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────────┘
Production
┌───────────────────────────────────────────────────────────────────┐
│ Production Deployment │
├───────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ CDN / Edge Network │ │
│ │ (Cloudflare / Vercel Edge) │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────┴────────────────────────────────┐ │
│ │ Load Balancer │ │
│ │ (nginx / Cloud LB) │ │
│ └───────────────────────────┬────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────┼────────────────────────────────┐ │
│ │ ┌──────────┐ ┌───────┴────┐ ┌──────────┐ │ │
│ │ │ API Pod │ │ API Pod │ │ API Pod │ │ │
│ │ │ #1 │ │ #2 │ │ #3 │ │ │
│ │ └──────────┘ └────────────┘ └──────────┘ │ │
│ │ (Kubernetes) │ │
│ └───────────────────────────┬────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────┼────────────────────────────────┐ │
│ │ ┌─────────────────┐ │ ┌─────────────────┐ │ │
│ │ │ PostgreSQL │ │ │ Redis │ │ │
│ │ │ (Primary) │◄─────┴─────►│ (Cluster) │ │ │
│ │ └────────┬────────┘ └─────────────────┘ │ │
│ │ │ │ │
│ │ ┌────────┴────────┐ │ │
│ │ │ PostgreSQL │ │ │
│ │ │ (Replica) │ │ │
│ │ └─────────────────┘ │ │
│ │ (Managed Database) │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Next.js Apps │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Backend │ │ ID │ │ Policies │ │ Docs │ │ │
│ │ │ (Vercel) │ │ (Vercel) │ │ (Vercel) │ │ (Vercel) │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────┘
Security Architecture
Authentication Layers
-
Session-based (Next.js apps via NextAuth)
- HTTP-only secure cookies
- JWT tokens with short expiry
- Automatic refresh
-
Token-based (API access)
- Bearer tokens in Authorization header
- API keys for programmatic access
- OAuth 2.0 for third-party apps
-
Two-Factor Authentication
- TOTP-based (RFC 6238)
- Backup codes for recovery
- Role-based 2FA requirements
Authorization Model
Request
│
▼
┌─────────────────────┐
│ Extract Auth Token │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Lookup Token │
│ (JWT or API Key) │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Get User/Key │
│ Roles │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Aggregate │
│ Permissions │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Check Permission │
│ (resource:action) │
└──────────┬──────────┘
│
┌─────┴─────┐
│ │
▼ ▼
Allow Deny
Configuration System
Heimdall uses a 4-tier configuration system (via heimdall-config):
config/default.toml-- Base defaults for all environmentsconfig/{env}.toml-- Environment-specific overrides (e.g.,production.toml)config/local.toml-- Local developer overrides (git-ignored)HEIMDALL__*env vars -- Runtime overrides (highest priority, double underscore for nesting)
Example: HEIMDALL__DATABASE__URL=postgres://... overrides [database] url in TOML.
Next Steps
- Crate Reference - Detailed reference for all 18 crates
- Auth System - Detailed authentication architecture
- Databases & Caching - Database architecture
- API Overview - API documentation
- Web Apps - Frontend applications
- Discord Bot - Discord bot documentation