Repository navigation
feat(api,diff,output): diff NDES CA and EULA; flag global-only controls in fleet files - #71
Merged
Merged
Conversation
…ls in fleet files The "Not diffed" note blamed Fleet or the token for keys that were really something else: - certificate_authorities.ndes_scep_proxy.*: CAs moved out of /config. Fetch them from /certificate_authorities and the NDES detail endpoint and merge url, admin_url, username in at the default.yml path. - mdm.end_user_license_agreement: the EULA lives at /setup_experience/eula/metadata. Compare its file name with the basename of the configured path; 404 means none uploaded and diffs as "" -> name. - windows_migration_enabled, enable_turn_on_windows_mdm_manually, apple_require_hardware_attestation, etc.: global-only (AppConfig.MDM). Fleet accepts them in a fleet file but ignores them. They now get their own warning naming the fleets that set them, instead of "Not diffed". Against live Fleet 4.93.0 the NDES and EULA settings now diff clean and the note is gone; the warning lists the four global-only keys set in fleet files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018oc93zfUqr8neLyxFh1Br2
From diff-reviewer on the previous commit: - The CA and EULA endpoints are Premium-only and answer 402 on Fleet Free. That aborted the whole fetch; 402 now leaves the settings unreported, like 403/404. - A configured NDES proxy that Fleet does not have yet was listed as "not diffed". When the CA list was read without one, its leaves are additions. - fleetctl gitops deletes the uploaded EULA when default.yml sets none (doGitOpsEULA -> DeleteEULAIfNeeded); that removal is now shown. - The global-only note no longer names only the fleets/ no-team file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018oc93zfUqr8neLyxFh1Br2
diffNDESAdded emitted configured NDES leaves as-is, so a literal password (not an env var) would be posted in the MR comment. Redact secret-looking keys the same way diffFlat does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018oc93zfUqr8neLyxFh1Br2
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
9 of 10 tasks
robbiet480
force-pushed
the
fix/not-diffed-ca-eula-global-only
branch
from
October 10, 2026 02:23
6727166 to
51daa5c
Compare
robbiet480
added a commit
that referenced
this pull request
Oct 10, 2026
#71 added unreadable() as isPermissionError plus 402. This branch makes isPermissionError match 402 itself, so AddMovedConfig uses it directly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018oc93zfUqr8neLyxFh1Br2
robbiet480
added a commit
that referenced
this pull request
Oct 10, 2026
* fix(api,diff,output): only blame the token when Fleet returns 403 Several messages said "API token lacks permission" without knowing it: - Team software/profiles/scripts and no-team policies/profiles/scripts were marked unavailable on 403 or 404 and always reported as a token problem. The flags now carry the refusing HTTP status. A 403 keeps the token message; anything else says "Fleet returned HTTP <n> for ...", and only 403s feed the "Token lacks read access" warning. - Every label at 0 hosts was added to that warning as "label host counts", though it may just mean no matching hosts. It is now its own neutral note: "Label host counts hidden: Fleet reported 0 hosts for every label." - The not-diffed note no longer suggests the token: "Not diffed (Fleet did not report these)". Fleet-maintained app categories already blamed the token only on 403. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018oc93zfUqr8neLyxFh1Br2 * fix(api): skip resources Fleet refuses with 402 instead of failing A Premium-only endpoint answers 402 on Fleet Free. isPermissionError only matched 403/404, so a 402 from a team or no-team resource aborted FetchAll instead of recording the status for the skipped-diff path. It now matches 402 too; transport errors and other statuses stay fatal. The FetchAll no-team test returns 402 for policies. Addresses CodeRabbit review on #72. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018oc93zfUqr8neLyxFh1Br2 * refactor(api): drop unreadable now that isPermissionError covers 402 #71 added unreadable() as isPermissionError plus 402. This branch makes isPermissionError match 402 itself, so AddMovedConfig uses it directly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018oc93zfUqr8neLyxFh1Br2 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The "Not diffed" note on CampusTech/fleet-gitops#177 said "Fleet does not report these, or the token cannot read them" for 7 keys. None of the 7 was really a token problem. Two settings moved out of
/config, and three are global-only controls set in fleet files, where Fleet ignores them. This PR diffs the moved settings and gives the global-only controls their own warning.Changes
internal/apiAddMovedConfigadds settings Fleet serves outside/config, at the pathsdefault.ymluses. FetchAll calls it when fetching global config.certificate_authorities.ndes_scep_proxy:url,admin_urlandusernamecome fromGET /certificate_authoritiesand/certificate_authorities/{id}. The password is write-only.mdm.end_user_license_agreement: the file name comes fromGET /setup_experience/eula/metadata. A 404 means none is uploaded and maps to"".internal/diffdiffEULAcompares the EULA by file name against the basename of the configured path. Whendefault.ymlsets no EULA, an uploaded one shows as a removal, becausefleetctl gitopsdeletes it (doGitOpsEULA).diffNDESAdded: if the CA list was read and has no NDES proxy, the configured leaves show as additions. Secret-looking keys are redacted.globalOnlyControlscovers controls that exist only onAppConfig.MDM.diffTeamConfigtakes them out of a team's controls and returns them as a newDiffResult.GlobalOnlyControlsfield. The no-team flow still diffs them against global config.internal/outputHasChangesis unchanged, so the note never changes the exit code.docs/: added the new endpoints to API-Endpoints.md and described the behavior in Architecture.md.Test plan
go build ./...go vet ./...go test -race ./...golangci-lint runreports no issuesfix/remove-global-only-controls-from-fleets: No changes detected.Invariants
GETonly — no Fleet state is mutatedFLEET_PLAN_INSECURE=1remains the only escape hatch)Follow-up
FLEET_PLAN_SHAin fleet-gitops.github/workflows/workflow.yml.References (Fleet v4.93.0, tag
fleet-v4.93.0/ 92732182)docs/Configuration/yaml-files.md:windows_enabled_and_configured,windows_entra_tenant_ids,windows_entra_client_ids,enable_turn_on_windows_mdm_manually,windows_migration_enabled,apple_require_hardware_attestationandandroid_enabled_and_configured(lines 415–423), plusapple_account_provisioning(line 595). Each entry says "Can only be configured for "All fleets" (default.yml)."server/fleet/app.go:285-333: the fields exist only on globalAppConfig.MDM; team MDM has none of them.server/service/client.goDoGitOps: these keys are written only in the global branch (incoming.TeamName == nil, lines 2282–2581). The team branch never reads them.pkg/spec/gitops.go:1324: onlyapple_account_provisioningis rejected in a fleet file. The rest are accepted and ignored.GET /teamsmdmleaves out all of them;GET /configmdmreports them.🤖 Generated with Claude Code
https://claude.ai/code/session_018oc93zfUqr8neLyxFh1Br2
Summary by CodeRabbit