Actana CLI Pairing

You are on the machine being paired — not on the Core. Somebody there ran actana pair new; since 0.4.3 its handout ends in this very command with every value filled in, so usually you paste rather than type:

actana core pair NAME core.example:8443 XXXX-XXXX --session <id> --fingerprint AA:BB:…

NAME is what this machine will call the Core in its local registry (actana core ls, actana core use) — swap the placeholder, or it registers a Core literally called NAME (recoverable with actana core rm NAME). It is not the --label passed to pair new; that label is what the Core lists in actana pair ls. The address is host:port (or https:// / wss://) — the Core's TLS port, 8443 by default. Plain http:// and ws:// are refused: there is no certificate on a plaintext dial, so there is no fingerprint to check.

Pass --session <id> from the handout — it is not optional; a bare code without it is refused. A single <session>:<XXXX-XXXX> ticket works too; the two ids must agree if you pass both.

Which address to dial

The address you dial must be a name on the Core's certificate — the TLS stack verifies it before anything else happens. Since 0.4.2, ACTANA_PUBLIC_HOST on the Core is a comma-separated list and the certificate carries every name in it, so any entry verifies. Pick the one that routes from this machine:

You are pairing from Dial
the same host as a published Core port localhost:8443
inside another container (Docker Desktop) host.docker.internal:8443
inside the Core's compose network the service name, core:8443
another machine on the network the Core's LAN IP or DNS name

The handout prints one command per configured address, each annotated with which endpoint the credential will register — that comes from the code (pair new --public-host <addr>), not from the address you dial. If the registered endpoint would not route from here, mint a fresh code with the right --public-host rather than pairing a client that then cannot reach its own Core.

Fingerprint, or refuse

--fingerprint is the scriptable path, and the pasted handout command carries it. On a terminal, omit it and the CLI dials with nothing trusted, prints the fingerprint the Core presents, and asks whether it matches pair new. There is no skip flag. Unconfirmed — no flag, no TTY, or you answered no — refuses, and the code is unsent.

What success looks like

At a terminal, a framed confirmation and the next steps:

┌────────────────────────────────────────────────────────────────────────┐
│                                                                        │
│   ✓ Paired Core "NAME"                                                 │
│                                                                        │
│   Endpoint     192.168.1.50:8443                                       │
│   Sent as      laptop — the name this machine gave                     │
│   Current      "NAME" — every later verb talks to this Core            │
│   Credential   ~/.config/actana/cores/NAME.json (mode 0600)            │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

Next steps
  actana core status
    Reach the Core and report what it says. …
  actana project ls
  actana harness ls
  actana session start <project> "<prompt>"
  actana core shell

The Current row is the one to read on a machine that already had a Core: pairing a second Core does not move the current pointer, and the block then leads with actana core use NAME. On success the Core signs a CSR this machine generated; the private key never leaves this machine, and the issued credential is written at mode 0600 and never printed — not on --verbose, not in an error.

If this registry already has that NAME, the command replaces the stored credential in place — that is how you re-pair after token regenerate. The Panel is the opposite: it refuses a duplicate address before spending the code.

What failure looks like

Each class of refusal gets its own framed explanation at a terminal — what happened, and the exact command that fixes it — and its own exit code for scripts:

Exit Failure The fix it prints
10 Core unreachable check the address, the port, and the route from this machine
11 endpoint answered but is not a pairable Core check you dialled a Core's TLS port
12 no CA presented the dial hit something that is not this Core
13 fingerprint unconfirmed confirm interactively or pass --fingerprint
14 fingerprint mismatch stop; get a current fingerprint from a fresh pair new
15 TLS hostname mismatch dial a name that is on the certificate — the table above
16 certificate invalid mint a fresh code; the material moved underneath this one
17 refused (wrong / expired / spent code) mint a fresh code on the Core
18 rate limited wait, then retry with a fresh code
19–21 rejected / Core error / malformed response read the Core's log; mint a fresh code

Down a pipe, output stays the plain lines earlier releases printed — the frame is terminal-only, and behaviour never differs by where output goes.

See also

Built by Qcentic