diff --git a/docs/docs.json b/docs/docs.json index 3a21acce..7b6635c1 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -116,6 +116,7 @@ "group": "OpenGraph", "pages": [ "opengraph/overview", + "opengraph/quickstart", "opengraph/requirements", "opengraph/graph-theory", "opengraph/schema", diff --git a/docs/images/opengraph/bob-and-alice.png b/docs/images/opengraph/bob-and-alice.png new file mode 100644 index 00000000..b1979bcf Binary files /dev/null and b/docs/images/opengraph/bob-and-alice.png differ diff --git a/docs/images/opengraph/bob-knows-alice.png b/docs/images/opengraph/bob-knows-alice.png new file mode 100644 index 00000000..3c532bef Binary files /dev/null and b/docs/images/opengraph/bob-knows-alice.png differ diff --git a/docs/images/opengraph/bob-manages-alice.png b/docs/images/opengraph/bob-manages-alice.png new file mode 100644 index 00000000..4e0103e1 Binary files /dev/null and b/docs/images/opengraph/bob-manages-alice.png differ diff --git a/docs/images/opengraph/bob.png b/docs/images/opengraph/bob.png new file mode 100644 index 00000000..0cdb37ae Binary files /dev/null and b/docs/images/opengraph/bob.png differ diff --git a/docs/images/opengraph/managers.png b/docs/images/opengraph/managers.png new file mode 100644 index 00000000..24d854b0 Binary files /dev/null and b/docs/images/opengraph/managers.png differ diff --git a/docs/opengraph/overview.mdx b/docs/opengraph/overview.mdx index 1562e5a8..2625b967 100644 --- a/docs/opengraph/overview.mdx +++ b/docs/opengraph/overview.mdx @@ -7,6 +7,8 @@ description: "Learn about OpenGraph in BloodHound." ## The BloodHound OpenGraph + + diff --git a/docs/opengraph/quickstart.mdx b/docs/opengraph/quickstart.mdx new file mode 100644 index 00000000..56f1623d --- /dev/null +++ b/docs/opengraph/quickstart.mdx @@ -0,0 +1,379 @@ +--- +title: OpenGraph Quickstart +description: Learn how to create and test OpenGraph data in BloodHound. +sidebarTitle: Quickstart +--- + +Applies to BloodHound Enterprise and CE + +This guide walks you through creating and testing OpenGraph data using a simple example JSON file. By following these steps, you'll learn how to: + +- Create a properly structured OpenGraph JSON file and upload it to BloodHound +- Define custom icons and colors for your node types to enhance visualization +- Validate the data using search and Cypher queries in the **Explore** page +- Remove the example data in the **Administration** > **Database Management** page when finished + +Use this guide to get hands-on experience with the OpenGraph structure and validate custom nodes and edges in BloodHound. + +## Create example data + +This example defines two custom nodes (`Manager` for Bob and `Employee` for Alice) connected by a `Manages` edge to demonstrate the structure of an OpenGraph payload. + +It also includes an optional (but recommended) `source_kind` property in the `metadata` section to facilitate easy cleanup later. + +You can expand on this example to create more complex graphs with additional nodes, edges, and properties as needed. + + + + + First, you need to define your OpenGraph payload in a JSON file. + + At minimum, every OpenGraph payload must follow this basic structure: + + ```json + { + "metadata": { + "source_kind": "EXBase" + }, + "graph": { + "nodes": [], + "edges": [] + } + } + ``` + + See the [OpenGraph schema](/opengraph/schema) for required fields and the full structure. + + 1. Create a new file called `opengraph-example.json` using a plain text editor (UTF-8 encoding). + + 1. Copy and paste the following example, which includes two nodes (`bob` as a `Manager` and `alice` as an `Employee`) connected by a `Manages` edge. + + ```json + { + "metadata": { + "source_kind": "EXBase" + }, + "graph": { + "nodes": [ + { + "id": "123", + "kinds": [ + "Manager" + ], + "properties": { + "displayname": "bob", + "property1": "property1", + "objectid": "123", + "name": "BOB" + } + }, + { + "id": "234", + "kinds": [ + "Employee" + ], + "properties": { + "displayname": "alice", + "property1": "property1", + "objectid": "234", + "name": "ALICE" + } + } + ], + "edges": [ + { + "kind": "Manages", + "start": { + "value": "123", + "match_by": "id" + }, + "end": { + "value": "234", + "match_by": "id" + } + } + ] + } + } + ``` + + The following table describes the structure and properties of the example JSON file: + + | Section | Property | Description | + |---------|----------|-------------| + | **metadata** | `source_kind` | Optional data source identifier for grouping and managing nodes (e.g., "EXBase") | + | **graph.nodes** | `id` | Unique identifier for the node | + | | `kinds` | Array of node types; the first determines the node's icon and display | + | | `properties` | Object containing node properties (e.g., `name`, `displayname`, `objectid`, and custom properties) | + | **graph.edges** | `kind` | The edge type name (e.g., "Manages") | + | | `start` | Source node reference; can match a node in this payload or any pre-existing node | + | | `end` | Target node reference; can match a node in this payload or any pre-existing node | + + + **About source kinds and node types:** + + - The `source_kind` value automatically applies to all nodes in the payload, enabling grouped management and bulk deletion in **Database Management**. Alternatively, you can add `source_kind` to individual nodes if you don't declare it in metadata. + + - Each node must have at least one `kind`. The first `kind` is the **Primary Kind** that determines which node type it is and which icon and color represents it. + + - Edges can reference nodes from different payloads. You can create all your nodes first, then create edges between them in a separate payload. + + + + **BloodHound Enterprise only:** All nodes must have at least one edge connecting them to other nodes. Nodes without any edges are [automatically removed](/opengraph/faq#why-do-opengraph-nodes-disappear-after-ingestion) by the built-in reconciliation process. Ensure every node has at least one edge pointing to or from it. + + + + + Save the `opengraph-example.json` file to a location you can easily access for uploading in the next step. + + + Use the BloodHound web interface to upload the `opengraph-example.json` file directly through the browser. + + 1. Log in to your BloodHound instance. + 1. In the left menu, click **Quick Upload**. + 1. Click the **Upload Files** screen to open a file system dialog or drag and drop the `opengraph-example.json` file. + 1. Click **Upload** and wait for the upload to complete. + + You should see a confirmation message indicating the file was successfully ingested. + + If you receive an error, validate your JSON file using a [linter](https://jsonlint.com/) and ensure all [required properties](/opengraph/requirements) are present. + + + +## Customize nodes + +To enhance the visualization of the node types on the graph and in the **Entity** panel, you can define custom icons and colors. + +This is done separately from the OpenGraph data payload and must be uploaded through the [BloodHound API](/integrations/bloodhound-api/working-with-api). Stay tuned for a more streamlined process for managing icons and colors! + + + + This example creates custom definitions for the `Manager` and `Employee` node types defined in the example JSON file. It specifies that `Manager` nodes should display with a briefcase icon in blue, and `Employee` nodes should display with a user icon in green. + + The custom type definition is a JSON object with the following structure: + + ```json + { + "custom_types": { + "Manager": { + "icon": { + "type": "font-awesome", + "name": "briefcase", + "color": "#0066CC" + } + }, + "Employee": { + "icon": { + "type": "font-awesome", + "name": "user", + "color": "#00AA00" + } + } + } + } + ``` + + The following table describes the properties in the custom type definition: + + | Property | Description | + |----------|-------------| + | `custom_types` | Object containing custom type definitions, where each key is a node type and the value defines the visualization properties for that type | + | `icon.type` | Font Awesome is the icon library used for custom icons | + | `icon.name` | Font Awesome [icon name](https://fontawesome.com/search?s=solid) (without "fa-" prefix) | + | `icon.color` | Hex color code in `#RGB` or `#RRGGBB` format (the `#` is required) | + + + Use a `POST` request to the BloodHound API to upload your custom type definitions. + + Here's an example request body for the `Manager` and `Employee` node types: + + ```bash + curl -X POST \ + https://your-bloodhound-instance/api/v2/graphs/custom_nodes \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "custom_types": { + "Manager": { + "icon": { + "type": "font-awesome", + "name": "briefcase", + "color": "#0066CC" + } + }, + "Employee": { + "icon": { + "type": "font-awesome", + "name": "user", + "color": "#00AA00" + } + } + } + }' + ``` + + After running this request, any nodes of type `Manager` or `Employee` in your graph display with the specified icons and colors. You can modify these custom type definitions as needed with a `PUT` request with updated properties. + + + +## Validate example data + +After uploading the OpenGraph example data and custom node icons/colors, it's important to validate that BloodHound ingested everything correctly and displays it as expected. + + + + Log in to your BloodHound instance and navigate to the **Explore** page. + + + + Use the **Search** features to find the example nodes and edges, and verify that properties and custom icons/colors are displayed correctly. + + + + To find nodes by display name or object ID: + + 1. Click the **Search** tab. + 1. In the search field, enter `bob` or `alice`. + 1. Select the node from the suggested search results. + 1. Click the node on the graph to view its properties in the **Entity** panel. + + **Expected results:** + + - Suggested search results include the Bob (`Manager`) and Alice (`Employee`) nodes + - Node properties and custom icons/colors display in the **Entity** panel after clicking a node on the graph + - Custom node icons and colors display on the graph (blue briefcase for Manager, green user for Employee) + + Custom icons/colors render on the graph for Cypher search only. + + A view of the custom Bob node on the graph showing properties in the Entity panel + + + To find nodes and edges by source or type: + + 1. Click the **Cypher** tab + 1. Copy and paste one of the following queries and click **Run**: + + - To find all nodes from the `EXBase` source: + + ```cypher + MATCH (n) + WHERE n:EXBase + RETURN n + ``` + **Expected results:** + + - All nodes with `source_kind` of "EXBase" display on the graph (BOB as `Manager` and ALICE as `Employee` in this example) + - Node properties and custom icons/colors display in the **Entity** panel after clicking a node on the graph + - Custom node icons and colors display on the graph (blue briefcase for Manager, green user for Employee) + + This query is useful when you have multiple node types within a single source and want to see them all at once. + + A view of the custom Bob and Alice nodes on the graph and property details for Bob in the Entity panel + + - To find all `Manager` nodes specifically: + + ```cypher + MATCH (n:Manager) + RETURN n + ``` + **Expected results:** + + - Node BOB displays on the graph with the blue briefcase icon + - Node properties and custom icons/colors display in the **Entity** panel after clicking the node on the graph + - Custom node icon and color display on the graph (blue briefcase for Manager) + + This query is useful when you want to find a specific node type, which is helpful when your source contains multiple different node types. You could also search for `Employee` nodes with `MATCH (n:Employee) RETURN n`. + + A view of the custom Manager nodes on the graph and property details for a Manager node in the Entity panel + + - To find the `Manages` edge between nodes: + + ```cypher + MATCH p=()-[:Manages]->() + RETURN p + ``` + **Expected results:** + + - Nodes BOB (`Manager`) and ALICE (`Employee`) display on the graph and are connected by the `Manages` edge from BOB to ALICE + - Custom node icons and colors display on the graph (blue briefcase for Manager, green user for Employee) + - Edge properties display in the **Entity** panel after clicking the `Manages` edge on the graph + + A view of the custom Bob and Alice nodes connected by the Manages edge on the graph and property details for the Manages edge in the Entity panel + + + + + +## Delete example data + +After you've finished testing, you should clean up your example data by deleting the example OpenGraph payload. + + + + Use the BloodHound web interface to delete nodes by `source_kind`. + + 1. Log in to your BloodHound instance. + 1. In the left menu, click **Administration** > **Database Management**. + 1. Under **All graph data**, check the **EXBase data** checkbox. + + The name of the checkbox is based on the value of the `source_kind` property in the metadata section of the example JSON file. + + 1. Click **Delete** and confirm the deletion. + + This action permanently deletes all nodes with the `EXBase` source kind, including any edges connected to those nodes. + + + Run the following Cypher query to confirm the example OpenGraph data is gone: + + ```cypher + MATCH (n) + WHERE n:EXBase + RETURN n + ``` + + You should see a `No results match your criteria` message confirming that all nodes from the EXBase source have been deleted. + + The Cypher query results may be cached. If you don't see the expected results immediately, try refreshing the **Cypher** page to clear the cache and confirm the deletion. + + + +## Troubleshooting + +This section provides solutions to common issues you may encounter when testing your OpenGraph data. + + + + - Validate your JSON using [JSONLint](https://jsonlint.com/) + - Ensure all required sections are present + - Verify that node IDs within the current payload are unique + - Check that node IDs referenced in edges match nodes either in the current payload or from pre-existing data + + + + - Ensure you correctly used the node name or object ID values in search + - Verify the upload completed successfully without errors + - Check the [file ingest logs](/collect-data/enterprise-collection/monitor#file-ingest-logs) for errors (restricted based on [user role](/manage-bloodhound/auth/users-and-roles#user-role-definitions)) + + + + - Verify the icon name is correct and does not include a prefix, such as `fa-` (see [FontAwesome](https://fontawesome.com/search?o=r&ic=free&s=solid) to confirm available icons) + - Ensure the color is in valid HEX format (#RGB or #RRGGBB) and includes the `#` symbol + - Run a `GET` request to `api/v2/graphs/custom_nodes` to confirm your BloodHound instance contains the custom type definition you want to use + + + + - Verify the edge `kind` name is spelled correctly and matches your JSON file + - Ensure the `id` values in the `start` and `end` references match your node `id` values exactly (labeled as **Object ID** in the **Entity** panel on the graph, but referenced as `id` in the payload) + - Check that both referenced nodes were created successfully + + + +## Next steps + +After you're comfortable with this process, consider: + +- Creating more complex node types with additional properties +- Testing multiple edge types between different node kinds +- Reading the [OpenGraph Schema](/opengraph/schema) documentation for advanced configurations +- Reviewing [OpenGraph Best Practices](/opengraph/best-practices) before deploying production data