> ## Documentation Index
> Fetch the complete documentation index at: https://bloodhound.specterops.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload Extension Assets

> Upload saved queries and Privilege Zone rules for OpenHound extensions.

<img noZoom src="https://mintcdn.com/specterops/tTIczgde9H07oLXf/assets/enterprise-edition-pill-tag.svg?fit=max&auto=format&n=tTIczgde9H07oLXf&q=85&s=b682a26b342bde12302ec829e265bdb6" alt="Applies to BloodHound Enterprise" width="225" height="45" data-path="assets/enterprise-edition-pill-tag.svg" />

OpenHound extensions include saved queries and Privilege Zone rules that help you analyze the data collected from the GitHub, Jamf, and Okta extensions.

Use the OpenHound CLI to upload these assets after the matching extension definition schema is installed or verified in BloodHound.

<Note>
  In BloodHound Enterprise v9.3.0 and later, the GitHub, Jamf, and Okta extension schemas are pre-installed. Saved queries and Privilege Zone rules are still managed separately.
</Note>

## Prerequisites

Before you upload extension assets, ensure that you have done the following:

* Installed the [OpenHound CLI](/openhound/community#install-the-openhound-cli).
* Verified or installed the matching extension definition schema in [OpenGraph Extension Management](/opengraph/extensions/manage#verify-or-install-an-extension).
* Obtained the BloodHound Enterprise tenant URL and browser JWT used by the OpenHound CLI for extension asset uploads.

## Configure CLI authentication

OpenHound uses DLT configuration management for CLI asset uploads. Add the BloodHound Enterprise tenant URL to your local `~/.dlt/config.toml` file, and the browser JWT to your local `~/.dlt/secrets.toml` file.

The asset upload commands use the `destination.bloodhound` section with a URL and a JWT bearer token.

This is different from the `destination.bloodhoundenterprise` collector client configuration, which uses `token_id` and `token_key` for scheduled OpenHound collection.

<Note>
  Scheduled collector examples separate the BloodHound Enterprise destination URL into `config.toml` and keep collector client credentials in extension-specific secrets files, such as `~/.dlt/secrets_github.toml`.

  Asset upload commands run from the OpenHound CLI and read the generic `~/.dlt/config.toml` and `~/.dlt/secrets.toml` files shown below.
</Note>

To get the browser JWT, follow the [BloodHound API JWT guidance](/integrations/bloodhound-api/working-with-api#use-a-jwt%2Fbearer-token). Copy only the token value and omit the `Bearer` prefix.

```toml title="~/.dlt/config.toml" theme={null}
[destination.bloodhound]
url = "https://your-tenant.bloodhoundenterprise.io"
```

```toml title="~/.dlt/secrets.toml" theme={null}
[destination.bloodhound]
token = "your-browser-jwt"
```

<Note>
  If an existing `~/.dlt/secrets.toml` file still has `url` under `[destination.bloodhound]` from a previous OpenHound version, it continues to work, but following the new pattern is preferred. Use `config.toml` for `url` in new configurations.
</Note>

<Warning>
  Do not commit `secrets.toml` or token values to version control. Browser JWTs are short-lived and intended for user-authenticated API calls, not long-running integrations.
</Warning>

## Upload assets

You must upload saved queries and Privilege Zone rules for each extension.

Saved queries and Privilege Zone rules are stored in each extension repository in the following directories:

* `extension/saved_searches`
* `extension/privilege_zone_rules`

<Note>
  OpenHound makes uploaded saved queries public by default.
</Note>

<Steps>
  <Step title="Clone the extension repositories">
    Clone each extension repository to your local machine.

    <Tabs>
      <Tab title="GitHub">
        ```bash theme={null}
        git clone https://github.com/SpecterOps/openhound-github ~/openhound-github
        ```
      </Tab>

      <Tab title="Jamf">
        ```bash theme={null}
        git clone https://github.com/SpecterOps/openhound-jamf ~/openhound-jamf
        ```
      </Tab>

      <Tab title="Okta">
        ```bash theme={null}
        git clone https://github.com/SpecterOps/openhound-okta ~/openhound-okta
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Upload the saved queries">
    For each extension, run the upload command against the saved queries directory.

    <Tabs>
      <Tab title="GitHub">
        ```bash theme={null}
        openhound searches upload ~/openhound-github/extension/saved_searches
        ```
      </Tab>

      <Tab title="Jamf">
        ```bash theme={null}
        openhound searches upload ~/openhound-jamf/extension/saved_searches
        ```
      </Tab>

      <Tab title="Okta">
        ```bash theme={null}
        openhound searches upload ~/openhound-okta/extension/saved_searches
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Upload the Privilege Zone rules">
    For each extension, run the upload command against the Privilege Zone rules directory.

    <Tabs>
      <Tab title="GitHub">
        ```bash theme={null}
        openhound rules upload ~/openhound-github/extension/privilege_zone_rules
        ```
      </Tab>

      <Tab title="Jamf">
        ```bash theme={null}
        openhound rules upload ~/openhound-jamf/extension/privilege_zone_rules
        ```
      </Tab>

      <Tab title="Okta">
        ```bash theme={null}
        openhound rules upload ~/openhound-okta/extension/privilege_zone_rules
        ```
      </Tab>
    </Tabs>

    <Tip>
      The default upload strategy is `skip`, which leaves existing assets unchanged.

      Use `--strategy overwrite` when you need to update previously uploaded saved queries or Privilege Zone rules.
    </Tip>
  </Step>
</Steps>

## Verify uploads

After the upload completes:

* Open **Explore** to confirm the saved queries are available.
* Open **Privilege Zones** to confirm the expected rules appear in the target zone.
* Wait for analysis to successfully run to verify rules that affect zone membership or findings.

## Troubleshoot

| Issue                                     | Cause                                                       | Resolution                                                                                                                                             |
| ----------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Existing assets do not update             | The `upload` command uses the `skip` strategy by default.   | Run the upload again with the `--strategy overwrite` option.                                                                                           |
| Upload fails with an authentication error | The BloodHound Enterprise URL or JWT is invalid or expired. | Verify both values; update `~/.dlt/config.toml` with a valid URL and `~/.dlt/secrets.toml` with a valid browser JWT as needed, then rerun the command. |
| No files are uploaded                     | The command points to the wrong directory.                  | Confirm that the path contains the extension assets.                                                                                                   |
