Skip to content

fix(honeytoken): request the honeytokens:write scope by default - #1410

Open
amascia-gg wants to merge 4 commits into
mainfrom
amascia/honeytoken-write-scope
Open

fix(honeytoken): request the honeytokens:write scope by default#1410
amascia-gg wants to merge 4 commits into
mainfrom
amascia/honeytoken-write-scope

Conversation

@amascia-gg

@amascia-gg amascia-gg commented Aug 17, 2026

Copy link
Copy Markdown
Member

ggshield machine setup plants a honeytoken by default, but nothing in the default login path could: the token never carried honeytokens:write. Setup ended on the raw 403 body from the endpoint-deployments API and failed the run, which reads as a missing workspace entitlement rather than a missing token scope — so the reported fix was to ask for the honeytoken module to be enabled instead of re-authenticating.

Four independent commits, smallest blast radius first:

  1. fix(honeytoken): explain a 403 from honeytoken plant — name the three prerequisites (module enabled, Manager access, token scope) instead of printing the API body. This is the shared reconcile path, so a direct run and the root fan-out get it too.
  2. fix(auth): honor --scopes when the current token lacks themauth login reuses any still-valid token, so --scopes was a no-op for anyone already authenticated, which made every "run auth login --scopes <scope>" message we print dead advice. Only --scopes triggers the scope lookup, and an unreadable scope list keeps the existing token.
  3. fix(machine): report unavailable protections instead of failing — setup skips planting without the scope, and doctor reports honeytokens:write / ai-discover:send in a new ! state that prints the fix without failing the run. endpoints:send stays required, since installing the machine_scan plugin is an explicit opt-in.
  4. feat(auth): request the honeytokens:write scope by default⚠️ needs a second opinion, @clement-tourriere. This reverts your review call on feat(auth): request broader default scopes on login #1254 (END-309). The scope was dropped from the defaults on 10 Jun, when nothing in the default path needed it — honeytoken plant was opt-in. machine setup landed on 24 Jun and made planting default behaviour. Requesting it is safe on a workspace that cannot have it (the backend grants the subset it allows and login still succeeds with a warning), but it does put a create capability on every developer PAT, which is presumably why it went. Drop this commit and the other three still stand — the opt-in path works either way.

Verified against a token holding neither plan-gated scope: doctor marks both ! and exits non-zero only for a genuinely fixable check, machine setup skips planting and exits 0, honeytoken plant prints the prerequisites without touching ~/.aws, and a full machine setup completes end to end. Each of the four commits passes the auth/machine/honeytoken suites on its own.

🤖 Generated with Claude Code

@amascia-gg
amascia-gg requested a review from a team as a code owner August 17, 2026 08:52
@amascia-gg amascia-gg self-assigned this Aug 17, 2026
@amascia-gg
amascia-gg force-pushed the amascia/honeytoken-write-scope branch from bf6a7c3 to 6026ca3 Compare August 17, 2026 09:11
The reconcile call answers 403 when the honeytoken module is disabled, the
user is below Manager, or the token lacks `honeytokens:write`. Printing the
raw API body left the reader guessing which one it was, and reading it as a
workspace entitlement problem when a token scope was missing.

Report the three prerequisites instead, matching what `honeytoken create`
already prints. This is the shared path, so a direct run and the root
fan-out get the message too, not only `machine setup`.
`auth login` reuses any still-valid token, so `--scopes` was a no-op for
anyone already authenticated: the command printed "already authenticated"
and exited without ever requesting the scope. Every message telling a user
to run `auth login --scopes <scope>` was therefore dead advice unless they
knew to log out first.

Compare the requested scopes against the ones the token carries and fall
through to a fresh login when one is missing. Only `--scopes` triggers the
lookup, so a plain login keeps costing no extra round trip, and an
unreadable scope list keeps the token rather than forcing a needless
re-login. Comparison is on raw strings, since pygitguardian's `TokenScope`
enum does not know every scope ggshield requests.
`machine setup` plants a honeytoken by default, so a token without
`honeytokens:write` ended the run on a raw 403 and a non-zero exit. Doctor
did the same for `honeytokens:write` and `ai-discover:send`. Both are gated
on the plan, so no action on the machine can turn them green, and failing on
them gates an MDM rollout on something out of the fleet's reach.

Setup now checks the scope up front and skips planting with a message naming
the command that grants it. Doctor gains an optional check state, rendered
`!`, that still prints its fix but does not fail the run. `endpoints:send`
stays required: installing the `machine_scan` plugin is an explicit opt-in,
so a token that cannot upload endpoint data really is misconfigured.
`machine setup` plants a honeytoken by default, but the default token could
not: the scope was never requested, so the first thing a fresh install did
was hit a 403 on a protection it enables on its own.

This reverts a deliberate call. The scope was removed from the defaults in
review on #1254 (END-309) on 10 Jun, when nothing in the default path needed
it -- `honeytoken plant` was an explicit, opt-in command. `machine setup`
landed on 24 Jun and made planting default behaviour, which is what makes
the scope a default concern now. Requesting it costs nothing on a workspace
that cannot have it: the backend grants the subset it allows and the login
still succeeds, with the ungranted scopes reported.

Worth a second opinion before merge: a default `honeytokens:write` puts a
create capability on every developer PAT, which is the likely reason it was
dropped. Dropping this commit leaves the rest of the branch coherent -- the
opt-in path (`auth login --scopes honeytokens:write`) works either way.
@amascia-gg
amascia-gg force-pushed the amascia/honeytoken-write-scope branch from 6026ca3 to e00130f Compare August 17, 2026 09:42
@codecov

codecov Bot commented Aug 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.61905% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 94.07%. Comparing base (a1a7089) to head (e00130f).

Files with missing lines Patch % Lines
ggshield/cmd/honeytoken/plant.py 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1410      +/-   ##
==========================================
+ Coverage   94.04%   94.07%   +0.02%     
==========================================
  Files         200      200              
  Lines       12555    12582      +27     
==========================================
+ Hits        11807    11836      +29     
+ Misses        748      746       -2     
Flag Coverage Δ
unittests 94.07% <97.61%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@clement-tourriere

Copy link
Copy Markdown
Member

I'm not sure about that ! honeytokens:write scope is only available to admins, so even it will not directly impact users login, it will definitely not solve the ggshield machine setup issue for non admin user. honeytokens plant feature has been designed to be run as a manager, mostly via MDM ! I think we should not put it in the setup by default without redesigning honeytokens scopes or feature.
Also @jCOTINEAU , I would like your opinion on that !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants