Repository navigation
fix(devicepolicy): repair legacy Windows state permissions - #237
Merged
ashishkurmi merged 3 commits intoOct 26, 2026
Merged
ashishkurmi merged 3 commits into
ashishkurmi merged 3 commits into
Conversation
State files left by older agents inherit their parent's DACL and fail the strict metadata check, so reads report no ownership and writes, probes and clears fail. Repair a correctly owned state file's DACL under the existing cross-process lock before use, preserving its bytes, owner and records. Existing verified objects (state, lock, parent directory) are repaired with READ_CONTROL|WRITE_DAC only, so Modify-only legacy permissions no longer need ownership-change rights. Fresh creation still assigns the owner. On Windows, a marker-based clear now stops before changing configuration when the state store cannot be prepared. Unexpected target-setup and swallowed state-read failures are logged at Warn, redacted. macOS/Linux behavior is unchanged.
There was a problem hiding this comment.
🔵 Needs a closer look
Security-sensitive Windows permission and clear-path changes still need the native lifecycle, peer-lock, and smoke validation marked pending in the PR description.
No open issues 🎉
What changed in this PR
This PR restores access to legacy Windows device-policy state by repairing permissions on owner-verified files without changing their contents or ownership.
Changes:
- Adds permission-only repair for existing state files, lock files, and parent directories.
- Integrates locked state preparation into cache operations and blocks marker-based clears when Windows state is unreadable.
- Adds redacted warnings and regression tests for permission repair, state preservation, and clear behavior.
| File | Description |
|---|---|
| internal/secureuserfile/file.go | Adds metadata repair and separates existing-object repair from creation. |
| internal/secureuserfile/file_windows.go | Repairs DACLs without requesting ownership-change rights. |
| internal/secureuserfile/file_windows_test.go | Tests limited-rights repair, ownership checks, and content preservation. |
| internal/secureuserfile/file_unix.go | Delegates repair to existing POSIX metadata handling. |
| internal/devicepolicy/reconcile.go | Stops marker clears when Windows state cannot be read safely. |
| internal/devicepolicy/cache.go | Adds shared state preparation, locked read repair, and redacted warnings. |
| internal/devicepolicy/cache_windows_test.go | Adds legacy-state lifecycle, peer-lock, and wrong-owner tests. |
| internal/devicepolicy/cache_test.go | Adds a non-Windows unreadable-state clear regression test. |
| cmd/stepsecurity-dev-machine-guard/main.go | Warns on unexpected target-setup failures with redaction. |
| cmd/stepsecurity-dev-machine-guard/main_devicepolicy_test.go | Tests warning visibility and secret redaction. |
Review effort: Balanced
ashishkurmi
approved these changes
Oct 26, 2026
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.
What does this PR do?
Device-policy state files written by older agents inherit their parent's DACL on Windows, so the strict metadata check rejects them. Reads then report no ownership, and writes, writability probes and clears fail.
cacheMuand cross-process state lock before using it. Bytes, owner and all category/target records are preserved. A plain read takes the lock only when the file has legacy permissions; absent state creates nothing.READ_CONTROL|WRITE_DAConly. Modify-only legacy permissions no longer need ownership-change rights. Fresh creation still assigns the owner. The final strict ACL is unchanged.macOS/Linux behavior is unchanged. No new dependencies, state-format changes or migration framework.
Type of change
Testing
go test -raceon affected packages,go vet,golangci-lint, gofmt, linux/darwin/windows builds, Windows test compilationsecureuserfilepermission tests under a limited-rights token, no skips (Modify-only repair, wrong-owner refusal)make smoke(45/45 checks)Validated at
9612366: five native Windows lifecycle cases, including actual 1.15/1.16 state and the unchanged 1.17 failure control; 11 edge cases; limited-rights repair without skips; and broader native file-writer tests. macOS race tests and non-root Linux container regressions passed. All 19 CI checks passed. The isolated lifecycle driver uses synthetic policies and an in-process API, not a live backend rollout.Related Issues
None.