---
title: Self-hosted verification
slug: docs/self-hosted-verification
docTags: 
createdAt: 2024-05-13T22:06:56.105Z
---

You can use custom verifiers to set the endpoints for enterprise or non-publicly accessible instances. This will allow TruffleHog to verify secrets against those domains.

Custom verifiers should be set at the root level of the `config.yaml` file such that they apply globally. Custom verifiers can be configured in your `config.yaml` file under the `customVerifiers` field.

We currently support the following verifiers. Use the value in the **Name** column as the verifier's `name`. Names are case-insensitive.

| Product                 | Name                                                                    | Sends the secret in `Authorization` |
| ----------------------- | ----------------------------------------------------------------------- | ----------------------------------- |
| Artifactory             | `ArtifactoryAccessToken`                                                | No                                  |
| Artifactory             | `ArtifactoryReferenceToken`                                             | Yes                                 |
| Bitbucket Data Center   | `BitbucketDataCenter`                                                   | Yes                                 |
| Confluence Data Center  | `ConfluenceDataCenter`                                                  | Yes                                 |
| Datadog                 | `DatadogApikey`, `DatadogToken`                                         | No                                  |
| GitHub                  | `Github`                                                                | Yes                                 |
| GitLab                  | `Gitlab`                                                                | Yes                                 |
| GitLab                  | `GitLabOauth2`                                                          | No                                  |
| HashiCorp Vault         | `HashiCorpVaultAuth`, `HashiCorpVaultToken`, `HashiCorpVaultBatchToken` | No                                  |
| Humio (Falcon LogScale) | `HumioAPIToken`                                                         | Yes                                 |
| Jira                    | `JiraToken`, `JiraDataCenterPAT`                                        | Yes                                 |
| Sumo Logic              | `SumoLogicKey`                                                          | Yes                                 |
| Tableau                 | `TableauPersonalAccessToken`                                            | No                                  |
| User.com                | `User`                                                                  | Yes                                 |

