Skip to main content
Applies to BloodHound Enterprise and Community Edition Package your OpenGraph extension definition schema, Privilege Zone rules, and saved queries in an extension bundle to install them together. An extension bundle is a ZIP archive supported in BloodHound v9.9.0 and later. This page is intended primarily for extension developers. Unless otherwise noted, the guidance below covers developing and packaging a bundle; users and administrators should see Manage extensions for installation and management workflows.

Bundle composition

A bundle supports three components:
  • Extension definition schema: Defines the extension’s graph structure, with findings and remediation guidance (if included).
  • Privilege Zone rules: Identify principals that belong to a zone. Bundles support only the built-in Tier Zero zone.
  • Saved queries: Help you explore and understand the extension’s data with contextually relevant queries.
To migrate an existing extension, update your publishing workflow to package its components in a bundle. See Migrate an extension.

Installation behavior

BloodHound Enterprise and BloodHound Community Edition accept ZIP bundles through PUT /api/v2/extensions. See the OpenGraph API index for related operations and how general saved-query endpoints apply to extension-managed queries. BloodHound installs all bundle components together. If any component fails to install, BloodHound rolls back all changes and returns error messages. No partial installation remains.
Test the complete bundle at least once, even if you test individual components during development. An error in any component causes the entire installation to fail.

ZIP archive structure

Place each component at the root of the ZIP archive. Use the exact file names shown here:
<extension-name>-v<version>.zip
schema.json
pz_rules.json
saved_queries.json
Follow these archive requirements:
  • Place each component at the archive root, using the exact file names shown above. BloodHound rejects nested files, documentation, checksums, and other extra files.
  • Include schema.json in every bundle. See Bundle composition for the requirements for pz_rules.json and saved_queries.json.
  • Include each component at most once. BloodHound rejects duplicate component names.
  • Keep each component at or below the 10 MB decompressed size limit.
  • Keep optional components separate from schema.json. BloodHound rejects a bundled schema.json that embeds pz_rules or queries.
If you omit a component when updating a bundle, BloodHound removes any existing extension-managed assets of that type. Use the existing extension definition schema format for schema.json. A schema-only bundle is valid if the file contains the required schema, node_kinds, and relationship_kinds fields and does not define relationship_findings.
If schema.json defines relationship findings, include pz_rules.json with at least one valid rule.

Privilege Zone rules

In pz_rules.json, define a JSON object with a top-level pz_rules array containing one or more Privilege Zone rules. For each rule:
  • Provide a stable key, a display name, and exactly one Cypher seed: an object that specifies the query used to identify principals.
  • Set the seed’s type to 2 and provide the Cypher query in its value field. Bundles support only Cypher-based rules.
  • Optionally, set enabled and allow_disable. Both default to true.
BloodHound associates each rule with its extension and assigns the rule to Tier Zero. Bundles do not support other zones. When you update the bundle, BloodHound uses each rule’s key to match existing rules. It updates matching rules with the values from the bundle and removes rules you omit. Uninstalling the extension also removes its rules.
pz_rules.json
array
required
Array of Privilege Zone rules. Include at least one valid rule when schema.json defines relationship findings.
string
required
Stable identifier that BloodHound uses to match the rule during extension updates. Use a nonempty value that is unique within the component and contains the extension’s namespace prefix, such as GH_.
string
required
Unique display name for the Privilege Zone rule. Provide a value that is not empty or whitespace-only.
string
Optional description of the rule’s purpose or the principals it identifies.
boolean
Whether the rule is enabled. Defaults to true. When enabled, the rule assigns matching principals to Tier Zero.
boolean
Whether users can disable the rule. Defaults to true.
array
required
Array containing exactly one Cypher seed object that identifies the principals for the rule.
integer
required
Seed type. Use 2 for a Cypher-based rule, the only supported type.
string
required
Cypher query that identifies principals for zone assignment. Provide a nonempty, valid Cypher query.

Saved queries

Best practiceAs an extension developer, you should plan to consolidate your queries under as few categories as possible and clearly determine the category nomenclature. Providing too many categories can make it difficult for users to find what they are looking for in BloodHound.The category field is a generic string, so you can specify any value. You should be careful not to make duplicative categories with spelling variations.
In saved_queries.json, define a JSON object with a top-level queries array containing one or more saved queries. Use queries as the array key. For each query:
  • Provide a stable query_key, a display name, and a Cypher query.
  • Optionally, provide a description and category.
BloodHound associates each query with its extension and makes it public and read-only. In the Saved Queries section of the Explore page, the extension name determines the option shown in the Platforms filter, and each query’s category value determines an option shown in the Categories filter. When you update the bundle, BloodHound uses each query’s query_key to match existing queries. It updates matching queries with the values from the bundle and removes queries you omit. Omitting saved_queries.json removes all existing saved queries associated with the extension. Uninstalling the extension also removes its queries.
To modify a query, publish a bundle update with the changes. To remove it, omit it from the bundle.
saved_queries.json
array
required
Array of saved queries. Include at least one query when you include saved_queries.json.
string
required
Stable identifier that BloodHound uses to match the query during extension updates. Use a nonempty value that is unique within the component and contains the extension’s namespace prefix, such as GH_.
string
required
Display name for the saved query. Provide a nonempty value that is unique within the component.
string
required
Cypher query to save. Provide a nonempty, valid Cypher query.
string
Optional description of the saved query.
string
Optional category used to organize the saved query.

Migrate an extension

BloodHound continues to support schema-only extensions. To include the supported assets with your schema, package them in an extension bundle. Increment the extension version when you migrate.
1

Prepare the components

Update each component to meet the requirements on this page.
2

Create the ZIP archive

Create a ZIP archive with the required components.
3

Test the complete bundle

Test installation with all components present. Confirm that the extension and its assets install successfully.
4

Make the updated version available

Commit the updated extension bundle or make it available through your distribution method.