Skip to content
Merged
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
10 changes: 5 additions & 5 deletions docs/analyze-data/explore/search.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ description: Search for objects and visualize relationships between them in the

After [uploading data](/get-started/quickstart/community-edition-quickstart#get-data-into-bloodhound) to BloodHound, use the **Explore** page to search for objects and visualize their relationships. The graph displays <Tooltip headline="nodes" tip="Part of the graph construct and refers to an entity in the network, such as a user, computer, group, or domain. Two nodes can be connected by an edge." cta="See the docs" href="/resources/nodes/overview">nodes</Tooltip> and <Tooltip headline="edges" tip="Part of the graph construct and refers to a relationship between two nodes, such as group membership or session information." cta="See the docs" href="/resources/edges/overview">edges</Tooltip>, helping you understand your environment and identify potential attack paths.

BloodHound supports multiple data sources, including Active Directory, Azure (Entra ID), and other identity services through [OpenGraph](/opengraph/overview). The search methods return results for all data sources.
BloodHound supports multiple data sources, including Active Directory, Azure (Entra ID), and other identity services through [OpenGraph](/opengraph/overview).

<Note>BloodHound supports all search methods for [_schema-based_](/opengraph/schema) OpenGraph data. If you're exploring _schema-less_ OpenGraph data, you can use the **Search** and **Cypher** search methods only.</Note>

The **Explore** page provides the following methods for searching for objects and visualizing their relationships:

Expand All @@ -25,8 +27,6 @@ The **Explore** page provides the following methods for searching for objects an
</Card>
</CardGroup>

<Note>BloodHound currently supports the **Search** and **Cypher** search methods for OpenGraph data, with support for Pathfinding coming soon.</Note>

Which method you choose depends on your specific use case and what you're trying to accomplish. This page describes each of the search methods in more detail and provides guidance on when to use each one.

<Tip>You can interact with objects in the [graph](#graph-view) and customize the view to explore the data more effectively, regardless of which search method you use.</Tip>
Expand Down Expand Up @@ -67,9 +67,9 @@ group:admin

## Pathfinding

The **Pathfinding** tab allows you to discover relationships between objects by finding paths between them. This is particularly useful for investigating potential attack paths in an environment.
The **Pathfinding** tab allows you to discover relationships between objects by finding paths between them. This is particularly useful for investigating potential attack paths across identity providers and cloud services in a single graph view.

<Note>BloodHound currently supports the **Search** and **Cypher** search methods for OpenGraph data, with support for Pathfinding coming soon.</Note>
<Note>Pathfinding is available for [schema-based](/opengraph/schema) OpenGraph data only.</Note>

Use cases for the pathfinding search method include:

Expand Down
4 changes: 1 addition & 3 deletions docs/opengraph/faq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ You can remove generic data by using one of the following three (3) options:

</Accordion>
<Accordion title="Do custom nodes & edges work with Search and Pathfinding?">
**Search:** Yes! As of v8.5.0, OpenGraph nodes are partially supported in the search functionality on the **Explore** page. You can search for OpenGraph nodes by display name or object ID, and visualize them in the graph with custom icons and colors. However, you cannot yet prepend search queries by OpenGraph node types.

**Pathfinding:** Not yet. OpenGraph edges are not currently supported in the **Pathfinding** tab on the **Explore** page. For pathfinding queries involving OpenGraph data, you must use the Cypher tab to query the data manually.
Yes! BloodHound supports **Search** and **Pathfinding** for [_schema-based_](/opengraph/schema) OpenGraph data. For _schema-less_ OpenGraph data, only **Search** and **Cypher** are supported. Custom node type prefixes in queries are not yet supported.
</Accordion>
<Accordion title="How can I add my project to the OpenGraph library?">
Have you built a cool project using OpenGraph and want it featured here? Already got your project in the list and need to update something? Open a ["Library Change" issue](https://github.com/SpecterOps/bloodhound-docs/issues) on the BloodHound Docs repo and we'll get it added for you!
Expand Down
63 changes: 35 additions & 28 deletions docs/opengraph/schema.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,30 @@ description: "Description of the OpenGraph JSON Schema"

<img noZoom src="/assets/enterprise-AND-community-edition-pill-tag.svg" alt="Applies to BloodHound Enterprise and CE"/>

# Schema
This page explains the JSON payload structure and minimum JSON schema requirements that BloodHound uses to ingest OpenGraph nodes and edges.

In this section, you will find all the information to create a JSON file that BloodHound can ingest and use to display your Nodes and Edges.
Terms used on this page:

The most up-to-date JSON Schema can always be found in our CE repository. Currently, the location of the node and edge schema files in our source code can be found [here](https://github.com/SpecterOps/BloodHound/tree/main/cmd/api/src/services/upload/jsonschema).
- **Schema-less (generic) data** refers to OpenGraph payloads that follow the minimum node and edge schemas described on this page.
- **Schema-based data** refers to OpenGraph payloads that use an extension-defined schema outside the payload itself.

# Ingesting Generic Formatted Data
This page focuses on the JSON requirements for schema-less (generic) data.

## File Requirements
<Tip>You can find the latest node and edge schemas in the BloodHound [source code](https://github.com/SpecterOps/BloodHound/tree/main/cmd/api/src/services/upload/jsonschema) on GitHub.</Tip>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RE: tighter definitions/descriptions

This is specifically pointing to the JSON schema for data payload files.


## Ingesting Schema-less (Generic) Data

### File Requirements

Acceptable formats: `.json`, `.zip`

You can mix file types in a single upload (e.g. Sharphound + Generic).

Compressed ZIPs containing multiple file types are supported.

## JSON Format
### Data Payload Structure

The standard BloodHound UI upload screen now accepts files in a generic format. You can continue using it as before.
The standard BloodHound UI upload screen accepts all OpenGraph payloads—both schema-less (generic) and schema-based.

At minimum, your JSON file should have these elements:

Expand All @@ -37,26 +42,28 @@ At minimum, your JSON file should have these elements:
}
```

The `nodes` and `edges` must conform to our JSON Schema, see details below. The validation of the data occurs at upload time.

When ingest completes, the generic data will be available via **Cypher search ONLY**. Generic data is not searchable via the pathfinding feature (yet).

**Entity Panels**: clicking on a generic node or edge will only render the entity’s property bag. At this time there is no support for defining entity panels for generic entities.

The `nodes` and `edges` must conform to the minimum JSON schemas (see details below). BloodHound validates that the JSON is well-formed and that nodes and edges meet these schema requirements, but it does not enforce additional structure or constraints beyond them.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is an area where we can tighten up "schema" referencing.


## Nodes
When ingest completes, you can [search](/analyze-data/explore/search) OpenGraph data. Supported search methods depend on whether the data is schema-based or schema-less:

### Property Rules
| Search method | Schema-based | Schema-less |
| --- | --- | --- |
| Node Search | <Icon icon="square-check" iconType="solid" color="#22c55e" /> | <Icon icon="square-xmark" iconType="solid" color="#ef4444" /> |
| Pathfinding | <Icon icon="square-check" iconType="solid" color="#22c55e" /> | <Icon icon="square-xmark" iconType="solid" color="#ef4444" /> |
| Cypher | <Icon icon="square-check" iconType="solid" color="#22c55e" /> | <Icon icon="square-check" iconType="solid" color="#22c55e" /> |

Properties must be primitive types or arrays of primitive types
**Entity Panels**: clicking on a node or edge will only render the entity's property bag. At this time there is no support for defining entity panels for generic entities.

Nested objects and arrays of objects are not allowed
### Nodes

Arrays must be homogeneous (e.g. all strings or all numbers)
#### Property Rules

An array of kind labels for the node. The first element is treated as the node's primary kind and is used to determine which icon to display in the graph UI. This primary kind is only used for visual representation and has no semantic significance for data processing.
- Properties must be primitive types or arrays of primitive types.
- Nested objects and arrays of objects are not allowed.
- Arrays must be homogeneous (for example, all strings or all numbers).
- An array of kind labels for the node. The first element is treated as the node's primary kind and determines which icon appears in the graph UI. This primary kind is only used for visual representation and has no semantic significance for data processing.

### Node JSON
#### Node JSON

The following is the <a href="/assets/opengraph/opengraph-node.json" download>JSON schema</a> that all nodes must conform to.

Expand Down Expand Up @@ -112,15 +119,15 @@ The following is the <a href="/assets/opengraph/opengraph-node.json" download>JS
}
```

## Edges
### Edges

Edges names cannot contain dash `-`. It is highly recommended to use Pascal Case and no special characters.

From [tuple.nl](https://www.tuple.nl/en/knowledge-base/pascal-case): Pascal Case is a naming convention used in programming where compound words are written without spaces, and each word starts with an uppercase letter. It is commonly used for naming variables, functions, classes, and other identifiers in code. Pascal Case helps create descriptive and easily distinguishable names, contributing to the clarity of your code.

See Neo4j [Naming and Conventions](https://neo4j.com/docs/cypher-manual/current/syntax/naming/) for more details.

### Edge JSON
#### Edge JSON

The following is the <a href="/assets/opengraph/opengraph-edge.json" download>JSON schema</a> that all edges must conform to.

Expand Down Expand Up @@ -247,11 +254,11 @@ The following is the <a href="/assets/opengraph/opengraph-edge.json" download>JS
}
```

### Post-processing
#### Post-processing

Post-processing in BloodHound refers to the analysis phase where the system creates certain edges after ingesting data to identify attack paths.
Post-processing in BloodHound refers to a series of steps during analysis phase where the system creates specific edges after ingesting data to enrich the graph and more accurately reflect the graph's state.

After ingesting data, BloodHound analyzes the graph state and adds edges it considers useful. BloodHound regenerates "post-processed" edges after it builds a complete graph. Before regenerating post-processed edges, BloodHound deletes any existing ones. As a result, BloodHound removes any post-processed edges that you add directly to an OpenGraph payload.
After ingesting data, BloodHound analyzes the graph state and adds edges that are essential to accurately represent the environment and support attack path analysis. BloodHound regenerates "post-processed" edges after it builds a complete graph. Before regenerating post-processed edges, BloodHound deletes any existing ones. As a result, BloodHound removes any post-processed edges that you add directly to an OpenGraph payload.

<Accordion title="Show post-processed edges">
BloodHound creates the following edges during post-processing:
Expand Down Expand Up @@ -338,9 +345,9 @@ See the following example OpenGraph payload that produces the effect:
}
```

## Optional Metadata Field
### Optional Metadata Field

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add to this section to specify that adding a source_kind via metadata is what registers that kind as a source_kind in the first place. So if they want to track data via sources, they'll need to upload a data payload with this source_kind explicitly called out at least once. It can even be a blank payload aside from the source_kind, I think (we should double check that).

Once they've done that, anytime that kind is used, it's pre-defined as a source_kind and will be treated as such.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good feedback. I'll make a note for the rewrite since it's out of scope for this PR.

FWIW, the unmerged quickstart #155 attempts to provide more details about this.


You can optionally include a metadata object at the top level of your JSON payload. This metadata currently supports a single field:
You can optionally include a metadata object at the top level of your data payload. This metadata currently supports a single field:

- `source_kind`: a string that applies to all nodes in the file, used to attribute a source to ingested nodes (e.g. Github, Snowflake, MSSQL). This is useful for tracking where a node originated. We internally use this concept already for AD/Azure, using the labels “Base” and “AZBase” respectively.

Expand All @@ -360,7 +367,7 @@ Example:

If present, the `source_kind` will be added to the `kinds` list of all nodes in the file during ingest. This feature is optional.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I specified in my earlier comment how source_kind is properly handled: https://github.com/SpecterOps/bloodhound-docs/pull/200/changes#r2855480768

The main aspect that I think we should highlight here is that – once the source_kind has been registered – the main benefit of using the metadata field is that it automatically applies the source_kind to all of the nodes in the payload.

This is accurate, but actually undesirable behavior. It should only apply the source_kind to the nodes defined within the payload, but not the ones just referenced within it. This is the source of bug behavior, and the reason we have an FAQ and workaround in place.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good feedback. I'll make a note for the rewrite since it's out of scope for this PR.


## Minimal Working JSON
### Minimal Viable Data Payload

The following is a minimal example payload that conforms to the node and edge schemas above. You can use this as a starting point to build your own OpenGraph. Copy and paste the following example into a new `.json` file or <a href="/assets/opengraph/opengraph-minimal.json" download>download this example file</a>.

Expand Down