Aller au contenu principal

Deploy ggshield at scale with a service account token

What is a service account token?

A Service account is a special type of API key intended to represent a non-human user that needs to authenticate and be authorized for scenarios such as secrets scanning in CI pipelines or batch processing open incidents.

Prerequisites

To create a service account token, follow the instructions in the service accounts documentation.

End-to-end overview

At a high level, a fleet-wide deployment comes down to five steps:

  1. Create a dedicated GitGuardian service account token (SAT) with the nhi:send-inventory scope.
  2. Deploy ggshield to endpoints via your MDM or config management tool, keeping it continuously enforced and updated.
  3. Install and enable the machine_scan plugin — treat it as its own compliance item.
  4. Store the SAT in a secure secret store (MDM secret variable or a dedicated secret manager). Never embed it in scripts, config files, or CLI arguments.
  5. Configure a daily scheduled job that injects the SAT at runtime as GITGUARDIAN_API_KEY (and GITGUARDIAN_INSTANCE if needed) and runs ggshield machine inventory.

Step 1 - Create the service account token

Create a dedicated SAT from a GitGuardian Account Admin account.

Required scopes:

nhi:send-inventory
honeytokens:check

These scopes are required so endpoints can send machine inventory data to GitGuardian without triggering HoneyTokens from your account.

attention
  • Use a dedicated SAT for endpoint secret protection.
  • Do not use Personal Access Tokens.
  • Do not run ggshield auth login on endpoints.
  • Do not hardcode the SAT in public scripts, packages, or documentation.

Step 2 - Install and manage ggshield with MDM

At scale, do not treat installation as a one-time script. Treat ggshield as an MDM-managed component that is continuously checked.

MDM actionWhat it should do
Audit/checkVerify ggshield is installed, the binary is trusted according to your policy, and the version is the approved/current version.
InstallDownload, verify and install the approved version, then verify the binary again.
UpdateWhen the audit detects an outdated version, remediation installs the approved newer version.

Typical binary paths

PlatformTypical path
macOS/usr/local/bin/ggshield
Linux/usr/bin/ggshield

Validate the installation with:

ggshield --version

Implementation notes

  • On macOS, validate the package and installed binary signature according to your policy.
  • On Linux, validate package checksums/signatures according to your policy.
  • For large fleets, use an internal package cache or MDM-hosted package instead of having every endpoint download independently.
  • You can track either the latest available version or an internally approved pinned version.

Step 3 - Install, manage, and update the machine scan plugin with MDM

Machine scanning must be installed and enabled before running ggshield machine inventory.

At scale, manage the machine scan plugin as its own MDM compliance item. This lets you install, verify, update, and repair drift independently from the daily inventory scan.

MDM audit model

MDM actionWhat it should check or do
Audit/checkConfirm ggshield exists. Confirm machine_scan is enabled for the user context that will run the scan. Optionally confirm the plugin version is the approved/current version.
InstallGet the approved plugin package for the endpoint architecture, verify it, install it, enable machine_scan, then verify with ggshield plugin list.
UpdateIf the plugin is missing or outdated, rerun installation.
User-context repairBecause plugin configuration is user-scoped, install/enable it for the active or target scan user, not only for root/admin.

Generic commands used by the MDM:

export GITGUARDIAN_API_KEY="<SAT_FROM_SECRET_STORE>"
export GITGUARDIAN_INSTANCE="<GITGUARDIAN_INSTANCE_URL>"
ggshield plugin install machine_scan
ggshield plugin enable machine_scan
ggshield plugin list

User-scoped installation

Plugin configuration is user-scoped. The MDM job normally runs as root/admin, but the inventory scan is often run as the logged-in user. The remediation should therefore install and enable machine scanning in the same user context used for the scan.

macOS pattern:

export GITGUARDIAN_API_KEY="<SAT_FROM_SECRET_STORE>"
export GITGUARDIAN_INSTANCE="<GITGUARDIAN_INSTANCE_URL>"

GGSHIELD_BIN="/usr/local/bin/ggshield"
loggedInUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ && !/loginwindow/ {print $3}')

# Management/root context.
"$GGSHIELD_BIN" plugin install machine_scan
"$GGSHIELD_BIN" plugin enable machine_scan

# Scan user context.
if [ -n "$loggedInUser" ] && [ "$loggedInUser" != "root" ]; then
sudo -i -u "$loggedInUser" -- "$GGSHIELD_BIN" plugin install machine_scan
sudo -i -u "$loggedInUser" -- "$GGSHIELD_BIN" plugin enable machine_scan
sudo -i -u "$loggedInUser" -- "$GGSHIELD_BIN" plugin list
fi

Linux pattern:

export GITGUARDIAN_API_KEY="<SAT_FROM_SECRET_STORE>"
export GITGUARDIAN_INSTANCE="<GITGUARDIAN_INSTANCE_URL>"

GGSHIELD_BIN="/usr/bin/ggshield"
TARGET_USER="<target-user>"

"$GGSHIELD_BIN" plugin install machine_scan
"$GGSHIELD_BIN" plugin enable machine_scan

sudo -i -u "$TARGET_USER" -- "$GGSHIELD_BIN" plugin install machine_scan
sudo -i -u "$TARGET_USER" -- "$GGSHIELD_BIN" plugin enable machine_scan
sudo -i -u "$TARGET_USER" -- "$GGSHIELD_BIN" plugin list

Implementation notes

  • If the plugin package is copied to a temporary path, make sure the target user can read it.
  • If no user is logged in, install/enable for the management context and let the next MDM run repair the user context when a user is available.
  • Keep the plugin installation job separate from the inventory scan job where possible.
  • For updates, let the MDM audit fail when the plugin is missing or outdated, then remediate by installing the approved package again.

Step 4 - Run the inventory scan securely

At scan time, ggshield needs the SAT as GITGUARDIAN_API_KEY.

Simple form:

export GITGUARDIAN_API_KEY="<SAT_FROM_SECRET_STORE>"
export GITGUARDIAN_INSTANCE="<GITGUARDIAN_INSTANCE_URL>"

ggshield machine inventory

For managed endpoints, avoid exposing the SAT in command-line arguments, logs, or files.

attention

Disable shell tracing (set -x) in any script that handles the SAT.

Step 5 - Configure MDM jobs and the scheduled task

Use the MDM to manage three separate concerns:

MDM jobPurposeNeeds SAT?Suggested recurrence
Install/enforce ggshieldInstall, verify, and update the ggshield binary.NoMDM compliance/enforcement schedule.
Install/enforce machine scan pluginInstall, verify, enable, and update machine_scan for the scan user.YesMDM compliance/enforcement schedule.
Inventory scanRun ggshield machine inventory.YesOnce per day.

Inventory scan job settings

SettingRecommendation
Script purposeRun ggshield machine inventory
FrequencyOnce per day
Run asRoot/admin for the management script
Scan userActive user for workstations, unless another context is required
Secret inputSAT injected as a secret variable, for example GGSHIELD_SAT
First rollout10-20 monitored machines
Large fleetsSplit devices into groups/schedules so scans do not all start at the same time
Success criteriaCommand exits successfully and the machine appears in the GiGuardian's Endpoints dashboard with an updated latest scan
LogsSuccess/failure, endpoint identifier, date, and scan duration if available

Why separate jobs

  • MDM compliance can repair missing/outdated components automatically.
  • Updating the binary or plugin does not require changing the scan schedule.

Optional local schedules

If MDM scheduling is not available or sufficient, local schedulers can be used. Validate this approach in your environment before broad rollout.

PlatformLocal schedulerGuidance
macOSlaunchd LaunchDaemonRun a local scan script daily. Do not put the SAT in the plist.
Linuxsystemd timerRun a local scan script daily. Use protected local credential storage only if MDM secret injection is not available.
Legacy fallbackcronUse only when MDM or native schedulers are not available.

Recurrence recommendation

Recommended default: once per day per endpoint.

  • It gives GitGuardian enough endpoint inventory freshness.
  • It should be almost transparent for most users after the first scan, thanks to caching.
  • Less frequent scans may not send enough data and can reduce visibility over secrets exposure.
  • More frequent scans are possible for specific use cases, but more than once per day is not recommended as the default policy for performance and fleet/API load reasons.

Deployment runbook

Use this checklist to track your rollout from initial setup to full fleet coverage.

PhaseActionDone when
1. Create accessCreate a dedicated GitGuardian service account token (SAT).SAT exists with scope nhi:send-inventory and honeytokens:check.
2. Install ggshieldDeploy the ggshield package through MDM, RMM, or config management.Endpoint can run ggshield --version.
3. Enable machine scanningInstall and enable the machine scan plugin.ggshield plugin list shows machine_scan for the scan user.
4. Configure authStore the SAT in the MDM/RMM secret store or another controlled secret mechanism.The scan job receives the SAT as GITGUARDIAN_API_KEY at runtime.
5. Schedule scansConfigure a daily scheduled task.ggshield machine inventory runs without user interaction.
6. Validate first groupDeploy to 10-20 monitored machines.Machines appear in the GitGuardian's Endpoints dashboard with acceptable scan performance; see Validate and roll out.
7. Scale rolloutExpand by percentage-based waves.Success/error rates stay acceptable at each wave.

After deployment

When scheduled scans succeed, findings are available in the Endpoints Protection meanu of your GitGuardian dashboard:

  • Machines — fleet KPIs and a filterable table of endpoints with latest scan time and severity summary
  • Endpoint detail — per-machine discovered secrets, scan history, and optional AI agent inventory

Use Validate and roll out for the dashboard checklist before expanding beyond your pilot group. For what each view shows, see Core concepts.