CoreCP

Connecting a second panel

A second brand is a second CoreCP installation. It runs the same software and installs the same packages from the same source — and shares nothing else. Its own database, its own customers, its own keys, its own certificate authority, its o

Written for: Administrator

A second brand is a second CoreCP installation. It runs the same software and installs the same packages from the same source — and shares nothing else. Its own database, its own customers, its own keys, its own certificate authority, its own branding.

What the first panel (the primary) does know about the second (the replica): which version it runs, whether it is healthy, which release channel and wave it is in, and whether its licence is live. Nothing else. That is not a rule somebody has to remember: the panel at the other end simply has no command that could return a customer's anything.

Administrators only. Resellers and end customers never see any of this.

What you need

  • A second server with a working CoreCP panel on it: its own hostname, its own database, its own certificate. That is the same installation as the first time.
  • Its own node CA on that machine. This is the one thing you must never share — see "Why its own CA" at the bottom.
  • Outbound HTTPS from the replica to port 8443 on the primary. Nothing needs to be open inbound on the replica: it dials out, never the other way round.

Install first, connect second

These are two different jobs and they are done in two different places, which is the same split Plesk 360 and Rancher make:

WhereWhy
Installing a CoreCP panel on the second machineat a terminal, as root (bootstrap/install.sh, or scripts/deploy-panel-server.sh from the dev machine)it writes systemd units, creates a database and mints that machine's own certificate authority
Connecting it to this onein the panel, under Settings → Managed panelsit is a guided, infrequent setup that benefits from a form, a validation and a confirmation

The panel never installs anything on the other machine, and never holds a login for it. All it hands out is a code; whoever has root over there runs one line.

The short way: in the panel

Settings → Managed panels → Connect a panel. Administrators only — a reseller does not see the entry, and the API refuses the routes behind it whatever the sidebar says.

  1. Give the panel a short identifier (panel2), a name for the list, and the channel and wave it should update in.
  2. Optionally pin it to an IP address — the outbound address of the other panel. A connect from anywhere else is then refused.
  3. Press Issue the code. The panel shows the exact line to run on the other machine, with a copy button and its expiry counting down:
corecp-panel connect --code corecpf1.eyJ2IjoxLCJwIjoicGFuZWwyIiwi…

The code is shown once. Only a hash of it is stored, so this is the only place it will ever exist. Lost it? Issue a new one for the same panel — nothing else has to be redone. Withdraw the code kills it immediately.

  1. Run that line on the other machine (step 3 below is the same command, in detail). The screen moves from Waiting to connect to Connected by itself, and then shows the version, the health and the fingerprint of the replica's own node CA.

Afterwards the list shows every connected panel with its version, health, channel, wave and licence. Clicking a row opens it: assign a channel, assign a wave, trigger an update, hold updates, and — behind typing the panel's name — withdraw its licence.

What the screen will never do. It shows the fleet CA's fingerprint next to this panel's own node CA, so you can see with your eyes that they are two different authorities. It does not create, rotate or export either of them: those are root operations at a terminal (corecp-panel panels ca). And there is no button anywhere on it that reaches the other panel's customers — the agent at the other end implements no instruction that could answer.

The long way: at a terminal

Everything the screen does is also a command, which is what you want for ten panels rather than one. The rest of this page is that path.

Step 1 — create the panel on the primary

$ corecp-panel panels add panel2 --name "Second brand" --channel beta --wave 2 \
    --config /etc/corecp-panel/panel.yaml
managed panel panel2 created (beta, wave 2)
Next: corecp-panel panels code panel2 --config /etc/corecp-panel/panel.yaml

panel2 is a short slug you choose. It becomes the common name of the panel's certificate and the login half of its apt credential, so keep it short and leave it alone afterwards.

--channel is the release channel (edge, beta, stable, steady) and --wave is which wave this panel updates in. Panels are the outermost ring of the same wave system the servers use.

Step 2 — ask for a connect code

$ corecp-panel panels code panel2 --ip 185.117.226.123 --ttl 15m \
    --config /etc/corecp-panel/panel.yaml
Run this on panel2, within 15m0s:

  corecp-panel connect --code corecpf1.eyJ2IjoxLCJwIjoicGFuZWwyIiwi…

valid until  2026-08-09T17:10:24Z
pinned to    185.117.226.123 — a connect from any other address is refused
The code is single use and is burned on the first attempt that gets past the address check.

Use --ip. Without it the code works from anywhere; with it the code works only from the machine you meant. A code somebody reads over your shoulder is then worthless.

The code is single use and expires on its own. There is no password inside it: the apt credential comes back in the reply, over a channel the replica has already verified. A code in a chat window is therefore not a password in a chat window.

Step 3 — paste the line on the replica

$ corecp-panel connect --code corecpf1.eyJ2IjoxLCJwIjoicGFuZWwyIiwi… \
    --config /etc/corecp-panel/panel.yaml
connected as panel2
  channel      beta (wave 2)
  fleet CA     739d876dc5d26c76
  its node CA  c4430ea564db75b6
  our node CA  ed466a89fea08858   (verified different — neither panel signs for the other's nodes)
  apt login    panel-panel2 at packages.corecp.dev

Restart the panel to start reporting: systemctl restart corecp-panel

That fourth line is the most important one on this page. The two panels showed each other their own node CA and established that there are two of them. Had they matched, no certificate would have been issued and nothing would work — which is correct.

Then:

$ systemctl restart corecp-panel
$ corecp-panel connect status --config /etc/corecp-panel/panel.yaml
connected to panel1.corecp.dev:8443 as panel2
  since        2026-08-09T16:45:23Z
  channel      beta (wave 2)
  entitlement  installed
  last contact 9s ago

It can take up to a minute before apt works on the replica: the build server pulls the list of valid credentials from the primary once a minute.

Step 4 — look from the primary

$ corecp-panel panels list --config /etc/corecp-panel/panel.yaml
ID      STATE      CHANNEL  WAVE  HOLD  VERSION  HEALTH  LICENCE  LAST SEEN
panel2  connected  beta     2     no    0.14.0   ok      live     9s ago

What you can do with a connected panel

$ corecp-panel panels channel panel2 stable --config …   # a different channel
$ corecp-panel panels wave panel2 1 --config …           # a different wave
$ corecp-panel panels upgrade panel2 --config …          # update now
$ corecp-panel panels hold panel2 --config …             # no updates for now
$ corecp-panel panels resume panel2 --config …           # updates again
$ corecp-panel panels revoke panel2 --config …           # withdraw the licence
$ corecp-panel panels reinstate panel2 --config …        # give it back

Every one of those is also a control in Settings → Managed panels, on the same API — a fleet of forty panels stays scriptable, and one panel stays a click.

An instruction is queued and carried out the next time the replica reports (every 15 to 30 seconds). What actually happened comes back — in the terminal, and in the Outstanding instructions list on the panel's own screen:

$ corecp-panel panels show panel2 --config … | tail -3
  DIRECTIVE  VERB          STATE  DETAIL
  1          update.apply  done   upgraded: corecp-agent 0.30.12 -> corecp-agent 0.32.7

And that is the whole list. There is no panels accounts, no panels sql, no panels shell — not because they were forgotten, but because the agent at the other end has no answer for one.

What revoking does, and what it does not

panels revoke removes the apt credential and closes fleet access. Within a minute that panel can install nothing.

It touches no data. Its customers keep being served, the database stays, the certificates keep renewing, the backups keep running. A licence ending is a panel that stops receiving updates — not a panel that stops.

Disconnecting again

On the replica:

$ corecp-panel connect leave --config /etc/corecp-panel/panel.yaml
left the fleet of panel1.corecp.dev:8443 (was panel2)
A running panel notices within one poll interval and stops reporting; there is
nothing to restart.

The apt credential stays until you remove it yourself (rm -f /etc/apt/auth.conf.d/corecp-fleet.conf).

Why its own CA

Each panel has its own certificate authority for its servers. You must never share one between two brands. If they shared one, a replica that was taken over could mint certificates the primary's servers trust — and then the second brand is a key to the first.

So there are three: the primary's node CA, the replica's node CA, and a third authority for the link itself (the fleet CA). Both sides check this when they connect and refuse if any two of them are the same.

$ corecp-panel panels planes --config /etc/corecp-panel/panel.yaml | head -8
PLANE  SHARED     THING                                       WHY
build  SHARED     apt repository                              one pool of packages: …
build  SHARED     release channels (edge/beta/stable/steady)  a channel is a view of …
…
data   per panel  node CA                                     NEVER shared: a compromised replica …

See also: docs/architecture.md, "Primary and replica panels (three planes)", and docs/research/ui-vs-cli.md for why connecting is a screen and key custody is not.