Research: steward orders on Windows hosts (JEA, Ansible win_*, Intune Remediations and EPM, Windows OpenSSH, PIM, CyberArk, Teleport) and Starfire/Raven body facts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
ecb2ae0995
commit
e4fd4ae09c
1 changed files with 155 additions and 0 deletions
|
|
@ -128,3 +128,158 @@ says about this design.
|
|||
is its projection.
|
||||
- Break-glass, when it lands, waits on an announcement and a window, and is
|
||||
recorded in full.
|
||||
|
||||
## 5. Windows hosts: Starfire and Raven
|
||||
|
||||
Serves follow-up `steward-orders-windows-hosts` under ruling
|
||||
`remote-admin-on-desktops` (operator 2026-10-31: "We'll need a way to do this
|
||||
kind of thing remotely"). The trigger: on 2026-10-31 she approved through UAC,
|
||||
sitting at Starfire, an elevated script that added an inbound firewall rule for
|
||||
Ollama on the WireGuard interface and registered a SYSTEM startup task. She is
|
||||
away from today, possibly for months; a hard reboot already needs a call.
|
||||
|
||||
### Body, as read on 2026-10-31 (read-only)
|
||||
|
||||
- Both hosts answer TCP 22 and 3389 from Yggdrasil over WireGuard: Starfire
|
||||
10.77.0.2, Raven 10.77.0.4. WinRM is stopped (start type Manual) on both.
|
||||
winget v1.29 is present; choco is not on Raven.
|
||||
- Yggdrasil holds no SSH client config and no private key for either host:
|
||||
`gamecultadmin` has only `authorized_keys` and `known_hosts`, root has no
|
||||
client key, and the mind users have no home. Nothing on Yggdrasil can reach a
|
||||
Windows shell today.
|
||||
- Starfire: sshd runs, the stock `Match Group administrators` stanza is in
|
||||
force, `C:\ProgramData\ssh\administrators_authorized_keys` does not exist and
|
||||
the operator's user has no `authorized_keys`. Its admins are the operator's
|
||||
user (`Meta`) and the built-in Administrator. No key reaches Starfire; RDP,
|
||||
Sunshine/Moonlight and her own UAC click are the only privileged paths in.
|
||||
- Raven: `administrators_authorized_keys` holds one key, commented
|
||||
`192.168.1.84 access key`, whose private half is on Starfire (the `raven`
|
||||
host entry in the operator's `~/.ssh/config`). A session with it is
|
||||
`BUILTIN\Administrators` at High Mandatory Level: Starfire already holds raw,
|
||||
unaudited admin on Raven.
|
||||
- Raven already runs Idunn's host actuator (`idunn-host serve`, task
|
||||
`GameCult-Idunn-Host`, at logon, interactive, Limited): it dials
|
||||
`10.77.0.1:17890/udp` over CultNet RUDP, accepts only requests Idunn's
|
||||
service identity signed, and signs its reports with its own host identity
|
||||
(`docs/host-actuator.md`; runbook `gamecult-ops/runbooks/idunn-host-raven.md`).
|
||||
It is unelevated by design: Muninn must live in the desktop session. Starfire
|
||||
has no actuator.
|
||||
- Memory, not re-proven here: Starfire has frozen under load (PSU or GPU
|
||||
suspected), and nothing that must survive may depend on Starfire or Raven
|
||||
staying up (`workstation-load-budget.md`, 2026-10-29).
|
||||
|
||||
### PowerShell JEA (Just Enough Administration)
|
||||
|
||||
- A session configuration (`.pssc`, registered with
|
||||
`Register-PSSessionConfiguration`) maps caller groups to role capabilities
|
||||
(`.psrc`); a role lists `VisibleCmdlets` with per-parameter `ValidateSet` or
|
||||
`ValidatePattern`, the session runs in `NoLanguage` mode and executes as a
|
||||
temporary virtual account (`RunAsVirtualAccount`) or a gMSA, so the caller
|
||||
holds no admin right. `TranscriptDirectory` records every session.
|
||||
(Microsoft Learn: "JEA overview", "JEA role capabilities", "JEA session
|
||||
configurations", "Auditing and reporting on JEA".)
|
||||
- JEA rides WinRM. SSH-based PowerShell remoting has not supported endpoint
|
||||
configurations or JEA (Microsoft Learn, "PowerShell remoting over SSH",
|
||||
limitations; the current page may have changed, check before relying on it).
|
||||
- Microsoft's own warning: a role that exposes a command able to run arbitrary
|
||||
code (`Start-Process`, `Invoke-Expression`, `Register-ScheduledTask` with a
|
||||
free action, `New-Service` with a free path) is an escape to the run-as
|
||||
account ("JEA security considerations").
|
||||
- On a workgroup desktop, WinRM needs a listener (HTTPS for anything but
|
||||
Kerberos), a local Windows account for the caller, and that account's
|
||||
password or certificate mapping held by the caller.
|
||||
- Lesson: JEA is the platform's answer to "typed, parameter-validated admin
|
||||
with a transcript", and its role file is the same shape as a typed order. It
|
||||
brings WinRM (off today), a Windows credential that would live on Yggdrasil,
|
||||
and no order id, brake or post: those would still be Idunn's, so the grammar
|
||||
would live twice, once in PowerShell attributes on each host and once in the
|
||||
order record.
|
||||
|
||||
### Ansible `win_*` modules over WinRM or SSH
|
||||
|
||||
- `ansible.windows.win_service` (state started, stopped, restarted; start
|
||||
mode), `community.windows.win_firewall_rule` (name, direction, action,
|
||||
protocol, localport, remoteip, profiles, interfacetypes),
|
||||
`community.windows.win_scheduled_task` (actions, triggers, principal, run
|
||||
level), `ansible.windows.win_package` and the community `win_chocolatey` and
|
||||
winget modules. Each takes typed parameters, declares desired state, is
|
||||
idempotent and reports changed, ok or failed. Transport is WinRM or OpenSSH
|
||||
with `ansible_shell_type: powershell`; over OpenSSH an admin key already has
|
||||
the elevated token, so no `become`. (Ansible docs: "Windows Remote
|
||||
Management", "Windows SSH", module pages.)
|
||||
- Lesson: these modules are the order vocabulary to copy, with desired-state
|
||||
semantics ("rule X exists with these fields") rather than imperative verbs.
|
||||
Agentless push means the controller holds admin credentials for every host,
|
||||
which is the shape the brief rules out.
|
||||
|
||||
### Intune Remediations and Endpoint Privilege Management
|
||||
|
||||
- The Intune Management Extension runs on the device as SYSTEM, polls the
|
||||
service outbound over HTTPS, runs a detection script and, when it reports
|
||||
non-compliant, the remediation script, and returns both outputs to the
|
||||
console. No inbound port; the device authenticates by its enrolment
|
||||
certificate. (Microsoft Learn: "Remediations", "Intune Management
|
||||
Extension".)
|
||||
- Endpoint Privilege Management adds support-approved elevation: the user asks
|
||||
to elevate one file, the request reaches the console, an admin approves
|
||||
there, and the device elevates that file hash only, logged. (Microsoft
|
||||
Learn: "Endpoint Privilege Management", "support approved elevation".)
|
||||
- Lesson: the mature Windows pattern for an absent administrator is a SYSTEM
|
||||
agent that dials out, executes only what its authority signed and reports
|
||||
back, and EPM is the nearest thing to "remote approval in place of a UAC
|
||||
click". It is the shape `idunn-host` already has on Raven, minus elevation.
|
||||
|
||||
### Windows OpenSSH and administrators
|
||||
|
||||
- For a member of Administrators, sshd reads only
|
||||
`%ProgramData%\ssh\administrators_authorized_keys` (ACL Administrators and
|
||||
SYSTEM), and a key-authenticated session gets the full token: UAC does not
|
||||
apply. Observed on Raven at High Mandatory Level. (Win32-OpenSSH wiki;
|
||||
issue #1942 on the file's location.)
|
||||
- Forced commands: `ForceCommand` in a `Match` block is the documented route;
|
||||
whether `command=` in an authorized_keys line is honoured on Windows has an
|
||||
open report of it being ignored (Win32-OpenSSH issue #473). Unproven on
|
||||
these hosts.
|
||||
- Lesson: an admin key is a remote UAC bypass with nothing but sshd's event log
|
||||
for a record. As an order transport it needs a forced command that parses
|
||||
the order on the host, and that parser is the whole boundary.
|
||||
|
||||
### How remote approval replaces a local UAC click
|
||||
|
||||
- Entra PIM: a user eligible for a role activates it for a bounded time with a
|
||||
justification, optional MFA, and optional approval by a named approver who
|
||||
is notified and approves in the portal or app; every activation is logged.
|
||||
(Microsoft Learn, "Privileged Identity Management".)
|
||||
- CyberArk dual control: use of a privileged account needs an approver's
|
||||
confirmation in the vault's web or mobile client; sessions run through a
|
||||
recording proxy (PSM). (CyberArk docs: "Dual control", "Privileged Session
|
||||
Manager".)
|
||||
- Teleport access requests: a role is requested with a reason; reviewers
|
||||
approve or deny, thresholds can require N approvals, and plugins put the
|
||||
request in Slack, Mattermost or PagerDuty with approve buttons; the grant is
|
||||
time-boxed and sessions are recorded. (Teleport docs: "Access Requests",
|
||||
"Access Request plugins".)
|
||||
- Shared shape: the approval arrives over an out-of-band channel authenticated
|
||||
as the approver, is scoped to one request, expires, and is recorded beside
|
||||
the request. A request nobody answers is denied, never run. Shared
|
||||
assumption: an approver who answers in minutes.
|
||||
- Lesson for an operator away for months: positive approval is only as live as
|
||||
her reachability. Where her approval is kept, the channel is her Matrix
|
||||
account replying in #operator to one order id (Synapse authenticates the
|
||||
sender; a Mind cannot forge her mxid without root on Yggdrasil), with an
|
||||
expiry after which the order is refused. Where it is not, the order's type
|
||||
is the defence, as for Linux (section 3).
|
||||
|
||||
### What this gives the Windows design
|
||||
|
||||
- A SYSTEM agent on each host dials out to an authority that signs every
|
||||
request; no inbound port, no Windows credential and no admin key on
|
||||
Yggdrasil (Intune, Salt minion, `idunn-host`).
|
||||
- The four Ansible modules become typed, desired-state orders, and JEA's
|
||||
warning becomes the grammar rule: no order field names a free program,
|
||||
script, or path to run outside a root the host binding declares.
|
||||
- A Windows host is often absent (a frozen Starfire, a reboot waiting on a
|
||||
call): an order to an unattached host is refused at once, never queued to
|
||||
fire days later.
|
||||
- Approval, where kept, is a Matrix reply from her account to one order id,
|
||||
scoped and expiring; anything outside the grammar is break-glass.
|
||||
|
|
|
|||
Loading…
Reference in a new issue