Skip to content

[Bug][Windows]: elevated Task Scheduler staging is unreadable under alternate-credential UAC #4779

Description

@lidge-jun

Client or integration

OpenCodex CLI

Area

Installation or packaging

Summary

Follow-up to #4692. That fix stages the elevated Task Scheduler XML to an ACL-hardened private file instead of inlining two base64 payloads into the command line. The staging uses the existing hardenSecretPath/hardenSecretDir helpers, which grant the current effective token SID full control and then strip inheritance, removing SYSTEM and Administrators.

That is correct for the common case: a split-token elevation of the same user carries the same SID, so the elevated process reads the payload. It is not correct for an elevation answered with a different administrator's credentials — the over-the-shoulder prompt a standard user gets. That elevated process runs as the other admin and cannot open the staged file.

The inline form had no such dependency, so this is a behavioural narrowing introduced by the fix. #4692 mitigates the diagnosability half: the read failure has its own protocol exit code and the parent reports the cause and the remedy instead of a bare number. What is left open is the policy question.

The decision to make: should the staged payloads also grant SYSTEM (S-1-5-18) and Administrators (S-1-5-32-544)?

Arguments for: it restores alternate-credential elevation, and the staged content is a scheduled-task definition pointing at the user's own launcher — not a credential. Tamper-evidence does not depend on the ACL, because the elevated script verifies a SHA-256 over the bytes it reads, which is what covers a same-SID rewrite that no ACL can prevent.

Arguments against: it widens read access to every administrator on the machine, it adds a second ACL shape to src/lib/windows-secret-acl.ts, and that module is security-sensitive enough that MAINTAINERS.md requires explicit security review for changes to it. The current helpers are used for real secrets, so a variant that grants more must not be reachable from those call sites by accident.

Reproduction

  1. Windows host where the opencodex-proxy task file is owned by Administrators, so a non-elevated schtasks /create /f is denied and every repair funnels into the elevated fallback.
  2. Sign in as a standard user, so UAC prompts for an administrator's credentials rather than consent.
  3. Run ocx service repair.
  4. The elevated process runs as the supplied administrator account and cannot read the staged payload. With [Bug]: Elevated Task Scheduler re-registration exceeds command-line limit — ENAMETOOLONG (uv_spawn) with double base64 XML payloads #4692 applied it exits with the staging-unreadable protocol code and the parent explains the cause; the repair still does not complete.

Version

2.56.0 (behaviour introduced by the fix for #4692)

Operating system

Windows, Task Scheduler backend

Provider and model

Not provider-specific

Logs or error output

Background service install failed: the elevated process could not read the staged task
definition in <temp>\opencodex-service-stage-XXXXXX. That directory is readable only by
the account that staged it, so this happens when the UAC prompt was answered with a
different administrator account. Approve the prompt as the signed-in user, or run the
command again from a session already elevated as that user.

Screenshots and supporting files

Relevant code: stageElevatedSchedulerRegistration and describeElevatedRegistrationFailure in src/service/windows-ops.ts, OCX_ELEVATED_STAGING_UNREADABLE and runWindowsElevatedScheduledTaskRegistration in src/lib/windows-elevation.ts, and hardenSecretPath/hardenSecretDir in src/lib/windows-secret-acl.ts.

Workaround for an affected host, unchanged from #4692: delete the admin-owned task once from an elevated prompt (schtasks /delete /tn opencodex-proxy /f), then let repair re-create it as the current user.

Redacted configuration

{}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinginstallInstallation or packagingplatformOS/service/tray/ACL (Windows-heavy, not Windows-only)serviceService lifecycle (WinSW/launchd/scheduler)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions