Targets & groups
A target is one concrete endpoint of a given module type — an SSH host, a K8s cluster, an F5 BIG-IP management URL, a Vault instance. A target group is a named collection of targets for bulk distribution. Both live under Settings → Distribution.
Creating, editing, and deleting targets and target groups (including group member changes) is operator-capable, gated by default through the config-change approval toggle (Settings → General → Approval Requirements, ON by default) — an operator's change is filed as an approval request an admin approves before it applies. Admins and owners bypass approval. Module credentials referenced by a target stay admin-only. See Approval workflow and Auth & RBAC.
Model
- Identity vs display: every target has an immutable
_id(used in jobs, audit, references) and a mutable_name(safe to rename for humans). References use IDs; UI surfaces names. - Module type: fixed at creation time. Change requires deleting + recreating the target.
- Credential reference: most modules authenticate via a module credential. Multiple targets can share one credential (e.g. ten SSH hosts, one key). Rotating the credential rotates it for every target that references it.
- Project scope: targets belong to a single project. Cross-project reuse is not supported — create a target per project.
Create a target
The Targets list can be searched by name and narrowed with the type filter next to the search box (both apply server-side across every page).
- Settings → Distribution → Targets → New.
- Pick a module type. The form reveals type-specific fields:
- SSH — hostname, port, username, credential reference (SSH key or password), and an optional host-key verification toggle.
- Kubernetes — kubeconfig credential or in-cluster mode, default namespace, explicit TLS Secrets (empty = one auto-named Secret per certificate) and restart targets; namespaces, Secrets and workloads can be picked from the cluster.
- IIS — WinRM host + port, auth type on the target (NTLM / Basic / Kerberos with realm + optional KDC pin; empty = the credential's legacy auth fields), credential reference (bare username + password), certificate store + binding placement — site, bindings and application pools can be picked from the server, with a preview of the bindings a deploy would touch.
- WinRM (generic Windows) — hostname + port (empty = 5985 plain / 5986 TLS), TLS toggle + skip-verify, auth type (NTLM / Basic / Kerberos) with NTLM domain or Kerberos realm (Kerberos is zero-config — optional KDC pin, no krb5.conf), credential reference, PathSet (where files land) and ActionSet (post-deploy script), connect/command timeouts, max file size. The Windows sibling of the SSH target.
- F5 BIG-IP — management host + port, partition, credential.
- NetScaler (Citrix ADC) — NSIP, credential, intermediate naming strategy (fingerprint-based recommended; see NetScaler).
- HashiCorp Vault — Vault address, KV v2 mount path, credential (token or AppRole).
- Webhook — URL, HTTP method, headers, timeout, retry policy.
- Huawei Cloud — region, project ID, credential (AK/SK), scope (ELB / CDN / WAF).
- AWS ACM — region (CloudFront requires
us-east-1), credential (access key), optionalcertificate_arnto re-import an existing ACM certificate in place — pickable from the region, which also flags the certificates ACM issued itself and therefore cannot be imported over, optionalcertificate_nameused as theNametag when a new certificate is created. - Email/SMTP — relay host + port, TLS mode (
starttls/smtps/plaintext) + skip-verify, auth method (plain/login/none) + username, credential reference, from address + display name, TO/CC/BCC recipients, payload mode (pem/pem_and_key/pkcs12), subject prefix, timeout.pkcs12additionally requires a PKCS#12 passphrase credential. - Cloudflare — target zone ID (pickable from the account, with the zone's plan shown because a custom certificate needs Business or Enterprise), credential (API token), optional API host,
bundle_method/type/geo_restrictions. Uploads the certificate to the zone as a Custom Certificate (Business/Enterprise plan); updates in place on renewal. - cPanel / WHM — host,
mode(cpanel/whm), optional port/use_ssl/ssl_verify/timeout,domains(optional — a distribution can supply them per certificate),whm_user(deprecated, never sent); credential (API token{username, api_token}). Installs the certificate onto each domain via cPanel UAPI / WHM API; overridable domain list per distribution. - Azure Key Vault — vault URL (
https://<name>.vault.azure.net; sovereign clouds supported), credential (service principal), optionalcert_name(empty = per-certificate auto name), optional tags + HTTP timeout. Imports an AES-256-encrypted PKCS#12 (random per-import password) as a new version of the KV certificate on every renewal. - MerlinCDN — binding rows (
bindings: distribution ID + canonical-name ID or domain per row; one upload, each CNAME re-pointed), credential (personal access token + org/workspace), optional API host,bindtoggle (off = upload-only),delete_old_certtoggle. - Microsoft Exchange — WinRM host/port (address the server by its AD FQDN), Kerberos-only auth with the
domain(realm) required and an optionalkdc_hostpin, services (IIS/SMTP/POP/IMAP), apply mode (single / explicit list / all org),restart_services+delete_old_certtoggles, credential (bare username/password). The server list can be picked from the organization. With restarts on, every server in the list is contacted directly, so name each one by its FQDN and allow WinRM to all of them. Exchange serves RSA certificates only. On-prem Exchange Server only. - PAN-OS (Palo Alto) — management host + port, credential (
username+passwordorusername+api_key; username always required), optionalcert_name(empty = per-certificate auto name), optionalvsys(empty = shared location) — both pickable from the firewall,auto_committoggle (off = import to the candidate config only; the run succeeds with a "commit pending" warning),ssl_verify, timeouts. Imports cert + key + chain as one named certificate object, then runs a partial commit scoped to the API user; renewals re-import under the same name, so SSL/TLS profile and GlobalProtect bindings are preserved. Requires PAN-OS 9.0+.
- Give the target a descriptive name.
prod-web-lb-1beatstarget-42. - Optional validation endpoints (post-distribution TLS check):
- Host + port (
443for HTTPS). - SNI (optional; defaults to the endpoint's own hostname — empty only when the endpoint is IP-only).
- Method:
tls_fingerprint(compare the served leaf against the certificate just deployed) ornone(skip). There is no fingerprint-source choice — the expected value is always the certificate this run deployed. - Retry policy: count, delay, timeout.Validation endpoints can also be defined per-distribution later; per-target is the common case.
- Host + port (
- Save. Saving does not run a health check — it is a separate action on the target (project admin). Run it to confirm the endpoint is reachable and the credential authenticates; failure shows a red badge with the reason.
Health check
Clicking Health check on the target detail page re-runs a minimal reachability test:
- SSH: connect, then open and close an SFTP session (no command is run on the host).
- K8s:
GET /versionon the API server. - F5: iControl REST version query. NetScaler:
GET /nitro/v1/config/nsversion. - IIS:
Invoke-Commandover WinRM returning hostname. - WinRM (generic):
Write-Output "OK"over WinRM. - Vault: authenticate with the credential, then probe the mount's tune endpoint.
- Webhook: HTTP
HEADto the base URL (reachability probe; status code not evaluated). - Huawei: cert-service list call.
- AWS ACM:
acm:ListCertificatesin the target region. - SMTP: dial the relay, negotiate TLS as configured,
EHLO+QUIT— deliberately no AUTH attempt, so probes don't fill the relay's audit log with failed logins. - Cloudflare: reads the target's zone with the API token (
GET /zones/{id}), which proves the token is valid and reaches that zone. It does not useGET /user/tokens/verify— that route rejects account-owned tokens even though they deploy fine. - Azure Key Vault: AAD token acquisition + certificate list probe (
GET /certificates?maxresults=1). - cPanel / WHM: authenticated probe (cPanel installed-hosts list / WHM version).
- MerlinCDN: authenticated distribution lookup.
- Exchange: WinRM connect + Exchange Management Shell availability probe.
- PAN-OS: authenticate + read system info (reports the PAN-OS version); fails if the target sets a
vsyswhile multi-vsys is disabled.
Health-check failures do not disable the target — distribution still attempts it — but the list view shows a red dot so you have a warning before execution.
Create a target group
- Settings → Distribution → Target groups → New.
- Name it (e.g.
prod-web-lbs). - All targets in a group must share the same module type — you cannot mix SSH and Kubernetes in one group.
- Pick members from the list. Member count is shown in the list view.
On an attached distribution, you pick a single target or a single group, not both. Distributing to a group of 50 triggers fan-out only if a positive fan-out threshold is configured and 50 ≥ that threshold (default 0 = fan-out disabled; Settings → General).
Edit / delete
- Rename is always safe — it updates the display name; the immutable ID stays.
- Change credential — allowed; all future distributions pick up the new credential on next execution.
- Change module type — not allowed. Create a new target and update the distribution binding.
- Delete — blocked while the target is a member of a target group, or is listed in a module configuration. A distribution references a module config, never a target directly, so remove it from the group / module config first.
Variables in target config
Target connection fields (hostname, host, IP, NSIP, etc.) are literal values — they are not templated or variable-substituted. Project variables (Project variables) are resolved only in SSH/WinRM PathSet paths and ActionSet commands/scripts, via ${{ NAME }} placeholder substitution (not Go templates) — see primitives. For staging vs prod where only the hostname differs, create a separate target per environment.
Security notes
- Targets are scoped to a project; no cross-project leakage.
- Credential references are by ID — revoking a credential (admin-only) does not delete the target, but the next execution will fail with
authclassification. - SSRF: target hostnames are resolved via the standard network policy — link-local and cloud-metadata blocked by default.
Troubleshooting
Health check is red but I can reach the target manually
Usually credential scope or network path. Check the exact error on the detail page. Common causes:
- K8s: service-account missing
secrets: create, updatein the target namespace. - SSH: wrong port (22 vs 2222), wrong credential, or firewall between the backend pod and the host.
- IIS: WinRM not configured (
Enable-PSRemoting -Forceon the Windows side) or firewall on TCP 5985/5986.
Cannot delete target
The target is still in a target group or listed in a module configuration. Go to Settings → Distribution → Target groups / Modules, remove it there, then retry.
"module type mismatch" when adding a member to a group
Groups are homogeneous. Create a second group for the other module type. If you want to distribute to both types for the same cert, attach two distributions to the cert (one per module type).