From e409f52e2131a806d58b94be6eb1b503b1d2c6af Mon Sep 17 00:00:00 2001 From: Alyx Holms Date: Mon, 23 Feb 2026 17:43:51 -0800 Subject: [PATCH 1/4] feat: starting point for architecture courtesy of Augment feat: just command for starting the likeC4 server --- architecture/likec4.config.json | 6 ++ architecture/model/api-server.c4 | 111 ++++++++++++++++++++++++++++ architecture/model/bloodhound.c4 | 43 +++++++++++ architecture/model/external.c4 | 42 +++++++++++ architecture/model/relationships.c4 | 81 ++++++++++++++++++++ architecture/model/ui.c4 | 61 +++++++++++++++ architecture/specification.c4 | 95 ++++++++++++++++++++++++ architecture/views/api-server.c4 | 41 ++++++++++ architecture/views/auth.c4 | 49 ++++++++++++ architecture/views/containers.c4 | 30 ++++++++ architecture/views/context.c4 | 32 ++++++++ architecture/views/data-pipeline.c4 | 53 +++++++++++++ architecture/views/ui.c4 | 35 +++++++++ justfile | 4 + 14 files changed, 683 insertions(+) create mode 100644 architecture/likec4.config.json create mode 100644 architecture/model/api-server.c4 create mode 100644 architecture/model/bloodhound.c4 create mode 100644 architecture/model/external.c4 create mode 100644 architecture/model/relationships.c4 create mode 100644 architecture/model/ui.c4 create mode 100644 architecture/specification.c4 create mode 100644 architecture/views/api-server.c4 create mode 100644 architecture/views/auth.c4 create mode 100644 architecture/views/containers.c4 create mode 100644 architecture/views/context.c4 create mode 100644 architecture/views/data-pipeline.c4 create mode 100644 architecture/views/ui.c4 diff --git a/architecture/likec4.config.json b/architecture/likec4.config.json new file mode 100644 index 00000000000..54e876c0e18 --- /dev/null +++ b/architecture/likec4.config.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://likec4.dev/schemas/config.json", + "name": "bhce", + "title": "BloodHound Community Edition" +} + diff --git a/architecture/model/api-server.c4 b/architecture/model/api-server.c4 new file mode 100644 index 00000000000..2d906eb85c1 --- /dev/null +++ b/architecture/model/api-server.c4 @@ -0,0 +1,111 @@ +// 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' + } + + // ─── 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' + } + } +} + diff --git a/architecture/model/bloodhound.c4 b/architecture/model/bloodhound.c4 new file mode 100644 index 00000000000..077be1a26c6 --- /dev/null +++ b/architecture/model/bloodhound.c4 @@ -0,0 +1,43 @@ +// 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' + } + + 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' + } + } +} + diff --git a/architecture/model/external.c4 b/architecture/model/external.c4 new file mode 100644 index 00000000000..e5652c46130 --- /dev/null +++ b/architecture/model/external.c4 @@ -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.' + } +} + diff --git a/architecture/model/relationships.c4 b/architecture/model/relationships.c4 new file mode 100644 index 00000000000..997242e30e7 --- /dev/null +++ b/architecture/model/relationships.c4 @@ -0,0 +1,81 @@ +// 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 ──────────────────────────────── + + sharpHound -[sync]-> activeDirectory 'Enumerates AD objects' + sharpHound -[sync]-> bloodhound.apiServer 'Uploads collected data' + + azureHound -[sync]-> azureAd 'Enumerates Azure objects' + azureHound -[sync]-> bloodhound.apiServer '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.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.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.reduxStore -[uses]-> bloodhound.ui.apiClientLib 'Sagas call API' + bloodhound.ui.apiClientLib -[sync]-> bloodhound.apiServer 'HTTP requests' + + // ─── 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' + + // 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' + + // 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.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.neo4j 'Cypher / graph operations' +} + diff --git a/architecture/model/ui.c4 b/architecture/model/ui.c4 new file mode 100644 index 00000000000..5119fb7f774 --- /dev/null +++ b/architecture/model/ui.c4 @@ -0,0 +1,61 @@ +// BloodHound Community Edition - Web UI Components +// Internal structure of the Web UI container. + +model { + + extend bloodhound.ui { + + // ─── Application Shell ───────────────────────────────────── + + appShell = component 'Application Shell' { + #react + description 'Root React component providing theme, routing, error boundaries, notification providers, and the main navigation bar.' + technology 'React / MUI' + } + + // ─── State Management ────────────────────────────────────── + + reduxStore = component 'Redux Store' { + #react + description 'Centralized state management using Redux Toolkit with saga middleware. Manages auth, global UI, asset groups, tier-zero, and edge info state.' + technology 'Redux Toolkit / Redux-Saga' + } + + // ─── Graph Visualization ─────────────────────────────────── + + sigmaGraph = component 'Graph Explorer' { + #react + description 'Interactive graph visualization using Sigma.js and Graphology. Renders AD/Azure nodes and edges with custom WebGL shaders, layout algorithms, and exploration controls.' + technology 'Sigma.js / Graphology / WebGL' + } + + // ─── API Client ──────────────────────────────────────────── + + apiClientLib = component 'API Client' { + #react + description 'Axios-based HTTP client that attaches bearer tokens, handles 401/403 responses, and provides typed methods for all BloodHound API endpoints.' + technology 'Axios' + } + + // ─── Feature Views ───────────────────────────────────────── + + exploreView = component 'Explore View' { + #react + description 'Primary investigation interface combining graph visualization, search, node info panels, and pathfinding queries.' + technology 'React' + } + + administrationView = component 'Administration View' { + #react + description 'User and role management, data quality statistics, database management, and application configuration pages.' + technology 'React' + } + + groupManagementView = component 'Group Management View' { + #react + description 'Asset group and tier-zero management interface for defining and organizing high-value targets.' + technology 'React' + } + } +} + diff --git a/architecture/specification.c4 b/architecture/specification.c4 new file mode 100644 index 00000000000..88a0b383086 --- /dev/null +++ b/architecture/specification.c4 @@ -0,0 +1,95 @@ +// BloodHound Community Edition - Architecture Specification +// Defines element kinds, relationship kinds, tags, and default styling. + +specification { + + // ─── Element Kinds ─────────────────────────────────────────────── + + element actor { + style { + shape person + color amber + } + } + + element externalSystem { + style { + shape rectangle + color muted + } + } + + element system { + style { + shape rectangle + color primary + } + } + + element container { + style { + shape rectangle + color secondary + } + } + + element component { + style { + shape rectangle + color secondary + } + } + + element database { + style { + shape storage + color green + } + } + + element daemon { + style { + shape rectangle + color indigo + } + } + + element service { + style { + shape rectangle + color secondary + } + } + + element library { + style { + shape rectangle + color muted + } + } + + // ─── Relationship Kinds ────────────────────────────────────────── + + relationship async { + color amber + line dotted + } + + relationship sync { + color primary + line solid + } + + relationship uses { + line dashed + } + + // ─── Tags ──────────────────────────────────────────────────────── + + tag external + tag go + tag react + tag graphdb + tag relationaldb +} + diff --git a/architecture/views/api-server.c4 b/architecture/views/api-server.c4 new file mode 100644 index 00000000000..c4ba2f65674 --- /dev/null +++ b/architecture/views/api-server.c4 @@ -0,0 +1,41 @@ +// BloodHound Community Edition - API Server Component View +// Shows the internal components of the API Server container. + +views { + + view apiServerComponents of bloodhound.apiServer { + title 'API Server Components' + description 'Internal structure of the Go API Server: daemons, HTTP layer, services, and data access.' + + include * + + style bloodhound.apiServer.apiDaemon, + bloodhound.apiServer.datapipeDaemon, + bloodhound.apiServer.gcDaemon, + bloodhound.apiServer.changelogDaemon { + color indigo + } + + style bloodhound.apiServer.httpRouter, + bloodhound.apiServer.authMiddleware, + bloodhound.apiServer.authenticator, + bloodhound.apiServer.authorizer, + bloodhound.apiServer.restApi { + color sky + } + + style bloodhound.apiServer.graphifyService, + bloodhound.apiServer.analysisService, + bloodhound.apiServer.fileIngestService, + bloodhound.apiServer.graphQueryService, + bloodhound.apiServer.jobService { + color secondary + } + + style bloodhound.apiServer.databaseClient, + bloodhound.apiServer.graphClient { + color muted + } + } +} + diff --git a/architecture/views/auth.c4 b/architecture/views/auth.c4 new file mode 100644 index 00000000000..b876175359b --- /dev/null +++ b/architecture/views/auth.c4 @@ -0,0 +1,49 @@ +// BloodHound Community Edition - Authentication Flow View +// Focused view showing the authentication and authorization components. + +views { + + view authFlow { + title 'Authentication & Authorization' + description 'How requests are authenticated (bearer tokens, HMAC, SAML, OIDC) and authorized (RBAC) within the API Server.' + + include + securityOperator, + apiConsumer, + bloodhound.ui.apiClientLib, + bloodhound.apiServer.httpRouter, + bloodhound.apiServer.authMiddleware, + bloodhound.apiServer.authenticator, + bloodhound.apiServer.authorizer, + bloodhound.apiServer.restApi, + bloodhound.apiServer.databaseClient, + bloodhound.postgresql + + style securityOperator, apiConsumer { + color amber + } + + style bloodhound.ui.apiClientLib { + color sky + } + + style bloodhound.apiServer.httpRouter { + color primary + } + + style bloodhound.apiServer.authMiddleware, + bloodhound.apiServer.authenticator, + bloodhound.apiServer.authorizer { + color red + } + + style bloodhound.apiServer.restApi { + color secondary + } + + style bloodhound.postgresql { + color green + } + } +} + diff --git a/architecture/views/containers.c4 b/architecture/views/containers.c4 new file mode 100644 index 00000000000..af3e3a2212e --- /dev/null +++ b/architecture/views/containers.c4 @@ -0,0 +1,30 @@ +// BloodHound Community Edition - Container View +// Shows the major containers within the BloodHound CE system and their interactions. + +views { + + view containers of bloodhound { + title 'Container Diagram' + description 'The main containers that make up BloodHound CE: API Server, Web UI, PostgreSQL, and Neo4j.' + + include + *, + securityOperator, + apiConsumer, + sharpHound, + azureHound + + style bloodhound.apiServer { + color primary + } + + style bloodhound.ui { + color sky + } + + style bloodhound.postgresql, bloodhound.neo4j { + color green + } + } +} + diff --git a/architecture/views/context.c4 b/architecture/views/context.c4 new file mode 100644 index 00000000000..5e688f5797e --- /dev/null +++ b/architecture/views/context.c4 @@ -0,0 +1,32 @@ +// BloodHound Community Edition - System Context View +// Shows BloodHound CE and its interactions with external actors and systems. + +views { + + view context of bloodhound { + title 'System Context' + description 'High-level view of BloodHound CE, its users, and the external systems it interacts with.' + + include + *, + securityOperator, + apiConsumer, + sharpHound, + azureHound, + activeDirectory, + azureAd + + style * { + color secondary + } + + style securityOperator, apiConsumer { + color amber + } + + style sharpHound, azureHound, activeDirectory, azureAd { + color muted + } + } +} + diff --git a/architecture/views/data-pipeline.c4 b/architecture/views/data-pipeline.c4 new file mode 100644 index 00000000000..6b527867165 --- /dev/null +++ b/architecture/views/data-pipeline.c4 @@ -0,0 +1,53 @@ +// BloodHound Community Edition - Data Pipeline View +// Focused view showing the data ingestion and analysis flow. + +views { + + view dataPipeline { + title 'Data Pipeline' + description 'How collected data flows from upload through ingestion, graphification, and analysis.' + + include + sharpHound, + azureHound, + bloodhound.apiServer.restApi, + bloodhound.apiServer.fileIngestService, + bloodhound.apiServer.datapipeDaemon, + bloodhound.apiServer.jobService, + bloodhound.apiServer.graphifyService, + bloodhound.apiServer.analysisService, + bloodhound.apiServer.changelogDaemon, + bloodhound.apiServer.graphClient, + bloodhound.apiServer.databaseClient, + bloodhound.postgresql, + bloodhound.neo4j + + style sharpHound, azureHound { + color muted + } + + style bloodhound.apiServer.restApi { + color sky + } + + style bloodhound.apiServer.datapipeDaemon { + color indigo + } + + style bloodhound.apiServer.fileIngestService, + bloodhound.apiServer.graphifyService, + bloodhound.apiServer.analysisService, + bloodhound.apiServer.jobService { + color secondary + } + + style bloodhound.apiServer.changelogDaemon { + color indigo + } + + style bloodhound.postgresql, bloodhound.neo4j { + color green + } + } +} + diff --git a/architecture/views/ui.c4 b/architecture/views/ui.c4 new file mode 100644 index 00000000000..8ac8e60a94e --- /dev/null +++ b/architecture/views/ui.c4 @@ -0,0 +1,35 @@ +// BloodHound Community Edition - Web UI Component View +// Shows the internal components of the Web UI container. + +views { + + view uiComponents of bloodhound.ui { + title 'Web UI Components' + description 'Internal structure of the React SPA: shell, state management, graph visualization, views, and API client.' + + include * + + style bloodhound.ui.appShell { + color primary + } + + style bloodhound.ui.reduxStore { + color indigo + } + + style bloodhound.ui.sigmaGraph { + color green + } + + style bloodhound.ui.apiClientLib { + color muted + } + + style bloodhound.ui.exploreView, + bloodhound.ui.administrationView, + bloodhound.ui.groupManagementView { + color sky + } + } +} + diff --git a/justfile b/justfile index f91417137bc..9167ca7d0af 100644 --- a/justfile +++ b/justfile @@ -177,6 +177,10 @@ reset-node-modules: @rm -r node_modules @just ensure-deps +# View Architecture Diagrams +view-architecture: + @npx -y likec4 start + # Initialize your dev environment (use "just init clean" to reset your config files) init wipe="": #!/usr/bin/env bash From a28c6dabb79657aa5c84d0e288d404fff18bc165 Mon Sep 17 00:00:00 2001 From: Alyx Holms Date: Tue, 24 Feb 2026 15:06:48 -0800 Subject: [PATCH 2/4] feat: cleaned up with proper notations and fixed views --- architecture/model/api-server.c4 | 18 ++++++++++++++++++ architecture/model/relationships.c4 | 27 +++++++++++++++++++++++++++ architecture/model/ui.c4 | 24 ++++++++++++++++++++++++ architecture/specification.c4 | 10 ++++++++++ architecture/views/api-server.c4 | 26 ++++++++------------------ architecture/views/auth.c4 | 12 +++++++----- architecture/views/data-pipeline.c4 | 17 +++++++++++------ architecture/views/ui.c4 | 13 ++++++++----- 8 files changed, 113 insertions(+), 34 deletions(-) diff --git a/architecture/model/api-server.c4 b/architecture/model/api-server.c4 index 2d906eb85c1..b3dd521fb55 100644 --- a/architecture/model/api-server.c4 +++ b/architecture/model/api-server.c4 @@ -93,6 +93,24 @@ model { 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' { diff --git a/architecture/model/relationships.c4 b/architecture/model/relationships.c4 index 997242e30e7..533cfcf91e3 100644 --- a/architecture/model/relationships.c4 +++ b/architecture/model/relationships.c4 @@ -12,9 +12,11 @@ model { 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 ──────────────────────────────────────── @@ -31,12 +33,26 @@ model { 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.apiClientLib 'Uses web UI' + apiConsumer -[sync]-> bloodhound.apiServer.httpRouter 'Calls REST API' // ─── API Server Internal ───────────────────────────────────── @@ -50,6 +66,7 @@ model { // 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' @@ -57,10 +74,20 @@ model { 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' diff --git a/architecture/model/ui.c4 b/architecture/model/ui.c4 index 5119fb7f774..a8d5b366784 100644 --- a/architecture/model/ui.c4 +++ b/architecture/model/ui.c4 @@ -56,6 +56,30 @@ model { description 'Asset group and tier-zero management interface for defining and organizing high-value targets.' technology 'React' } + + downloadCollectorsView = component 'Download Collectors View' { + #react + description 'Interface for downloading SharpHound and AzureHound collector packages for AD and Azure data collection.' + technology 'React' + } + + privilegeZonesView = component 'Privilege Zones View' { + #react + description 'Tier-zero and privilege zone management interface for defining and reviewing critical asset boundaries.' + technology 'React' + } + + apiExplorerView = component 'API Explorer View' { + #react + description 'Interactive REST API documentation and testing interface for exploring BloodHound API endpoints.' + technology 'React' + } + + userProfileView = component 'User Profile View' { + #react + description 'User profile management page for viewing and updating account settings, API keys, and two-factor authentication.' + technology 'React' + } } } diff --git a/architecture/specification.c4 b/architecture/specification.c4 index 88a0b383086..c1fe0cbadf1 100644 --- a/architecture/specification.c4 +++ b/architecture/specification.c4 @@ -1,3 +1,4 @@ + // BloodHound Community Edition - Architecture Specification // Defines element kinds, relationship kinds, tags, and default styling. @@ -6,6 +7,7 @@ specification { // ─── Element Kinds ─────────────────────────────────────────────── element actor { + notation "Human users or external actors" style { shape person color amber @@ -13,6 +15,7 @@ specification { } element externalSystem { + notation "External systems outside the codebase" style { shape rectangle color muted @@ -20,6 +23,7 @@ specification { } element system { + notation "Core BloodHound system" style { shape rectangle color primary @@ -27,6 +31,7 @@ specification { } element container { + notation "Application containers (API, UI, databases)" style { shape rectangle color secondary @@ -34,6 +39,7 @@ specification { } element component { + notation "Internal components" style { shape rectangle color secondary @@ -41,6 +47,7 @@ specification { } element database { + notation "Data storage (PostgreSQL, Neo4j)" style { shape storage color green @@ -48,6 +55,7 @@ specification { } element daemon { + notation "Background daemons" style { shape rectangle color indigo @@ -55,6 +63,7 @@ specification { } element service { + notation "Application services" style { shape rectangle color secondary @@ -62,6 +71,7 @@ specification { } element library { + notation "Shared libraries and utilities" style { shape rectangle color muted diff --git a/architecture/views/api-server.c4 b/architecture/views/api-server.c4 index c4ba2f65674..4811b3d4d89 100644 --- a/architecture/views/api-server.c4 +++ b/architecture/views/api-server.c4 @@ -4,36 +4,26 @@ views { view apiServerComponents of bloodhound.apiServer { - title 'API Server Components' - description 'Internal structure of the Go API Server: daemons, HTTP layer, services, and data access.' + title "API Server Components" + description "Internal structure of the Go API Server: daemons, HTTP layer, services, and data access." include * - style bloodhound.apiServer.apiDaemon, - bloodhound.apiServer.datapipeDaemon, - bloodhound.apiServer.gcDaemon, - bloodhound.apiServer.changelogDaemon { + style bloodhound.apiServer.apiDaemon, bloodhound.apiServer.datapipeDaemon, bloodhound.apiServer.gcDaemon, bloodhound.apiServer.changelogDaemon { color indigo } - style bloodhound.apiServer.httpRouter, - bloodhound.apiServer.authMiddleware, - bloodhound.apiServer.authenticator, - bloodhound.apiServer.authorizer, - bloodhound.apiServer.restApi { + style bloodhound.apiServer.httpRouter, bloodhound.apiServer.authMiddleware, bloodhound.apiServer.authenticator, bloodhound.apiServer.authorizer, bloodhound.apiServer.restApi { + notation "HTTP & auth layer" color sky } - style bloodhound.apiServer.graphifyService, - bloodhound.apiServer.analysisService, - bloodhound.apiServer.fileIngestService, - bloodhound.apiServer.graphQueryService, - bloodhound.apiServer.jobService { + style bloodhound.apiServer.graphifyService, bloodhound.apiServer.analysisService, bloodhound.apiServer.fileIngestService, bloodhound.apiServer.graphQueryService, bloodhound.apiServer.jobService, bloodhound.apiServer.agiService, bloodhound.apiServer.dataQualityService, bloodhound.apiServer.openGraphSchemaService { color secondary } - style bloodhound.apiServer.databaseClient, - bloodhound.apiServer.graphClient { + style bloodhound.apiServer.databaseClient, bloodhound.apiServer.graphClient { + notation "Data access layer" color muted } } diff --git a/architecture/views/auth.c4 b/architecture/views/auth.c4 index b876175359b..d5caaf5f0a9 100644 --- a/architecture/views/auth.c4 +++ b/architecture/views/auth.c4 @@ -4,8 +4,8 @@ views { view authFlow { - title 'Authentication & Authorization' - description 'How requests are authenticated (bearer tokens, HMAC, SAML, OIDC) and authorized (RBAC) within the API Server.' + title "Authentication & Authorization" + description "How requests are authenticated (bearer tokens, HMAC, SAML, OIDC) and authorized (RBAC) within the API Server." include securityOperator, @@ -24,20 +24,22 @@ views { } style bloodhound.ui.apiClientLib { + notation "API client library" color sky } style bloodhound.apiServer.httpRouter { + notation "HTTP router" color primary } - style bloodhound.apiServer.authMiddleware, - bloodhound.apiServer.authenticator, - bloodhound.apiServer.authorizer { + style bloodhound.apiServer.authMiddleware, bloodhound.apiServer.authenticator, bloodhound.apiServer.authorizer { + notation "Auth component" color red } style bloodhound.apiServer.restApi { + notation "REST API handler" color secondary } diff --git a/architecture/views/data-pipeline.c4 b/architecture/views/data-pipeline.c4 index 6b527867165..3664af7ea35 100644 --- a/architecture/views/data-pipeline.c4 +++ b/architecture/views/data-pipeline.c4 @@ -4,8 +4,8 @@ views { view dataPipeline { - title 'Data Pipeline' - description 'How collected data flows from upload through ingestion, graphification, and analysis.' + title "Data Pipeline" + description "How collected data flows from upload through ingestion, graphification, and analysis." include sharpHound, @@ -16,6 +16,8 @@ views { bloodhound.apiServer.jobService, bloodhound.apiServer.graphifyService, bloodhound.apiServer.analysisService, + bloodhound.apiServer.agiService, + bloodhound.apiServer.dataQualityService, bloodhound.apiServer.changelogDaemon, bloodhound.apiServer.graphClient, bloodhound.apiServer.databaseClient, @@ -27,6 +29,7 @@ views { } style bloodhound.apiServer.restApi { + notation "REST API endpoint" color sky } @@ -34,10 +37,7 @@ views { color indigo } - style bloodhound.apiServer.fileIngestService, - bloodhound.apiServer.graphifyService, - bloodhound.apiServer.analysisService, - bloodhound.apiServer.jobService { + style bloodhound.apiServer.fileIngestService, bloodhound.apiServer.graphifyService, bloodhound.apiServer.analysisService, bloodhound.apiServer.jobService, bloodhound.apiServer.agiService, bloodhound.apiServer.dataQualityService { color secondary } @@ -45,6 +45,11 @@ views { color indigo } + style bloodhound.apiServer.databaseClient, bloodhound.apiServer.graphClient { + notation "Data access layer" + color muted + } + style bloodhound.postgresql, bloodhound.neo4j { color green } diff --git a/architecture/views/ui.c4 b/architecture/views/ui.c4 index 8ac8e60a94e..15ea9d11289 100644 --- a/architecture/views/ui.c4 +++ b/architecture/views/ui.c4 @@ -4,30 +4,33 @@ views { view uiComponents of bloodhound.ui { - title 'Web UI Components' - description 'Internal structure of the React SPA: shell, state management, graph visualization, views, and API client.' + title "Web UI Components" + description "Internal structure of the React SPA: shell, state management, graph visualization, views, and API client." include * style bloodhound.ui.appShell { + notation "Application shell" color primary } style bloodhound.ui.reduxStore { + notation "State management" color indigo } style bloodhound.ui.sigmaGraph { + notation "Graph visualization" color green } style bloodhound.ui.apiClientLib { + notation "API client library" color muted } - style bloodhound.ui.exploreView, - bloodhound.ui.administrationView, - bloodhound.ui.groupManagementView { + style bloodhound.ui.exploreView, bloodhound.ui.administrationView, bloodhound.ui.groupManagementView, bloodhound.ui.downloadCollectorsView, bloodhound.ui.privilegeZonesView, bloodhound.ui.apiExplorerView, bloodhound.ui.userProfileView { + notation "Feature view" color sky } } From 9fbf41516946da61352f12c25b0eca59ea79802d Mon Sep 17 00:00:00 2001 From: Alyx Holms Date: Tue, 24 Feb 2026 15:37:53 -0800 Subject: [PATCH 3/4] fix: resolve CR feedback --- architecture/model/relationships.c4 | 2 +- justfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/architecture/model/relationships.c4 b/architecture/model/relationships.c4 index 533cfcf91e3..7cd3b0195c3 100644 --- a/architecture/model/relationships.c4 +++ b/architecture/model/relationships.c4 @@ -51,7 +51,7 @@ model { // ─── External Actor → API Server Components ───────────────── - securityOperator -[sync]-> bloodhound.ui.apiClientLib 'Uses web UI' + securityOperator -[sync]-> bloodhound.ui.appShell 'Uses web UI' apiConsumer -[sync]-> bloodhound.apiServer.httpRouter 'Calls REST API' // ─── API Server Internal ───────────────────────────────────── diff --git a/justfile b/justfile index 9167ca7d0af..8d72d888f57 100644 --- a/justfile +++ b/justfile @@ -179,7 +179,7 @@ reset-node-modules: # View Architecture Diagrams view-architecture: - @npx -y likec4 start + @npx -y likec4@1.48.0 start # Initialize your dev environment (use "just init clean" to reset your config files) init wipe="": From a189ce620730daedd1c3ebf6d38c30c0bdad0088 Mon Sep 17 00:00:00 2001 From: Alyx Holms Date: Tue, 24 Feb 2026 15:54:35 -0800 Subject: [PATCH 4/4] fix: graph database references --- architecture/model/bloodhound.c4 | 6 ++++++ architecture/model/relationships.c4 | 7 ++++++- architecture/views/containers.c4 | 4 ++-- architecture/views/data-pipeline.c4 | 3 ++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/architecture/model/bloodhound.c4 b/architecture/model/bloodhound.c4 index 077be1a26c6..4b913087da2 100644 --- a/architecture/model/bloodhound.c4 +++ b/architecture/model/bloodhound.c4 @@ -33,6 +33,12 @@ model { 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.' diff --git a/architecture/model/relationships.c4 b/architecture/model/relationships.c4 index 7cd3b0195c3..892a0572d54 100644 --- a/architecture/model/relationships.c4 +++ b/architecture/model/relationships.c4 @@ -9,6 +9,9 @@ model { 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' @@ -25,6 +28,7 @@ model { // ─── 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 ───────────────────────────────────────────── @@ -103,6 +107,7 @@ model { // Data access → databases bloodhound.apiServer.databaseClient -[sync]-> bloodhound.postgresql 'SQL queries' - bloodhound.apiServer.graphClient -[sync]-> bloodhound.neo4j 'Cypher / graph operations' + bloodhound.apiServer.graphClient -[sync]-> bloodhound.postgresqlGraph 'Graph operations (DAWGS)' + bloodhound.apiServer.graphClient -[sync]-> bloodhound.neo4j 'Cypher queries' } diff --git a/architecture/views/containers.c4 b/architecture/views/containers.c4 index af3e3a2212e..e118b0e7bde 100644 --- a/architecture/views/containers.c4 +++ b/architecture/views/containers.c4 @@ -5,7 +5,7 @@ views { view containers of bloodhound { title 'Container Diagram' - description 'The main containers that make up BloodHound CE: API Server, Web UI, PostgreSQL, and Neo4j.' + description 'The main containers that make up BloodHound CE: API Server, Web UI, PostgreSQL (relational and graph), and Neo4j.' include *, @@ -22,7 +22,7 @@ views { color sky } - style bloodhound.postgresql, bloodhound.neo4j { + style bloodhound.postgresql, bloodhound.postgresqlGraph, bloodhound.neo4j { color green } } diff --git a/architecture/views/data-pipeline.c4 b/architecture/views/data-pipeline.c4 index 3664af7ea35..6471350a450 100644 --- a/architecture/views/data-pipeline.c4 +++ b/architecture/views/data-pipeline.c4 @@ -22,6 +22,7 @@ views { bloodhound.apiServer.graphClient, bloodhound.apiServer.databaseClient, bloodhound.postgresql, + bloodhound.postgresqlGraph, bloodhound.neo4j style sharpHound, azureHound { @@ -50,7 +51,7 @@ views { color muted } - style bloodhound.postgresql, bloodhound.neo4j { + style bloodhound.postgresql, bloodhound.postgresqlGraph, bloodhound.neo4j { color green } }