Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions architecture/likec4.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$schema": "https://likec4.dev/schemas/config.json",
"name": "bhce",
"title": "BloodHound Community Edition"
}

129 changes: 129 additions & 0 deletions architecture/model/api-server.c4
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// BloodHound Community Edition - API Server Components
// Internal structure of the API Server container.

model {

extend bloodhound.apiServer {

// ─── HTTP Layer ────────────────────────────────────────────

httpRouter = component 'HTTP Router' {
#go
description 'Gorilla Mux router that registers all REST API routes and applies global middleware.'
technology 'gorilla/mux'
}

authMiddleware = component 'Auth Middleware' {
#go
description 'Middleware that parses Authorization headers and authenticates requests via bearer tokens or HMAC signatures.'
technology 'Go'
}

authenticator = component 'Authenticator' {
#go
description 'Validates credentials for login, manages SAML/OIDC SSO flows, and issues JWT session tokens.'
technology 'Go'
}

authorizer = component 'Authorizer' {
#go
description 'Enforces role-based access control by checking user permissions against requested resources.'
technology 'Go'
}

// ─── REST API Handlers ─────────────────────────────────────

restApi = component 'REST API (v2)' {
#go
description 'HTTP handler functions implementing the BloodHound v2 REST API for graph queries, search, data upload, user management, and configuration.'
technology 'Go'
}

// ─── Background Daemons ────────────────────────────────────

apiDaemon = daemon 'API Daemon' {
description 'Hosts the HTTP server, listens for incoming connections, and serves the REST API and static UI assets.'
technology 'Go / net/http'
}

datapipeDaemon = daemon 'DataPipe Daemon' {
description 'Periodic loop that orchestrates the data pipeline: purge → ingest → analyze. Drives all data processing on a configurable tick interval.'
technology 'Go'
}

gcDaemon = daemon 'Data Pruning Daemon' {
description 'Daily background task that sweeps expired sessions and stale asset-group collections.'
technology 'Go'
}

changelogDaemon = daemon 'Changelog Daemon' {
description 'Tracks graph database changes and records a changelog of mutations for audit and incremental processing.'
technology 'Go'
}

// ─── Core Services ─────────────────────────────────────────

graphifyService = service 'Graphify Service' {
#go
description 'Transforms ingested JSON data into graph nodes and edges, writing them into the graph database.'
technology 'Go'
}

analysisService = service 'Analysis Service' {
#go
description 'Runs post-processing analysis on graph data including AD and Azure attack-path computation, ADCS analysis, and tier-zero identification.'
technology 'Go'
}

fileIngestService = service 'File Ingest Service' {
#go
description 'Handles uploaded data files (JSON/ZIP), validates them against the ingest schema, and queues them as ingest tasks.'
technology 'Go'
}

graphQueryService = service 'Graph Query Service' {
#go
description 'Executes Cypher queries against the graph database with caching, complexity limits, and result formatting.'
technology 'Go'
}

jobService = service 'Job Service' {
#go
description 'Manages background job lifecycle: creation, status tracking, timeout, and completion of ingest and analysis jobs.'
technology 'Go'
}

agiService = service 'Asset Group Isolation Service' {
#go
description 'Collects asset group membership from graph nodes based on system and user tags, and records isolation collections for each asset group.'
technology 'Go'
}

dataQualityService = service 'Data Quality Service' {
#go
description 'Computes and persists Active Directory and Azure data quality statistics and aggregations after each analysis run.'
technology 'Go'
}

openGraphSchemaService = service 'OpenGraph Schema Service' {
#go
description 'Manages custom graph schema extensions: CRUD operations for user-defined node kinds and relationship types, with graph database kind synchronization.'
technology 'Go'
}

// ─── Data Access ───────────────────────────────────────────

databaseClient = library 'Database Client' {
#go
description 'Abstraction layer providing typed queries against the PostgreSQL relational database via GORM.'
technology 'Go / GORM'
}

graphClient = library 'Graph Client (DAWGS)' {
#go
description 'DAWGS-based abstraction for graph database operations, supporting Neo4j and PostgreSQL graph backends.'
technology 'Go / DAWGS'
}
}
}

