Skip to content

Decide how darling.json's secrets get tightened without breaking the Viewer (three options, Erik's call) #1792

Closed

Description

@erikdarlingdata

Split out of #1769, which asked for NT AUTHORITY\INTERACTIVE to be dropped from darling.json's ACL hardening. That specific change is not safe and is not being made — see #1769 for the verified chain. The backups half shipped there. This issue carries what is left: the design decision, which is Erik's.

The problem that remains real

darling.json holds every monitored server's encryptedPassword, the MCP bearer token, the web access token, and in BYO mode the store connection string. Those are DPAPI LocalMachine blobs with an entropy constant that ships in an open-source repo, so READ access IS the secret, and the file ACL is the whole access boundary.

The file grants INTERACTIVE:(R), so any interactively-logged-on user can read all of it. On the single-operator admin-only VM this edition targets that is low severity, and it is what the design intends today. It is still the only interactive-readable path to those secrets: the Viewer also gets INTERACTIVE read on pg-admin-credential.dpapi, but the admin role's SELECT carves out the secret columns, so the store is not a way around it. Tightening it is worth doing.

Why it cannot just be removed

The Viewer reads the file, non-elevated, and would lose access outright. Full chain with file:line is recorded in #1769. The short version: ViewerSettings.TryLoad does File.ReadAllText, the Viewer manifest is asInvoker, and under UAC an interactive administrator's default token carries BUILTIN\Administrators as SE_GROUP_USE_FOR_DENY_ONLY — so a DACL of exactly SYSTEM + Administrators + the service identity denies it, and the window shows "darling.json could not be read" with no data at all. It hits the default shipped layout.

The three options

None of these is being picked without Erik. Recorded so the choice is made once, deliberately, rather than re-litigated each time someone reads the ACL and reaches for the obvious fix.

Option 1 — give the Viewer a non-secret handoff

The service writes {managed, port, dataDirectory, connectAs} beside the already-INTERACTIVE-readable credential files; darling.json drops to three identities.

Design-correct, and it fully separates topology from secrets — the Viewer only ever wanted the postgres section.

Known hole: it does not cover BYO mode, where postgres.connectionString is itself a secret the Viewer must read. BYO would need its own answer (or would keep the current posture, which is defensible since a BYO operator governs their own store).

Cost: a new artifact in the shipped layout, plus the Viewer's resolution order. Not a small fix.

Option 2 — ACL the config to a configured operator account instead of INTERACTIVE

Smaller, and the code already names this as the intended path: DarlingFileSecurity says the tightening for a shared machine is "a configured operator account ACL'd specifically — a future knob, not built for the Phase 1 single-operator default."

Cuts against the standing preference for defaults over speculative config, and it is a knob every operator then has to get right or lose their Viewer. It also only helps the multi-user machine, which is not the target deployment.

Option 3 — accept as designed, permanently

Keep the grant, and state in the docs that INTERACTIVE:(R) on darling.json is intended rather than tracked-for-removal.

The exposure is bounded to interactively-logged-on users on a box the design already assumes is single-operator and admin-only, which is exactly what the principal model in DarlingFileSecurity documents and accepts. This is the no-code option and it is not obviously wrong.

Field/client note

The client upgrade checklist's step-14 note becomes by-design-pending-this-decision, not "will be removed in a future build" — the latter is now false. Whichever option lands (including option 3) settles that wording for good.

Note for whoever picks this up: the backups are already handled. Post-#1786, any darling.json.bak-* carries three identities only, and that is a separate, falsifiable check from this one.

Activity

  1. erikdarlingdata commented on Jul 28, 2026

    @erikdarlingdata
    OwnerAuthor

    Decision (Erik, 2026-07-28): OPTION 3 - accept as designed. darling.json keeps INTERACTIVE:(R): the grant is load-bearing for the non-elevated Viewer (asInvoker manifest; under UAC an interactive admin's Administrators membership is deny-only, so a three-identity DACL denies the Viewer outright in the default shipped layout). The exposure is bounded to interactively-logged-on users on a single-operator admin box, which the design already documents and accepts. The genuinely unprotected copies - the config BACKUPS - were fixed by #1786.

    REVISIT TRIGGER, recorded so this close is not read as forever: a real customer running a multi-user monitoring host is the complaint that reopens this, and OPTION 1 (a secrets-free handoff file for the Viewer; darling.json locks to three identities) is the named successor - noting its BYO-mode hole (the connection string is itself a secret the Viewer needs there) must be solved for that option to be honest. Option 2 (configured-operator ACL knob) stays rejected under the knobs-need-real-complaints rule.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions