From 3d953c8b29354ea19675d98d85bee4f224c5a2c4 Mon Sep 17 00:00:00 2001 From: Mathieu Bellon Date: Tue, 23 Jun 2026 11:58:55 +0200 Subject: [PATCH] fix: lead with --method oob for headless auth across skills MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The setup reference documented `--method oob` as preferred for interactive headless shells, but the primary "Authenticate and verify" step led with bare `ggshield auth login` and never pointed at the headless path. Meanwhile the gitguardian-platform.md headless section and several SKILL.md troubleshooting entries told users to reach for `--method token` — two docs, two different answers for the same situation. Reconcile all auth guidance to one doctrine: interactive headless (SSH/container/devcontainer) leads with `--method oob` (ggshield 1.51.0+), `--method token` is the fallback when oob is unsupported, CI uses GITGUARDIAN_API_KEY. - ggshield-cli-setup.md (x4): add a headless pointer in the primary auth step - gitguardian-platform.md (x6): rewrite the headless section to lead with oob - scan-secrets SKILL.md: troubleshooting entry now leads with oob and fixes a stale cross-reference to a non-existent onboarding subsection - scan-machine / create-honeytokens SKILL.md: mention oob first, token fallback Co-Authored-By: Claude Opus 4.8 (1M context) --- .../references/ggshield-cli-setup.md | 2 +- .../references/gitguardian-platform.md | 10 ++- skills/create-honeytokens/SKILL.md | 2 +- .../references/ggshield-cli-setup.md | 2 +- .../references/gitguardian-platform.md | 10 ++- .../references/ggshield-cli-setup.md | 2 +- .../references/gitguardian-platform.md | 84 +++++++++++++++++++ skills/scan-machine/SKILL.md | 2 +- .../references/gitguardian-platform.md | 10 ++- skills/scan-secrets/SKILL.md | 2 +- .../references/ggshield-cli-setup.md | 2 +- .../references/gitguardian-platform.md | 10 ++- .../references/gitguardian-platform.md | 10 ++- 13 files changed, 121 insertions(+), 27 deletions(-) create mode 100644 skills/install-hooks/references/gitguardian-platform.md diff --git a/skills/check-hmsl/references/ggshield-cli-setup.md b/skills/check-hmsl/references/ggshield-cli-setup.md index 19cb2bd..425d33d 100644 --- a/skills/check-hmsl/references/ggshield-cli-setup.md +++ b/skills/check-hmsl/references/ggshield-cli-setup.md @@ -133,7 +133,7 @@ ggshield auth login --instance https://dashboard.eu1.gitguardian.com ggshield auth login --instance https:// ``` -Tell the user it opens a browser to authorize the workstation. Once they confirm it succeeded, verify: +Tell the user it opens a browser to authorize the workstation. Headless — SSH session, container, or devcontainer with no local browser? Don't lead with this; go to [Headless and CI](#headless-and-ci) and use `--method oob`. Once login succeeds, verify: ```bash ggshield api-status diff --git a/skills/check-hmsl/references/gitguardian-platform.md b/skills/check-hmsl/references/gitguardian-platform.md index 5319f9f..cec21d3 100644 --- a/skills/check-hmsl/references/gitguardian-platform.md +++ b/skills/check-hmsl/references/gitguardian-platform.md @@ -39,13 +39,15 @@ The `Token scopes:` line should now list the new scope alongside `scan`. ## Headless environments (no browser) -When the OAuth flow can't open a browser (remote SSH, sandboxed dev container, devcontainer image), use `--method token`: +When the OAuth flow can't open a local browser (remote SSH, sandboxed dev container, devcontainer image), lead with out-of-band OAuth — don't reach for a manually-created token first: -1. User creates a Personal Access Token at **https://dashboard.gitguardian.com/api/personal-access-tokens** (or the equivalent path on their instance) with the required scopes selected. -2. User runs `ggshield auth login --method token` and pastes the token at the prompt. +1. User runs `ggshield auth login --method oob` (ggshield 1.51.0+). `ggshield` prints an authorization URL. To add a scope, append `--scopes ` (e.g. `honeytokens:write`). +2. User opens the URL on any device with a browser, signs in, and pastes the code shown by the dashboard back at the prompt. 3. Verify with `ggshield api-status`. -`--method token` does not need a browser. It is the fallback when the OAuth flow can't run; the OAuth flow with `--scopes` is preferred when a browser is available because the agent can drive it end-to-end. +If `oob` is unavailable (ggshield < 1.51.0, or an instance that doesn't support it), fall back to token auth: the user creates a Personal Access Token at **https://dashboard.gitguardian.com/api/personal-access-tokens** (or the equivalent path on their instance) with the required scopes selected, then runs `ggshield auth login --method token` and pastes the token at the prompt. + +Neither method needs a local browser. Prefer `oob` over a hand-created token: it carries no manual PAT step and reuses the OAuth flow end-to-end. When a local browser *is* available, plain `ggshield auth login` (optionally with `--scopes`) is preferred because the agent can drive it without the user leaving the terminal. ## GitGuardian Instances diff --git a/skills/create-honeytokens/SKILL.md b/skills/create-honeytokens/SKILL.md index ecde7a3..9d0ee7a 100644 --- a/skills/create-honeytokens/SKILL.md +++ b/skills/create-honeytokens/SKILL.md @@ -115,7 +115,7 @@ Exit codes: `0` = honeytoken created, non-zero = error (most commonly auth / per **`403 Forbidden` / "Insufficient permissions"** — the current PAT lacks `honeytokens:write`, or the user is below **Manager** role. -The fix is the standard scope-recovery flow: `ggshield auth logout` + `ggshield auth login --scopes honeytokens:write`. See [references/gitguardian-platform.md](references/gitguardian-platform.md) for the full procedure — both commands are runnable on the user's behalf, the OAuth flow handles scope upgrade without any manual PAT creation, and the same file covers the Manager-role caveat and headless `--method token` fallback. +The fix is the standard scope-recovery flow: `ggshield auth logout` + `ggshield auth login --scopes honeytokens:write`. See [references/gitguardian-platform.md](references/gitguardian-platform.md) for the full procedure — both commands are runnable on the user's behalf, the OAuth flow handles scope upgrade without any manual PAT creation, and the same file covers the Manager-role caveat and headless login (`--method oob` first, with `--method token` as fallback). **`--type` is required** — pass `--type AWS`. No other types are supported yet (this will change). diff --git a/skills/create-honeytokens/references/ggshield-cli-setup.md b/skills/create-honeytokens/references/ggshield-cli-setup.md index 19cb2bd..425d33d 100644 --- a/skills/create-honeytokens/references/ggshield-cli-setup.md +++ b/skills/create-honeytokens/references/ggshield-cli-setup.md @@ -133,7 +133,7 @@ ggshield auth login --instance https://dashboard.eu1.gitguardian.com ggshield auth login --instance https:// ``` -Tell the user it opens a browser to authorize the workstation. Once they confirm it succeeded, verify: +Tell the user it opens a browser to authorize the workstation. Headless — SSH session, container, or devcontainer with no local browser? Don't lead with this; go to [Headless and CI](#headless-and-ci) and use `--method oob`. Once login succeeds, verify: ```bash ggshield api-status diff --git a/skills/create-honeytokens/references/gitguardian-platform.md b/skills/create-honeytokens/references/gitguardian-platform.md index 5319f9f..cec21d3 100644 --- a/skills/create-honeytokens/references/gitguardian-platform.md +++ b/skills/create-honeytokens/references/gitguardian-platform.md @@ -39,13 +39,15 @@ The `Token scopes:` line should now list the new scope alongside `scan`. ## Headless environments (no browser) -When the OAuth flow can't open a browser (remote SSH, sandboxed dev container, devcontainer image), use `--method token`: +When the OAuth flow can't open a local browser (remote SSH, sandboxed dev container, devcontainer image), lead with out-of-band OAuth — don't reach for a manually-created token first: -1. User creates a Personal Access Token at **https://dashboard.gitguardian.com/api/personal-access-tokens** (or the equivalent path on their instance) with the required scopes selected. -2. User runs `ggshield auth login --method token` and pastes the token at the prompt. +1. User runs `ggshield auth login --method oob` (ggshield 1.51.0+). `ggshield` prints an authorization URL. To add a scope, append `--scopes ` (e.g. `honeytokens:write`). +2. User opens the URL on any device with a browser, signs in, and pastes the code shown by the dashboard back at the prompt. 3. Verify with `ggshield api-status`. -`--method token` does not need a browser. It is the fallback when the OAuth flow can't run; the OAuth flow with `--scopes` is preferred when a browser is available because the agent can drive it end-to-end. +If `oob` is unavailable (ggshield < 1.51.0, or an instance that doesn't support it), fall back to token auth: the user creates a Personal Access Token at **https://dashboard.gitguardian.com/api/personal-access-tokens** (or the equivalent path on their instance) with the required scopes selected, then runs `ggshield auth login --method token` and pastes the token at the prompt. + +Neither method needs a local browser. Prefer `oob` over a hand-created token: it carries no manual PAT step and reuses the OAuth flow end-to-end. When a local browser *is* available, plain `ggshield auth login` (optionally with `--scopes`) is preferred because the agent can drive it without the user leaving the terminal. ## GitGuardian Instances diff --git a/skills/install-hooks/references/ggshield-cli-setup.md b/skills/install-hooks/references/ggshield-cli-setup.md index 19cb2bd..425d33d 100644 --- a/skills/install-hooks/references/ggshield-cli-setup.md +++ b/skills/install-hooks/references/ggshield-cli-setup.md @@ -133,7 +133,7 @@ ggshield auth login --instance https://dashboard.eu1.gitguardian.com ggshield auth login --instance https:// ``` -Tell the user it opens a browser to authorize the workstation. Once they confirm it succeeded, verify: +Tell the user it opens a browser to authorize the workstation. Headless — SSH session, container, or devcontainer with no local browser? Don't lead with this; go to [Headless and CI](#headless-and-ci) and use `--method oob`. Once login succeeds, verify: ```bash ggshield api-status diff --git a/skills/install-hooks/references/gitguardian-platform.md b/skills/install-hooks/references/gitguardian-platform.md new file mode 100644 index 0000000..cec21d3 --- /dev/null +++ b/skills/install-hooks/references/gitguardian-platform.md @@ -0,0 +1,84 @@ +# GitGuardian Platform Reference + +Shared, cross-skill reference for any skill in this repo that interacts with GitGuardian or `ggshield`. SKILL.md files point here so platform-level guidance (public docs URL pattern, auth/scope recovery, instance URLs, headless setup) lives in one place. + +## Public Documentation + +GitGuardian's public docs are at **https://docs.gitguardian.com**. The AI-agent content index is at **https://docs.gitguardian.com/llms.txt** — load it whenever you need a map of what's documented. + +**Markdown shortcut for any doc page.** When the user shares an HTML docs URL (e.g. `https://docs.gitguardian.com/internal-repositories-monitoring/dashboard`), append `.md` to fetch the same content as Markdown: + +``` +https://docs.gitguardian.com/internal-repositories-monitoring/dashboard.md +``` + +Use this instead of `WebFetch` against the HTML page — it saves tokens, avoids HTML parsing, and returns the canonical content. Applies to every page on `docs.gitguardian.com`. + +## Auth: Adding a missing scope (403 Forbidden / Insufficient permissions) + +When any `ggshield` action fails with `403 Forbidden` or "Insufficient permissions", the current PAT is valid but is missing a scope this action requires (most commonly `honeytokens:write` for `ggshield honeytoken create`). The fix is a fresh OAuth login that requests the extra scope — **no manual PAT creation in the dashboard needed**: + +```bash +ggshield auth logout +ggshield auth login --scopes # e.g. honeytokens:write +``` + +`--scopes` extends the default `scan` scope during the OAuth flow. The browser opens; the user clicks "Authorize"; ggshield writes a fresh token with both `scan` and the additional scope. + +**Run this on the user's behalf.** Both `ggshield auth logout` and `ggshield auth login --scopes ` can be executed by the agent — the user only needs to approve in the browser tab that opens. This has been confirmed to work end-to-end; offer it before asking the user to create a PAT manually in the dashboard. + +Verify with: + +```bash +ggshield api-status +``` + +The `Token scopes:` line should now list the new scope alongside `scan`. + +**If the OAuth login completes but the scope still doesn't appear in `api-status`** — the user's GitGuardian role lacks the privilege the scope confers. The token request completes with whatever scopes the workspace actually allows; missing privileges yield a token without the requested scope. Most commonly this is the **Manager** role requirement for `honeytokens:write`. Surface this to the user and ask them to have a workspace admin upgrade their seat (Settings → Members on the GitGuardian dashboard), or have a Manager-level teammate run the command instead. + +## Headless environments (no browser) + +When the OAuth flow can't open a local browser (remote SSH, sandboxed dev container, devcontainer image), lead with out-of-band OAuth — don't reach for a manually-created token first: + +1. User runs `ggshield auth login --method oob` (ggshield 1.51.0+). `ggshield` prints an authorization URL. To add a scope, append `--scopes ` (e.g. `honeytokens:write`). +2. User opens the URL on any device with a browser, signs in, and pastes the code shown by the dashboard back at the prompt. +3. Verify with `ggshield api-status`. + +If `oob` is unavailable (ggshield < 1.51.0, or an instance that doesn't support it), fall back to token auth: the user creates a Personal Access Token at **https://dashboard.gitguardian.com/api/personal-access-tokens** (or the equivalent path on their instance) with the required scopes selected, then runs `ggshield auth login --method token` and pastes the token at the prompt. + +Neither method needs a local browser. Prefer `oob` over a hand-created token: it carries no manual PAT step and reuses the OAuth flow end-to-end. When a local browser *is* available, plain `ggshield auth login` (optionally with `--scopes`) is preferred because the agent can drive it without the user leaving the terminal. + +## GitGuardian Instances + +By default `ggshield` targets **SaaS US**. To target a different instance, pass `--instance` on the *first* login (the choice persists in `ggshield`'s local config thereafter): + +```bash +# SaaS US — default, no flag needed +ggshield auth login + +# SaaS EU +ggshield auth login --instance https://dashboard.eu1.gitguardian.com + +# Self-hosted GitGuardian +ggshield auth login --instance https:// +``` + +The same `--instance` flag works on `auth login --method token`, `auth logout`, and any other auth-related subcommand. + +## CI / non-interactive contexts + +For stateless CI jobs without a persistent home directory, skip `ggshield auth login` entirely and set **`GITGUARDIAN_API_KEY`** as a pipeline secret. `ggshield` reads it directly — no on-disk config needed. This is the pattern documented for GitHub Actions, GitLab CI, CircleCI, and similar runners. + +## Role and Permission Notes + +`ggshield` actions and the GitGuardian roles / scopes they require: + +| Action | Role required | PAT scope | +|---|---|---| +| `ggshield secret scan ...` | any role (incl. Free tier) | `scan` (default) | +| `ggshield honeytoken create` / `create-with-context` | **Manager** | `scan` + `honeytokens:write` | +| `ggshield api-status`, `ggshield quota` | any role | `scan` (default) | +| `ggshield install`, `ggshield auth`, `ggshield config` | n/a (local only) | n/a | + +When in doubt about which scope a command needs, check the `Token scopes:` line of `ggshield api-status` against the command that just failed, and consult the [GitGuardian API scopes reference](https://docs.gitguardian.com/api-docs/authentication#scopes). diff --git a/skills/scan-machine/SKILL.md b/skills/scan-machine/SKILL.md index ca3971a..92702e4 100644 --- a/skills/scan-machine/SKILL.md +++ b/skills/scan-machine/SKILL.md @@ -97,7 +97,7 @@ If `ggshield --version` fails or returns < 1.45.0, follow the full **Onboarding #### Step 2 — Authenticate -If `ggshield api-status` errors, follow the full **Onboarding → Step 2 (Authenticate and verify)** section in the `scan-secrets` skill — run `ggshield auth login` (or `--method token` for headless). Return here once `ggshield api-status` reports OK. +If `ggshield api-status` errors, follow the full **Onboarding → Step 2 (Authenticate and verify)** section in the `scan-secrets` skill — run `ggshield auth login` (or `--method oob` for headless, with `--method token` as the fallback). Return here once `ggshield api-status` reports OK. #### Step 3 — Install and enable the `machine_scan` plugin diff --git a/skills/scan-machine/references/gitguardian-platform.md b/skills/scan-machine/references/gitguardian-platform.md index 5319f9f..cec21d3 100644 --- a/skills/scan-machine/references/gitguardian-platform.md +++ b/skills/scan-machine/references/gitguardian-platform.md @@ -39,13 +39,15 @@ The `Token scopes:` line should now list the new scope alongside `scan`. ## Headless environments (no browser) -When the OAuth flow can't open a browser (remote SSH, sandboxed dev container, devcontainer image), use `--method token`: +When the OAuth flow can't open a local browser (remote SSH, sandboxed dev container, devcontainer image), lead with out-of-band OAuth — don't reach for a manually-created token first: -1. User creates a Personal Access Token at **https://dashboard.gitguardian.com/api/personal-access-tokens** (or the equivalent path on their instance) with the required scopes selected. -2. User runs `ggshield auth login --method token` and pastes the token at the prompt. +1. User runs `ggshield auth login --method oob` (ggshield 1.51.0+). `ggshield` prints an authorization URL. To add a scope, append `--scopes ` (e.g. `honeytokens:write`). +2. User opens the URL on any device with a browser, signs in, and pastes the code shown by the dashboard back at the prompt. 3. Verify with `ggshield api-status`. -`--method token` does not need a browser. It is the fallback when the OAuth flow can't run; the OAuth flow with `--scopes` is preferred when a browser is available because the agent can drive it end-to-end. +If `oob` is unavailable (ggshield < 1.51.0, or an instance that doesn't support it), fall back to token auth: the user creates a Personal Access Token at **https://dashboard.gitguardian.com/api/personal-access-tokens** (or the equivalent path on their instance) with the required scopes selected, then runs `ggshield auth login --method token` and pastes the token at the prompt. + +Neither method needs a local browser. Prefer `oob` over a hand-created token: it carries no manual PAT step and reuses the OAuth flow end-to-end. When a local browser *is* available, plain `ggshield auth login` (optionally with `--scopes`) is preferred because the agent can drive it without the user leaving the terminal. ## GitGuardian Instances diff --git a/skills/scan-secrets/SKILL.md b/skills/scan-secrets/SKILL.md index 0bbd07d..13ebd9b 100644 --- a/skills/scan-secrets/SKILL.md +++ b/skills/scan-secrets/SKILL.md @@ -165,7 +165,7 @@ The three triggers most often missed: **Recursive scan hangs** — `-r` was used without `-y`. The CLI is waiting on the `Confirm recursive scan.` prompt. Re-run with `-y`. -**OAuth browser window does not open** — the environment is headless. Use `ggshield auth login --method token` instead — see **Onboarding → Headless / non-interactive environments** above. +**OAuth browser window does not open** — the environment is headless. Lead with `ggshield auth login --method oob` (ggshield 1.51.0+): it prints a URL the user opens on any device, signs in, and pastes the code back — no manually-created token. Fall back to `--method token` only if `oob` is unsupported (older ggshield, or an instance that doesn't offer it). See **Headless and CI** in [references/ggshield-cli-setup.md](references/ggshield-cli-setup.md). **Rate limiting** — free tier quota exceeded. Direct the user to check usage at https://dashboard.gitguardian.com. diff --git a/skills/scan-secrets/references/ggshield-cli-setup.md b/skills/scan-secrets/references/ggshield-cli-setup.md index 19cb2bd..425d33d 100644 --- a/skills/scan-secrets/references/ggshield-cli-setup.md +++ b/skills/scan-secrets/references/ggshield-cli-setup.md @@ -133,7 +133,7 @@ ggshield auth login --instance https://dashboard.eu1.gitguardian.com ggshield auth login --instance https:// ``` -Tell the user it opens a browser to authorize the workstation. Once they confirm it succeeded, verify: +Tell the user it opens a browser to authorize the workstation. Headless — SSH session, container, or devcontainer with no local browser? Don't lead with this; go to [Headless and CI](#headless-and-ci) and use `--method oob`. Once login succeeds, verify: ```bash ggshield api-status diff --git a/skills/scan-secrets/references/gitguardian-platform.md b/skills/scan-secrets/references/gitguardian-platform.md index 5319f9f..cec21d3 100644 --- a/skills/scan-secrets/references/gitguardian-platform.md +++ b/skills/scan-secrets/references/gitguardian-platform.md @@ -39,13 +39,15 @@ The `Token scopes:` line should now list the new scope alongside `scan`. ## Headless environments (no browser) -When the OAuth flow can't open a browser (remote SSH, sandboxed dev container, devcontainer image), use `--method token`: +When the OAuth flow can't open a local browser (remote SSH, sandboxed dev container, devcontainer image), lead with out-of-band OAuth — don't reach for a manually-created token first: -1. User creates a Personal Access Token at **https://dashboard.gitguardian.com/api/personal-access-tokens** (or the equivalent path on their instance) with the required scopes selected. -2. User runs `ggshield auth login --method token` and pastes the token at the prompt. +1. User runs `ggshield auth login --method oob` (ggshield 1.51.0+). `ggshield` prints an authorization URL. To add a scope, append `--scopes ` (e.g. `honeytokens:write`). +2. User opens the URL on any device with a browser, signs in, and pastes the code shown by the dashboard back at the prompt. 3. Verify with `ggshield api-status`. -`--method token` does not need a browser. It is the fallback when the OAuth flow can't run; the OAuth flow with `--scopes` is preferred when a browser is available because the agent can drive it end-to-end. +If `oob` is unavailable (ggshield < 1.51.0, or an instance that doesn't support it), fall back to token auth: the user creates a Personal Access Token at **https://dashboard.gitguardian.com/api/personal-access-tokens** (or the equivalent path on their instance) with the required scopes selected, then runs `ggshield auth login --method token` and pastes the token at the prompt. + +Neither method needs a local browser. Prefer `oob` over a hand-created token: it carries no manual PAT step and reuses the OAuth flow end-to-end. When a local browser *is* available, plain `ggshield auth login` (optionally with `--scopes`) is preferred because the agent can drive it without the user leaving the terminal. ## GitGuardian Instances diff --git a/skills/triage-incidents/references/gitguardian-platform.md b/skills/triage-incidents/references/gitguardian-platform.md index 5319f9f..cec21d3 100644 --- a/skills/triage-incidents/references/gitguardian-platform.md +++ b/skills/triage-incidents/references/gitguardian-platform.md @@ -39,13 +39,15 @@ The `Token scopes:` line should now list the new scope alongside `scan`. ## Headless environments (no browser) -When the OAuth flow can't open a browser (remote SSH, sandboxed dev container, devcontainer image), use `--method token`: +When the OAuth flow can't open a local browser (remote SSH, sandboxed dev container, devcontainer image), lead with out-of-band OAuth — don't reach for a manually-created token first: -1. User creates a Personal Access Token at **https://dashboard.gitguardian.com/api/personal-access-tokens** (or the equivalent path on their instance) with the required scopes selected. -2. User runs `ggshield auth login --method token` and pastes the token at the prompt. +1. User runs `ggshield auth login --method oob` (ggshield 1.51.0+). `ggshield` prints an authorization URL. To add a scope, append `--scopes ` (e.g. `honeytokens:write`). +2. User opens the URL on any device with a browser, signs in, and pastes the code shown by the dashboard back at the prompt. 3. Verify with `ggshield api-status`. -`--method token` does not need a browser. It is the fallback when the OAuth flow can't run; the OAuth flow with `--scopes` is preferred when a browser is available because the agent can drive it end-to-end. +If `oob` is unavailable (ggshield < 1.51.0, or an instance that doesn't support it), fall back to token auth: the user creates a Personal Access Token at **https://dashboard.gitguardian.com/api/personal-access-tokens** (or the equivalent path on their instance) with the required scopes selected, then runs `ggshield auth login --method token` and pastes the token at the prompt. + +Neither method needs a local browser. Prefer `oob` over a hand-created token: it carries no manual PAT step and reuses the OAuth flow end-to-end. When a local browser *is* available, plain `ggshield auth login` (optionally with `--scopes`) is preferred because the agent can drive it without the user leaving the terminal. ## GitGuardian Instances