The last column only matters for [verification endpoints that require OAuth2](#verification-endpoints-that-require-oauth2).

## Custom verifiers

Each verifier can include one or more endpoints. TruffleHog checks secrets against your endpoints in addition to the provider's public API, if it has one (for example, `api.github.com`), and, for detectors that look for them, endpoints found alongside the secret in scanned data.

### Example config

:::CodeblockTabs
config.yaml

```yaml
trufflehogAddress: <instance-name>.api.c1.prod.trufflehog.org:8443
trufflehogScannerGroup: <scanner-group-name>
trufflehogScannerToken: thog-agent-<token>
...
customVerifiers:
# Github Enterprise Server
  - name: github
    endpoints:
    - https://github.example.com/api/v3
    
# Gitlab
  - name: gitlab
    endpoints:
    - https://example.gitlab.com

# JFrog Artifactory (self-hosted) — access token (AKCp...)
  - name: ArtifactoryAccessToken
    endpoints:
      - https://artifactory.example.com

  # JFrog Artifactory (self-hosted) — reference token variant
  - name: ArtifactoryReferenceToken
    endpoints:
      - https://artifactory.example.com

  # HashiCorp Vault — AppRole auth (role_id + secret_id)
  - name: HashiCorpVaultAuth
    endpoints:
      - https://vault.example.com

  # Jira Data Center — Personal Access Token (on-prem only, not Jira Cloud)
  - name: JiraDataCenterPAT
    endpoints:
      - https://jira.example.com

  # Confluence Data Center — Personal Access Token (on-prem only)
  - name: ConfluenceDataCenter
    endpoints:
      - https://confluence.example.com

  # Bitbucket Data Center — Personal Access Token (BBDC- prefix, on-prem only)
  - name: BitbucketDataCenter
    endpoints:
      - https://bitbucket.example.com
...
```
:::

## Verification endpoints that require OAuth2

If your verification endpoint only accepts requests that carry an OAuth2 access token, add an `auth` block to the custom verifier. TruffleHog then gets an access token from your identity provider and includes it with every verification request it sends to that endpoint.

Verification with `auth` works like this:

1. **TruffleHog gets an access token.** It logs in to your identity provider's token endpoint as a service account, using the Resource Owner Password Credentials (ROPC) grant. It reuses the token until shortly before it expires, then logs in again.
2. **TruffleHog sends the verification request.** The request is the same one the detector always sends, with the secret being verified in its usual place. TruffleHog adds one header to it, carrying the access token as `Bearer <token>`. You optionally choose that header with `tokenHeader`, and it can't be a header the detector already uses.
3. **Your endpoint checks the access token and verifies the secret**, then responds the same way the service's API would. TruffleHog reads the response exactly as it would read the real service's response.

### Example config

```yaml
customVerifiers:
# Github Enterprise Server, requiring an OAuth2 access token
  - name: github
    endpoints:
    - https://github.example.com/api/v3
    auth:
      oauth2:
        tokenEndpoint: https://idp.example.com/oauth2/token
        tokenHeader: X-Access-Token # optional
        ropc:
          username: scanner
          password: scanner-password
          clientId: trufflehog
          clientSecret: client-secret # optional
          scope: verify # optional, space-separated
```

- `tokenEndpoint`: Your identity provider's token endpoint. Must use HTTPS.
- `tokenHeader`: The header that carries the access token. Optional, defaults to `Authorization`. The default only works for detectors that don't send the secret in `Authorization`. For detectors marked "Yes" in the table above, set another header, such as `X-Access-Token`. See [Choosing tokenHeader](#choosing-tokenheader).
- `ropc`: The service account TruffleHog logs in as (`username`, `password`), your OAuth2 client (`clientId`, and `clientSecret` if it has one), and any `scope` to request, separated by spaces.

### Choosing `tokenHeader`

The access token and the secret can't share a header. Many detectors send the secret in `Authorization` (see the last column of the table above), so for those, set `tokenHeader` to another header your endpoint reads the access token from.

With the example config using a custom `tokenHeader`, the verification request looks like this:

```http
GET /api/v3/user HTTP/1.1
Host: github.example.com
Authorization: token ghp_xxxxxxxxxxxxxxxxxxxx
X-Access-Token: Bearer eyJhbGci...
```

`Authorization` carries the GitHub token being verified, as it would on any GitHub API call. `X-Access-Token` carries the OAuth2 access token.

For detectors that don't send the secret in `Authorization`, the default works and the access token arrives as `Authorization: Bearer <token>`.

### What your endpoint needs to do

- **Respond as the service's API would.** Each detector calls its usual API path under your endpoint and reads the response the usual way. For example, the GitHub verifier calls `GET <endpoint>/user` and treats a 2xx response containing the user as verified.
- **Reject a bad access token with a 5xx status, and log it.** TruffleHog can't tell a rejected access token apart from a rejected secret. Many detectors report an unexpected status such as a 5xx as a verification error, so your endpoint should do the same. Your endpoint's logs are the only place a rejected access token will show up.

### Other behavior

- When using OAuth2, TruffleHog verifies only against the endpoints you list. The provider's public API and endpoints found in scanned data are skipped.
- The access token is sent only to the hosts in that verifier's `endpoints`.
- Each detector can have only one `customVerifiers` entry when using `auth`. Versioned names such as `github.v2` count as the same detector.
- Secret analysis doesn't use custom verifiers or `auth`. `auth` applies only to verification.

## Customizing via command line

You can also set custom verifiers via our open source TruffleHog tool.

In the following example, we scan the current directory in our filesystem and pass-in two custom verifier endpoints for Github and one custom verifier endpoint for Gitlab.

:::BlockQuote
trufflehog filesystem . --verifier github=[https://github1.example.com/api/v3,https://github2.example.com/api/v3](https://github1.example.com/api/v3,https://github2.example.com/api/v3) --verifier gitlab=[https://example.gitlab.com](https://example.gitlab.com)
:::

Add `--custom-verifiers-only` to verify only against the endpoints you pass in.
