# Targets and inventory

> Address forms, transports, and the inventory file that describes a fleet.

Source: https://refpoint.dev/docs/guides/targets-and-inventory

This guide covers how refpoint reaches a machine and how to describe a fleet
once instead of on every command line.

## Address forms

| Form | Transport |
|------|-----------|
| `local` or empty | Local execution |
| `host`, `user@host`, `user@host:port` | SSH, default port 22 |
| `[::1]`, `[::1]:2222`, bare IPv6 | SSH. A bare IPv6 address is taken whole, so use bracket form to pin a port |
| `winrm://user@host[:port]` | WinRM, default 5985 for HTTP or 5986 for HTTPS |

Ports must be 1 to 65535. An empty host is rejected, because `:22` resolves to
the local machine and the run would report results for a host that is not the
one named.

## Platform probing

Each target is probed once and the result is cached in the transport. `uname -s`
is tried first. If that is unavailable, three Windows-specific probes follow.
On Linux, `/etc/os-release` supplies the distro `ID` as the name and the first
token of `ID_LIKE` as the family, with the family defaulting to the name.

An inconclusive probe is a hard failure, not a guess. Defaulting to Linux would
send unquoted, unencoded commands to a Windows host, and platform-scoped
controls would be silently dropped, leaving the target looking compliant.

## SSH authentication

Authentication is tried in order: `--ssh-key` if given, then `--ssh-password`,
then `SSH_AUTH_SOCK`. The agent is the only path for hardware-backed or
passphrase-protected keys. A passphrase-protected key given with `--ssh-key`
produces an explicit message telling you to load it into ssh-agent and drop the
flag. Key bytes are zeroed after parsing.

### Host key verification

The default is `~/.ssh/known_hosts`. Two special values are accepted.

`accept-new` records unknown hosts on first contact, matching OpenSSH's
`StrictHostKeyChecking=accept-new`. Changed keys still fail. Appends are
serialised across a parallel multi-target run so concurrent trust-on-first-use
writes do not interleave, and each addition prints a warning.

`insecure` skips verification entirely.

The client constrains `HostKeyAlgorithms` to the algorithms already recorded for
that host, mirroring OpenSSH. Without that, Go's default order lists RSA and
ECDSA before Ed25519, so a server offering several key types would present one
the operator's known_hosts had not recorded, and verification failed against
hosts that `ssh` connected to without complaint.

### sudo

`--sudo` wraps each command in a root shell. Without a password it runs
`sudo -n sh -c '<quoted command>'`, which is non-interactive, so a command
needing a password fails immediately instead of hanging on a prompt. With
`--sudo-password`, or `REFPOINT_SUDO_PASSWORD`, it runs
`sudo -S -p '' sh -c '<quoted command>'`, feeding the password on stdin with
the prompt suppressed so it cannot pollute stdout parsing.

The command is single-quote escaped so shell syntax survives byte for byte.
sudo is not supported on WinRM targets, and combining the two is an error.

## WinRM

Over HTTPS, TLS encrypts the channel and plain NTLM authentication runs inside
it. `--winrm-insecure` skips certificate verification and prints a warning about
MITM exposure.

Over plain HTTP, payloads are SPNEGO-encrypted, but that encryption is
best-effort in the client library. A pre-flight refuses a peer that cannot
negotiate NTLM sealing, because without sealing the password crosses the network
in cleartext. `--winrm-allow-unencrypted` skips the pre-flight, and it is for lab
hosts only.

## Inventory files

```hcl
defaults {
  for              = { env = "prod" }
  ssh_key          = "~/.ssh/prod_ed25519"
  known_hosts_file = "~/.ssh/known_hosts_prod"
}

defaults {
  for     = { env = ["dev", "qa"] }
  ssh_key = "~/.ssh/nonprod_ed25519"
}

target "admin@web-01.example.com" {
  tags = { env = "prod", role = "web", region = "eu" }
}

target "winrm://Administrator@win-01.example.com" {
  winrm_https = true
  tags        = { env = "prod", role = "app", os = "windows" }
}

target "local" {}
```

### target attributes

| Attribute | Type | Notes |
|---|---|---|
| label | string | The address |
| `ssh_key` | string | Per-target override |
| `password` | string | Per-target override |
| `port` | int | 0 means the default |
| `tags` | map(string) | Labels for `--host-tag` selection and `defaults` matching |
| `known_hosts_file` | string | Per-target, so relaxing one host does not relax the fleet |
| `winrm_https` | bool | |
| `winrm_insecure` | bool | |

### defaults blocks

A `defaults` block supplies connection settings to every target whose tags match
its `for` selector. A block with no `for` is a catch-all.

The selector model is shared with `--host-tag`. A list value, or a repeated
flag, ORs within one key. Distinct keys AND. AND across keys is deliberate:
real scopes are intersections such as "prod in eu", OR would apply the wrong
credentials whenever one tag happened to match, and the specificity rule below
only holds under AND.

Resolution is per field. Among matching blocks, the one with the most `for` keys
wins a field, with ties going to the earlier declaration:

```
per-target value  >  matching defaults (most specific)  >  CLI flag  >  built-in
```

## Selecting hosts at run time

```shell
refpoint run baseline --targets-file fleet.rptargets \
  --host-tag env=prod --host-tag role=web --host-tag region=eu
```

```shell
refpoint run baseline --targets-file fleet.rptargets \
  --host-tag env=prod --host-tag env=staging
```

Targets given with `--targets` carry no tags, so a selector naturally keeps only
inventory hosts. A selector that matches nothing is an error naming the
selector, not a silent fall-through to `local`.

## Concurrency

Two independent dials. `--target-parallelism`, default 16, sets how many targets
are scanned at once and is clamped down to the target count.
`--concurrency`, default 1, sets how many controls run in parallel within one
target.

Targets are isolated from each other. A provider panic, which can happen because
providers parse untrusted target output, becomes that target's error rather than
crashing the run. The same guard exists per control. Control results are written
to a pre-sized slice by index, so control order in the report is deterministic
regardless of completion order.

## System identity

Each scanned target gets a `system_id` in the result. It is the trimmed content
of `/etc/refpoint/system-id`, or `C:\ProgramData\refpoint\system-id` on Windows,
when that is 1 to 255 characters of `A-Z`, `a-z`, `0-9`, `_`, `-`, `|` and `.`,
used as written with its case preserved. Content outside that set is ignored and
logged as a warning. Otherwise it is the SHA-256 hex digest of the hostname,
lowercased first so a host reporting its name in upper case keeps one digest.
This gives a stable identifier when a host's address changes between runs.