Skip to content

Honor Windows token owner for private files#6

Merged
mariusvniekerk merged 6 commits into
mainfrom
codex/windows-token-owner-private-dir
Jun 2, 2026
Merged

Honor Windows token owner for private files#6
mariusvniekerk merged 6 commits into
mainfrom
codex/windows-token-owner-private-dir

Conversation

@mariusvniekerk
Copy link
Copy Markdown
Contributor

Summary

  • compare Windows file and private directory ownership against the current token owner SID
  • keep private directory DACL restrictions granting the current token user, SYSTEM, and Administrators
  • add Windows coverage for token owner lookup and accepting files owned by the current token owner

Validation

  • go test ./...
  • go vet ./...
  • GOOS=windows GOARCH=amd64 go test -c ./safefileio -o /tmp/kit-safefileio-windows.test.exe
  • GOOS=windows GOARCH=amd64 go test -c ./daemon -o /tmp/kit-daemon-windows.test.exe

Windows verification note

This repository does not include a visible Windows Go test workflow to dispatch. \Dependency Graph active 286880732
CodeQL active 286880707 only shows Dependency Graph and CodeQL, so I could cross-compile the Windows test binaries locally but could not run the Windows-only tests in GitHub Actions from this repo.

Windows can assign newly created filesystem objects to the process token owner rather than the token user SID, especially for elevated/admin tokens on hosted runners. The daemon runtime store was rejecting directories and runtime records that the same process had just created, which broke consumers that rely on safefileio for private runtime state.

Validate private directories and current-user files against the current token owner SID while continuing to grant the token user explicit DACL access. This matches Windows ownership semantics without weakening the non-reparse and restricted-DACL checks.

Validation: go test ./...; go vet ./...; GOOS=windows GOARCH=amd64 go test -c ./safefileio -o /tmp/kit-safefileio-windows.test.exe; GOOS=windows GOARCH=amd64 go test -c ./daemon -o /tmp/kit-daemon-windows.test.exe

🤖 Generated with [OpenAI Codex](https://openai.com/codex)
Co-authored-by: OpenAI Codex <noreply@openai.com>
@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Jun 1, 2026

roborev: Combined Review (64f1195)

No issues found.


Synthesized from 2 reviews (agents: codex | types: default, security)

Kit did not have repository-level CI beyond the existing GitHub security workflows, which left PRs without native Windows test coverage for filesystem and daemon behavior. Add a small workflow modeled after the sibling kenn-io repositories so every PR builds, tests, and vets on Linux, macOS, and Windows with pinned official actions and read-only checkout credentials.

The hygiene job checks that module metadata remains tidy. Running that locally with Go 1.26.3 required marking golang.org/x/mod and golang.org/x/sys as direct requirements, so include that metadata-only adjustment with the workflow instead of letting the new job fail on its first run.

Validation: go mod tidy && git diff --exit-code -- go.mod go.sum; go build ./...; go test ./...; go vet ./...

Generated with OpenAI Codex
Co-authored-by: OpenAI Codex <noreply@openai.com>
@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Jun 2, 2026

roborev: Fail

Summary verdict: One medium-severity Windows ownership regression should be addressed before merging.

Medium

  • safefileio/private_dir_windows.go:49, safefileio/open_file_windows.go:74
    • Windows validation now accepts only the current token owner SID. For an admin account, the token owner can differ between elevated and non-elevated runs while CurrentUserID still derives the shared path from the token user SID. A directory or runtime file created unelevated can therefore be rejected when the same user runs elevated, and vice versa, breaking per-user runtime discovery across elevation boundaries.
    • Suggested fix: treat both the token user SID and token owner SID as acceptable owners for validation, while still using the token user SID for the DACL grant.

Review type: | Agent: codex | Job: 19402

mariusvniekerk and others added 4 commits June 1, 2026 20:16
Adding native Windows CI exposed a few assumptions in the git helpers and tests that only held on Unix-like systems. Git reports some paths with slash separators on Windows, and the test fake-git shim was a shell script that Windows never executed.

Normalize worktree-list paths before returning them and make the tests compare cleaned paths and use platform-native null device and fake command behavior. This keeps the new Windows lane meaningful without relaxing the CI coverage.

Validation: go mod tidy && git diff --exit-code -- go.mod go.sum; go test ./...; go vet ./...

Generated with OpenAI Codex
Co-authored-by: OpenAI Codex <noreply@openai.com>
Remote and Actions-based Windows validation surfaced an elevation boundary that the token-owner fix did not fully cover. The runtime path is derived from the token user SID, but Windows may assign object ownership to either the token user or token owner depending on how the process is launched.

Accept both SIDs during private directory and current-user file validation while continuing to grant DACL access to the token user. That keeps elevated and non-elevated runs for the same account compatible without weakening the reparse-point or restricted-DACL checks.

Validation: go test ./...; go vet ./...; GOOS=windows GOARCH=amd64 go test -c ./safefileio -o /tmp/kit-safefileio-windows.test.exe; GOOS=windows GOARCH=amd64 go test -c ./daemon -o /tmp/kit-daemon-windows.test.exe

Generated with OpenAI Codex
Co-authored-by: OpenAI Codex <noreply@openai.com>
The new Ubuntu CI lane exposed that a one millisecond per-probe timeout was too tight for hosted runners, even when the next local httptest server was healthy. That made the test assert scheduler timing rather than Discover's behavior.

Make the slow probe block until its request context is canceled and use a timeout that still exercises the per-probe skip path while leaving room for the fast local probe to complete. This keeps the coverage meaningful and removes the CI race.

Validation: go test ./daemon -run TestDiscoverSkipsPerProbeTimeouts -count=20; go test ./...; go vet ./...

Generated with OpenAI Codex
Co-authored-by: OpenAI Codex <noreply@openai.com>
The new CI matrix was still using plain go test output, which is harder to scan in GitHub logs when a package fails. Match the middleman workflow style by running tests through gotestsum with pkgname-and-test-fails formatting while keeping the raw JSON event stream available as a per-runner file.

Record gotestsum as a Go tool dependency so CI uses a pinned version through the module rather than installing an implicit latest binary.

Validation: go tool gotestsum --format pkgname-and-test-fails --jsonfile=/tmp/kit-gotestsum.json -- ./...; go vet ./...

Generated with OpenAI Codex
Co-authored-by: OpenAI Codex <noreply@openai.com>
@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Jun 2, 2026

roborev: Combined Review (3851fb2)

No issues found.


Synthesized from 2 reviews (agents: codex | types: default, security)

@mariusvniekerk mariusvniekerk merged commit 7088ce0 into main Jun 2, 2026
7 checks passed
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.

1 participant