Skip to content

Darling install tree: narrow the service account's Modify to pg-runtime and pg-runtime-prev (#4043 part 2) #4052

Description

@erikdarlingdata

Split from #4043. Part 1 of that issue, the ACL check before the lock, ships in #4050. This is the part 2 residual (Low, defence in depth).

The gap

#4038's lock grants the Darling service account Modify on the whole install tree. Only pg-runtime\ and pg-runtime-prev\ need writes from the service. So a compromised service or postgres process can rewrite the service exe or a DLL and persist across restarts.

Fix

Grant the service account Read & Execute on the install root, and Modify only on pg-runtime\ and pg-runtime-prev\, created ahead of time. Do this in both install-darling.ps1 and the upgrade script, and pin the resulting ACEs in a test.

Write-site audit (static, done in #4050, not yet closed)

Path (under the install root) Service writes?
pg-runtime\, pg-runtime-prev\, and the pg-runtime.sha256 / .stamp / .blocked stamp files Yes. Confirmed, and scoped to those two folders (DarlingManagedPostgres, DarlingStoreUpgrade).
darling.json No. Only the elevated installer (step 4b) and the --configure-network verb write it.
DarlingInstallLocation.Report No. It reads only.
wwwroot (the web content root) Believed read-only. Not verified.
The BringYourOwnDirectoryName folder beside darling.json (DarlingLogHashKeyFile.DirectoryFor) Open. It is used only when postgres.managed = false and the service is not in a container (bring-your-own Postgres). The managed default resolves under %ProgramData%, outside the tree.

Resolve the open row before narrowing anything. Pick one:

  • move that folder under %ProgramData%, and migrate an existing key;
  • fold it into the Modify grant;
  • show that nobody runs that combination on Windows.

Risk and verification

If a write site is missed, the service breaks at start, which is tier 1. So, before shipping:

  • verify that wwwroot is read-only;
  • run a real service install and upgrade on a disposable box, never on a monitored or dev-in-use host. Walk it through install, start, one collection cycle, restart, an upgrade that rescue-copies into pg-runtime-prev, and bring-your-own-Postgres mode if that mode keeps a write site in the tree.

Also exercise #4050 on the same box

#4050's check couldn't be tested where it was built. The box run should also cover:

  • a real locked install re-run;
  • a gMSA service account;
  • a domain admin whose local-admin membership is nested;
  • an install root on a second volume.

Confirm each passes or refuses as #4050's PR body says it should.

Done when

  • The narrowed grant is in both scripts.
  • A test pins the ACEs.
  • The box run is recorded in the PR body.

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

    client-siteOwned by the client-site agents (other laptop). Local sessions never pick these up.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions