fix(honeytoken): request the honeytokens:write scope by default - #1410
fix(honeytoken): request the honeytokens:write scope by default#1410amascia-gg wants to merge 4 commits into
Conversation
bf6a7c3 to
6026ca3
Compare
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.
6026ca3 to
e00130f
Compare
Codecov Report❌ Patch coverage is
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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
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. |
ggshield machine setupplants a honeytoken by default, but nothing in the default login path could: the token never carriedhoneytokens:write. Setup ended on the raw403body 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:
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.fix(auth): honor --scopes when the current token lacks them—auth loginreuses any still-valid token, so--scopeswas a no-op for anyone already authenticated, which made every "runauth login --scopes <scope>" message we print dead advice. Only--scopestriggers the scope lookup, and an unreadable scope list keeps the existing token.fix(machine): report unavailable protections instead of failing— setup skips planting without the scope, and doctor reportshoneytokens:write/ai-discover:sendin a new!state that prints the fix without failing the run.endpoints:sendstays required, since installing themachine_scanplugin is an explicit opt-in.feat(auth): request the honeytokens:write scope by default—honeytoken plantwas opt-in.machine setuplanded 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 setupskips planting and exits 0,honeytoken plantprints the prerequisites without touching~/.aws, and a fullmachine setupcompletes end to end. Each of the four commits passes the auth/machine/honeytoken suites on its own.🤖 Generated with Claude Code