Remote execution

Remote activities are executed over WinRM without an additional agent; nothing is installed on the target machines. Remote:Provider selects the provider.

Providers

ProviderValueBehaviour
WinRMwinrmPowerShell SDK / WinRM sessions to the target machine
NoOpnoopNo remote execution — has to be acknowledged with Remote:AllowNoop=true or NODEPILOT_ALLOW_NOOP_REMOTE=1, otherwise the boot is aborted

Localhost bypass & self-managed remoting

Without a machine set (or with targetMachineId: "localhost" and no credential), runScript runs engine-local in the API host instead of through a managed WinRM session. This is a product feature; do not introduce a guard against it. Ideal for demos — and the escape hatch for the SCOrch style: the script can establish the remote connection itself (Invoke-Command -ComputerName SRV01 -Credential $c { … } / New-PSSession), for example for dynamic target lists or fan-out to N machines from one node.

The trade-offs of managing it yourself: it runs on the API host (which then needs network/WinRM access itself); the DPAPI credential store is not wired up (build the PSCredential in the script, take the secret from {{globals.NAME}}); there is no machine targeting, testing or auditing; and hardening such as Remote:RequireWinRmSsl and the session pool do not apply — those hang off the managed WinRM path.

Identity and rights on the target system

Which account carries the WinRM connection depends solely on whether a credential was resolved for the step — there is no authentication-mode switch.

CaseThe connection runs as
Credential set on the node or as the machine defaultThe stored account (Domain\User) — Negotiate with an explicit password
No credential, real target machineThe service identity of the API — the gMSA, or the computer account DOMAIN\HOST$ when the service runs as LocalSystem (integrated Windows authentication)
No credential, loopback host nameNo WinRM at all — the node runs engine-local in the API process and therefore also under the service identity (see the section above)

Credential resolution has two levels: credential on the node → the machine's DefaultCredentialId → the service identity. There is no global default credential. Deleting a credential silently clears the machine's reference to it, and the machine falls back to the service identity.

Admins and Operators manage credentials under Infrastructure → Credentials; Viewers do not see the menu entry because the API refuses them the list. Only an Admin can delete. An optional expiry date feeds the credential-expiring system policy. The badge on the menu entry counts expired accounts and those with at most 14 whole days left, using the same calculation as the policy's preset. Show dependencies on each row lists the machines and steps that use a credential — the place to look before deleting one.

On the target system the account in use — stored credential or service identity alike — needs a reachable WinRM endpoint and access to it:

Enable-PSRemoting -Force
winrm quickconfig -transport:https   # only for machines using HTTPS

By default only local administrators and members of Remote Management Users may use that endpoint. Without one of those memberships the step fails at the endpoint even though the sign-in itself succeeds.

For a target without stored credentials, NodePilot connects directly as the service process identity: the gMSA, or the host computer account under LocalSystem. Grant that account the required endpoint and resource permissions. With LocalSystem in an active/passive installation, authorize each node's computer account.

This direct first hop does not require resource-based constrained delegation. NodePilot does not impersonate the browser user for it. Configure delegation only for a separately justified delegated-user or second-hop topology. With stored credentials, authorize the selected account instead.

A machine's connection test (POST /api/machines/{id}/test) requires a credential and otherwise answers 400 MACHINE_CREDENTIAL_REQUIRED. It therefore cannot exercise the credential-less path — workflow steps still run in that situation.

Transport: HTTP or HTTPS

By default every machine connects over HTTP (5985) with Negotiate. Windows negotiates which protocol actually runs:

  • Domain (target entered by DNS name): Kerberos. Client and server authenticate each other, and the WinRM messages are encrypted.
  • Workgroup, or a target entered by IP address: NTLM. The messages are encrypted as well, but NTLM does not prove that the right server is on the other end. The target has to be listed in TrustedHosts on the NodePilot host.

Whether NTLM is allowed at all is up to the operator in Windows (the target's WinRM authentication settings, NTLM policy via GPO), not NodePilot.

HTTPS (5986) is switched on per machine (UseSsl) when the server identity should be secured without Kerberos too. The target then needs an HTTPS listener on the configured port and a certificate that the NodePilot host trusts and whose name matches the configured host name.

Remote:RequireWinRmSsl (default false) forbids HTTP entirely, so every machine then needs HTTPS. See Hardening flags.

REST API proxy (for the restApi activity)

RestApi:Proxy:Enabled (default false). Per-step override via proxyMode (default/direct/custom), proxyAddress, noProxy. RestApi:BlockPrivateNetworks (default true) blocks RFC 1918/loopback. RestApi:AllowedHosts contains exact host names/IPs only and is mandatory for every initial target and redirect target that actually goes through a default or custom proxy. The PowerShell-based waitForCondition modes portOpen/httpOk have their own list, WaitForCondition:AllowedHosts (default ["localhost"]) — they cannot re-check the target when the connection is established and are therefore deliberately kept separate, so that a permitted probe does not also open restApi to loopback. That list alone decides for both probe modes: RestApi:BlockPrivateNetworks/RestApi:AllowedHosts are not consulted, so a loopback probe needs no restApi exception. direct targets, and targets bypassed through noProxy, remain protected by the IP check when the connection is established. The allow-list can permit private/loopback targets, but never link-local or cloud-metadata addresses.

All chapters