49 changes: 49 additions & 0 deletions architecture/model/bloodhound.c4
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// BloodHound Community Edition - Top-Level System & Containers
// Defines the BloodHound system boundary and its primary containers.

model {

bloodhound = system 'BloodHound' {
description 'Attack path management platform that reveals hidden relationships in Active Directory and Azure environments.'

// ─── API Server ──────────────────────────────────────────────

apiServer = container 'API Server' {
#go
description 'Go HTTP server that hosts the REST API, manages authentication, orchestrates data ingestion, and runs background daemons.'
technology 'Go'
}

// ─── Web UI ──────────────────────────────────────────────────

ui = container 'Web UI' {
#react
description 'Single-page application that provides interactive graph exploration, search, and administration interfaces.'
technology 'React / TypeScript'
style {
shape browser
}
}

// ─── Databases ───────────────────────────────────────────────

postgresql = database 'PostgreSQL' {
#relationaldb
description 'Relational database that stores application configuration, user accounts, audit logs, ingest tasks, and saved queries.'
technology 'PostgreSQL'
}

postgresqlGraph = database 'PostgreSQL (Graph)' {
#graphdb
description 'PostgreSQL-backed graph database that stores Active Directory and Azure objects as nodes with their relationships as edges for attack path analysis, using the DAWGS graph abstraction layer.'
technology 'PostgreSQL / DAWGS'
}

neo4j = database 'Neo4j' {
#graphdb
description 'Graph database that stores Active Directory and Azure objects as nodes with their relationships as edges for attack path analysis.'
technology 'Neo4j'
}
}
}

42 changes: 42 additions & 0 deletions architecture/model/external.c4
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// BloodHound Community Edition - External Systems
// Systems and actors that exist outside the BHCE codebase.

model {

// ─── Actors ──────────────────────────────────────────────────────

securityOperator = actor 'Security Operator' {
description 'Uses BloodHound to identify and remediate Active Directory and Azure attack paths.'
}

apiConsumer = actor 'API Consumer' {
description 'External tooling or scripts that interact with the BloodHound REST API.'
}

// ─── External Data Collectors ────────────────────────────────────

sharpHound = externalSystem 'SharpHound' {
#external
description 'Windows data collector that enumerates Active Directory objects, ACLs, sessions, and group memberships.'
technology 'C#'
}

azureHound = externalSystem 'AzureHound' {
#external
description 'Data collector that enumerates Azure AD / Entra ID objects, roles, and permissions.'
technology 'Go'
}

// ─── Target Environments ─────────────────────────────────────────

activeDirectory = externalSystem 'Active Directory' {
#external
description 'On-premises Microsoft Active Directory domain environment being assessed.'
}

azureAd = externalSystem 'Azure AD / Entra ID' {
#external
description 'Microsoft cloud identity service being assessed.'
}
}

113 changes: 113 additions & 0 deletions architecture/model/relationships.c4
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// BloodHound Community Edition - Relationships
// All relationships between elements in the architecture model.

model {

// ─── External Actor → System ─────────────────────────────────

securityOperator -[sync]-> bloodhound.ui 'Uses web browser'
apiConsumer -[sync]-> bloodhound.apiServer 'Calls REST API'

// ─── External Data Collectors ────────────────────────────────
// Container-level and component-level edges coexist intentionally:
// container-level edges render in context/container views,
// component-level edges render in component-level views (e.g., data-pipeline).

sharpHound -[sync]-> activeDirectory 'Enumerates AD objects'
sharpHound -[sync]-> bloodhound.apiServer 'Uploads collected data'
sharpHound -[sync]-> bloodhound.apiServer.restApi 'Uploads collected data'

azureHound -[sync]-> azureAd 'Enumerates Azure objects'
azureHound -[sync]-> bloodhound.apiServer 'Uploads collected data'
azureHound -[sync]-> bloodhound.apiServer.restApi 'Uploads collected data'

// ─── UI → API Server ────────────────────────────────────────

bloodhound.ui -[sync]-> bloodhound.apiServer 'REST API calls'

// ─── API Server → Databases ──────────────────────────────────

bloodhound.apiServer -[sync]-> bloodhound.postgresql 'Reads/writes application data'
bloodhound.apiServer -[sync]-> bloodhound.postgresqlGraph 'Reads/writes graph data'
bloodhound.apiServer -[sync]-> bloodhound.neo4j 'Reads/writes graph data'

// ─── UI Internal ─────────────────────────────────────────────

bloodhound.ui.appShell -[uses]-> bloodhound.ui.reduxStore 'Dispatches actions, reads state'
bloodhound.ui.appShell -[uses]-> bloodhound.ui.exploreView 'Routes to'
bloodhound.ui.appShell -[uses]-> bloodhound.ui.administrationView 'Routes to'
bloodhound.ui.appShell -[uses]-> bloodhound.ui.groupManagementView 'Routes to'
bloodhound.ui.appShell -[uses]-> bloodhound.ui.downloadCollectorsView 'Routes to'
bloodhound.ui.appShell -[uses]-> bloodhound.ui.privilegeZonesView 'Routes to'
bloodhound.ui.appShell -[uses]-> bloodhound.ui.apiExplorerView 'Routes to'
bloodhound.ui.appShell -[uses]-> bloodhound.ui.userProfileView 'Routes to'
bloodhound.ui.exploreView -[uses]-> bloodhound.ui.sigmaGraph 'Renders graph'
bloodhound.ui.exploreView -[uses]-> bloodhound.ui.apiClientLib 'Fetches data'
bloodhound.ui.administrationView -[uses]-> bloodhound.ui.apiClientLib 'Fetches data'
bloodhound.ui.groupManagementView -[uses]-> bloodhound.ui.apiClientLib 'Fetches data'
bloodhound.ui.downloadCollectorsView -[uses]-> bloodhound.ui.apiClientLib 'Fetches collector data'
bloodhound.ui.privilegeZonesView -[uses]-> bloodhound.ui.apiClientLib 'Manages privilege zones'
bloodhound.ui.apiExplorerView -[uses]-> bloodhound.ui.apiClientLib 'Makes API requests'
bloodhound.ui.userProfileView -[uses]-> bloodhound.ui.apiClientLib 'Fetches profile data'
bloodhound.ui.reduxStore -[uses]-> bloodhound.ui.apiClientLib 'Sagas call API'
bloodhound.ui.apiClientLib -[sync]-> bloodhound.apiServer 'HTTP requests'
bloodhound.ui.apiClientLib -[sync]-> bloodhound.apiServer.httpRouter 'HTTP requests'

// ─── External Actor → API Server Components ─────────────────

securityOperator -[sync]-> bloodhound.ui.appShell 'Uses web UI'
apiConsumer -[sync]-> bloodhound.apiServer.httpRouter 'Calls REST API'

// ─── API Server Internal ─────────────────────────────────────

// HTTP request flow
bloodhound.apiServer.apiDaemon -[uses]-> bloodhound.apiServer.httpRouter 'Serves'
bloodhound.apiServer.httpRouter -[uses]-> bloodhound.apiServer.authMiddleware 'Applies to requests'
bloodhound.apiServer.authMiddleware -[uses]-> bloodhound.apiServer.authenticator 'Validates credentials'
bloodhound.apiServer.httpRouter -[uses]-> bloodhound.apiServer.restApi 'Dispatches to handlers'
bloodhound.apiServer.restApi -[uses]-> bloodhound.apiServer.authorizer 'Checks permissions'

// REST API → services
bloodhound.apiServer.restApi -[uses]-> bloodhound.apiServer.graphQueryService 'Executes graph queries'
bloodhound.apiServer.restApi -[uses]-> bloodhound.apiServer.fileIngestService 'Handles uploads'
bloodhound.apiServer.restApi -[uses]-> bloodhound.apiServer.openGraphSchemaService 'Manages graph extensions'

// DataPipe daemon pipeline
bloodhound.apiServer.datapipeDaemon -[async]-> bloodhound.apiServer.fileIngestService 'Processes queued files'
bloodhound.apiServer.datapipeDaemon -[async]-> bloodhound.apiServer.graphifyService 'Writes to graph'
bloodhound.apiServer.datapipeDaemon -[async]-> bloodhound.apiServer.analysisService 'Triggers analysis'
bloodhound.apiServer.datapipeDaemon -[uses]-> bloodhound.apiServer.jobService 'Manages job lifecycle'

// Analysis → sub-services
bloodhound.apiServer.analysisService -[uses]-> bloodhound.apiServer.agiService 'Runs isolation collections'
bloodhound.apiServer.analysisService -[uses]-> bloodhound.apiServer.dataQualityService 'Saves data quality stats'

// Services → data access
bloodhound.apiServer.graphifyService -[uses]-> bloodhound.apiServer.graphClient 'Writes nodes/edges'
bloodhound.apiServer.analysisService -[uses]-> bloodhound.apiServer.graphClient 'Reads/writes graph'
bloodhound.apiServer.analysisService -[uses]-> bloodhound.apiServer.databaseClient 'Reads config'
bloodhound.apiServer.agiService -[uses]-> bloodhound.apiServer.graphClient 'Reads tagged nodes'
bloodhound.apiServer.agiService -[uses]-> bloodhound.apiServer.databaseClient 'Records collections'
bloodhound.apiServer.dataQualityService -[uses]-> bloodhound.apiServer.graphClient 'Computes graph stats'
bloodhound.apiServer.dataQualityService -[uses]-> bloodhound.apiServer.databaseClient 'Persists quality stats'
bloodhound.apiServer.openGraphSchemaService -[uses]-> bloodhound.apiServer.databaseClient 'Manages schema extensions'
bloodhound.apiServer.openGraphSchemaService -[uses]-> bloodhound.apiServer.graphClient 'Refreshes graph kinds'
bloodhound.apiServer.graphQueryService -[uses]-> bloodhound.apiServer.graphClient 'Executes queries'
bloodhound.apiServer.fileIngestService -[uses]-> bloodhound.apiServer.databaseClient 'Manages ingest tasks'
bloodhound.apiServer.jobService -[uses]-> bloodhound.apiServer.databaseClient 'Tracks job state'
bloodhound.apiServer.authenticator -[uses]-> bloodhound.apiServer.databaseClient 'Looks up users/tokens'
bloodhound.apiServer.authorizer -[uses]-> bloodhound.apiServer.databaseClient 'Looks up permissions'

// Changelog daemon
bloodhound.apiServer.changelogDaemon -[uses]-> bloodhound.apiServer.graphClient 'Tracks graph changes'
bloodhound.apiServer.changelogDaemon -[uses]-> bloodhound.apiServer.databaseClient 'Persists changelog'

// GC daemon
bloodhound.apiServer.gcDaemon -[uses]-> bloodhound.apiServer.databaseClient 'Sweeps expired data'

// Data access → databases
bloodhound.apiServer.databaseClient -[sync]-> bloodhound.postgresql 'SQL queries'
bloodhound.apiServer.graphClient -[sync]-> bloodhound.postgresqlGraph 'Graph operations (DAWGS)'
bloodhound.apiServer.graphClient -[sync]-> bloodhound.neo4j 'Cypher queries'
}

Loading