---
title: Google Drive Domain-Wide Delegation (DWD)
slug: docs/google-drive-domain-wide-delegation-dwd
docTags: 
createdAt: 2026-05-07T22:55:45.970Z
---

# Google Drive Domain-Wide Delegation (DWD)

:::BlockQuote
**Edition:** Enterprise only
:::

The Google Drive DWD integration scans files and comments across an entire Google Workspace domain by impersonating users via a service account, enabling org-wide scanning without individual user consent. For single-account scanning, see the Google Drive integration instead.

## Prerequisites

| Requirement            | Detail                                                     |
| ---------------------- | ---------------------------------------------------------- |
| Google Workspace plan  | Business, Enterprise, Education, or Nonprofits.            |
| Google Workspace Admin | Super Admin access to the Admin Console.                   |
| GCP project            | Owner or Editor access to a Google Cloud Platform project. |

## Configuration

DWD setup requires four phases in Google's consoles before TruffleHog can scan: create a GCP service account, enable Domain-Wide Delegation, generate a JSON key, and authorize the service account in Google Workspace. The TruffleHog configuration itself is the fifth and final step.

### Step 1: Create a GCP service account

1. In the Google Cloud Console, create or select a project.&#x20;
2. Navigate to **APIs & Services > Library** and enable the following APIs: API Purpose Google Drive API Access user Drive files. Admin SDK API List users in the domain. Required only when scanning all users.&#x20;
3. Navigate to **IAM & Admin > Service Accounts** and click **+ Create Service Account**.&#x20;
4. Name the account (e.g., trufflehog-drive-scanner) and click **Create and Continue**. Skip optional permissions and click **Done**.&#x20;

### Step 2: Enable Domain-Wide Delegation on the service account

1. Click the service account you just created.
2. Click **Advanced settings** (or **Show domain-wide delegation**).
3. Check **Enable Google Workspace Domain-Wide Delegation** and click **Save**.
4. Copy the **Client ID** — a numeric string like 123456789012345678901. You'll need it in Step 4.

### Step 3: Create a JSON key

1. In the service account details, go to the **Keys** tab.
2. Click **Add Key > Create new key**, select **JSON**, and click **Create**.
3. Save the downloaded file securely. Its contents go into the service\_account\_json field in the TruffleHog configuration.

If your organization has disabled service account key creation (the iam.disableServiceAccountKeyCreation policy), contact your GCP Organization Admin to request an exception.

### Step 4: Authorize the service account in Google Workspace

1. Go to the Google Admin Console and sign in with a **Super Admin** account.&#x20;
2. Navigate to **Security > Access and data control > API controls**.&#x20;
3. Click **Manage Domain Wide Delegation**, then **Add new**.&#x20;
4. Enter the **Client ID** from Step 2.&#x20;
5. Enter the following OAuth scopes (comma-separated, no spaces): https\://www\.googleapis.com/auth/drive.readonly,https\://www\.googleapis.com/auth/admin.directory.user.readonly&#x20;
6. Click **Authorize**.&#x20;

The admin.directory.user.readonly scope is only required when scanning all domain users. If you provide an explicit include\_users list, only drive.readonly is needed.

### Step 5: Configure TruffleHog

Local configuration supports three scoping variants depending on which users you want to scan:

- **All domain users** — requires a Super Admin email to enumerate users via the Admin SDK.
- **Specific users only** — provide an explicit list. No Super Admin needed.
- **All users except specific users** — combine domain enumeration with an exclusion list.

**All domain users**

:::BlockQuote
sources:
&#x20; \- connection:
&#x20;     "@type": type.googleapis.com/sources.GoogleDrive
&#x20;     dwd:
&#x20;       service\_account\_json: |
&#x20;         \{
&#x20;           "type": "service\_account",
&#x20;           "project\_id": "your-project-id",
&#x20;           "private\_key\_id": "...",
&#x20;           "private\_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
&#x20;           "client\_email": "your-sa\@your-project.iam.gserviceaccount.com",
&#x20;           "client\_id": "..."
&#x20;         }
&#x20;       admin\_email: "admin\@yourcompany.com"
&#x20;   name: gd-dwd
&#x20;   type: SOURCE\_TYPE\_GOOGLE\_DRIVE
&#x20;   scanPeriod: 12h
:::

**Specific users only**

:::BlockQuote
sources:
&#x20; \- connection:
&#x20;     "@type": type.googleapis.com/sources.GoogleDrive
&#x20;     dwd:
&#x20;       service\_account\_json: |
&#x20;         \{ ... }
&#x20;       include\_users:
&#x20;         \- "user1\@yourcompany.com"
&#x20;         \- "user2\@yourcompany.com"
&#x20;   name: gd-dwd-targeted
&#x20;   type: SOURCE\_TYPE\_GOOGLE\_DRIVE
&#x20;   scanPeriod: 12h
:::

**All users except specific users**

:::BlockQuote
sources:
&#x20; \- connection:
&#x20;     "@type": type.googleapis.com/sources.GoogleDrive
&#x20;     dwd:
&#x20;       service\_account\_json: |
&#x20;         \{ ... }
&#x20;       admin\_email: "admin\@yourcompany.com"
&#x20;       exclude\_users:
&#x20;         \- "service-account\@yourcompany.com"
&#x20;         \- "external-contractor\@yourcompany.com"
&#x20;   name: gd-dwd-filtered
&#x20;   type: SOURCE\_TYPE\_GOOGLE\_DRIVE
&#x20;  &#x20;
:::

## Configuration options

| Field                      | Type   | Required    | Description                                                                                                        |
| -------------------------- | ------ | ----------- | ------------------------------------------------------------------------------------------------------------------ |
| dwd.service\_account\_json | string | Yes         | Full contents of the service account JSON key file.                                                                |
| dwd.admin\_email           | string | Conditional | Super Admin email used to enumerate domain users via the Admin SDK. Required when include\_users is not specified. |
| dwd.include\_users         | list   | No          | Explicit list of user emails to scan. When set, admin\_email is not required.                                      |
| dwd.exclude\_users         | list   | No          | User emails to skip when scanning all users. Ignored when include\_users is set.                                   |

## Capabilities

| Feature                                             | Supported |
| --------------------------------------------------- | --------- |
| Org-wide scanning via impersonation                 | ✅         |
| Scan file contents (Docs, Sheets, Slides, Drawings) | ✅         |
| Scan file comments and replies                      | ✅         |
| Scan files in My Drive and Shared Drives            | ✅         |
| Shared file deduplication                           | ✅         |
| Skip suspended and archived users                   | ✅         |

## Verification checklist

After setup, confirm:

| Item                              | Where to Find It                                                  |
| --------------------------------- | ----------------------------------------------------------------- |
| Service Account JSON key          | Downloaded in Step 3.                                             |
| Client ID authorized in Workspace | Admin Console > Security > API Controls > Domain-Wide Delegation. |
| OAuth scopes match exactly        | drive.readonly and admin.directory.user.readonly.                 |
| Admin email is a Super Admin      | Admin Console > Directory > Users (check role).                   |
| DWD enabled on service account    | GCP Console > Service Account > Advanced settings.                |

## How DWD scanning works

:::BlockQuote
┌──────────────┐         ┌─────────────────┐         ┌──────────────────┐
│  TruffleHog  │ ──────> │ Service Account │ ──────> │ User's Drive     │
│              │         │ (impersonates)  │         │ (via DWD)        │
└──────────────┘         └─────────────────┘         └──────────────────┘
:::

1. **Initialization.** The source validates the configuration (service account JSON, admin email).
2. **User enumeration.** If include\_users is provided, that list is used directly. Otherwise, the Admin SDK (impersonating admin\_email) enumerates all domain users.
3. **Filtering.** Suspended, archived, and excluded users are skipped automatically.
4. **Per-user scanning.** For each user, TruffleHog creates an impersonated Drive service, lists files, and scans contents and comments. Errors on a single user don't stop the scan — it continues to the next user.

### User filtering

When scanning all users (no include\_users), users are filtered automatically based on their state:

| User state        | Behavior |
| ----------------- | -------- |
| Active            | Scanned  |
| Suspended         | Skipped  |
| Archived          | Skipped  |
| In exclude\_users | Skipped  |

When using include\_users, the list is used as-is. If a user in the list is suspended, archived, or invalid, the impersonation fails, the error is logged, and scanning continues with the next user.

### Shared file deduplication

When scanning multiple users, files shared between users are deduplicated automatically:

| File type                  | Detection           | Behavior                                    |
| -------------------------- | ------------------- | ------------------------------------------- |
| Files shared from My Drive | file.Shared == true | Scanned once, skipped for subsequent users. |
| Files in Shared Drives     | file.DriveId != ""  | Scanned once, skipped for subsequent users. |
| Private files              | Neither condition   | Scanned (appears only for one user).        |

### Google file type exports

Google-native file types are exported before scanning:

| Google file type | Exported as |
| ---------------- | ----------- |
| Google Docs      | Plain text  |
| Google Sheets    | CSV         |
| Google Slides    | Plain text  |
| Google Drawings  | PDF         |

## Notes

- Files larger than 10 MB are skipped. Empty files are also skipped.
- Google Groups, service accounts, and external users cannot be scanned. Groups don't have Drive storage, service accounts aren't in the Workspace user directory, and external users can't be impersonated.

### Troubleshooting

| Error                                    | Cause                                                        | Solution                                                                              |
| ---------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------- |
| unauthorized\_client                     | DWD scopes not authorized in Workspace Admin.                | Verify Client ID and scopes in Admin Console > API Controls > Domain-Wide Delegation. |
| Not authorized to access this resource   | Admin email is not a Super Admin.                            | Use a Super Admin email for admin\_email.                                             |
| Invalid subject / User not found         | Impersonating a non-existent user, group, or external email. | Verify the email is a valid user in the domain.                                       |
| User is suspended                        | Impersonating a suspended user.                              | Remove from include\_users; auto-filtered when scanning all users.                    |
| Service account key creation is disabled | Organization policy blocks key creation.                     | Contact your GCP Org Admin for an exception.                                          |
| Admin SDK API has not been enabled       | API not enabled in GCP.                                      | Enable Admin SDK API in GCP Console.                                                  |

## Security and data handling

- **Read-only access.** The scanner only requires drive.readonly. It cannot modify, delete, or create content in Google Drive.
- **No data persistence.** All file content is downloaded and scanned in memory. No document content is stored by TruffleHog.
- **Least-privilege scopes.** Only drive.readonly and admin.directory.user.readonly are requested.
- **Credential redaction.** Service account JSON keys are automatically redacted from log output.
- **Audit trail.** Google Workspace audit logs show impersonation events from the service account.
