Skip to main content

Install on Linux

The Linux installer (install-node-linux.sh) authenticates the release, verifies your signed enrollment package, validates your certificate material in a private staging directory, and only then installs a hardened systemd service. Nothing on the host changes until every check has passed.

Before you start: confirm the requirements — amd64, systemd, a TPM 2.0 device, cosign and jq installed, and the five customer-held files ready.

What gets installed​

PathOwner / modeContents
/usr/local/bin/edgepki-noderoot, 0755Node binary
/etc/systemd/system/edgepki-node.serviceroot, 0644systemd unit
/etc/edgepki/root:edgepki, 0750config.json, policy-trust.json, registration-trust.json, your TLS material (0640) and acme-eab.json (0600, owned by edgepki)
/var/lib/edgepki/edgepki, 0700Node state: identity, TPM-wrapped key blobs, audit log, ACME and rotation state
/var/lib/edgepki/enrollment-tokenedgepki, 0600One-time token; deleted by the node after successful enrollment

The installer creates a system user edgepki (home /var/lib/edgepki, shell /usr/sbin/nologin) and adds it to the tss group when that group exists, so the service can reach the TPM resource manager.

The unit runs as edgepki with no capabilities, ProtectSystem=strict, ProtectHome=yes, NoNewPrivileges=yes, MemoryDenyWriteExecute=yes, a 0077 umask, and write access only to /var/lib/edgepki. It restarts on failure after 5 seconds.

Install​

  1. Create the enrollment package. In ConsoleMesh nodes select Enroll node, enter the node name, choose Linux service as the runtime and select Create one-time package. Download the signed package. See Enrollment for details.
  2. Copy the package and your material to the host. Place the bootstrap package (named sectigo-edge-<node-name>.bootstrap.json) in a working directory, and create a private node-material directory with local-api.crt, local-api.key, workload-ca.pem, edge-client.crt and edge-client.key.
  3. Download the release into the same working directory (below).
  4. Verify the release and package without installing (below).
  5. Install as root (below).
  6. Delete the bootstrap package from the working directory (for example with shred -u). It is single-use, but should not be left on disk.

Download the release​

All seven files must come from one release directory. The console's ConsoleDownloads & install page shows this command with the current version filled in; v0.1.26 below is an example.

mesh-node-01 (bash)
mkdir -p ~/sectigo-edge && cd ~/sectigo-edge
base=https://downloads.sharppki.com/v0.1.26
for f in edgepki-node-linux-amd64 edgepki-node.service install-node-linux.sh \
  RELEASE.json bootstrap-trust.json SHA256SUMS manifest.sigstore.json; do \
  curl -fSLO "$base/$f"; done

Verify without installing​

--verify-only checks the Sigstore signature over SHA256SUMS, pins it to the exact repository, release workflow, tag and GitHub OIDC issuer, checks the digests of the binary, unit, installer and trust file, and verifies the bootstrap package's signature, lifetime and platform. It does not need root and changes nothing.

mesh-node-01 (bash)
sh ./install-node-linux.sh --verify-only \
  --bootstrap-package ./sectigo-edge-mesh-node-01.bootstrap.json \
  . hassard0/sharppki
Sectigo Edge v0.1.26 release and signed Linux bootstrap package verified.

Install the service​

Run the same command as root without --verify-only, adding --material-directory. Verification runs again immediately before any privileged change. The installer then starts the service and waits up to 60 seconds for the node to enroll and delete its one-time token.

mesh-node-01 (bash)
sudo sh ./install-node-linux.sh \
  --bootstrap-package ./sectigo-edge-mesh-node-01.bootstrap.json \
  --material-directory ./node-material \
  . hassard0/sharppki
Created symlink /etc/systemd/system/multi-user.target.wants/edgepki-node.service → /etc/systemd/system/edgepki-node.service.
Sectigo Edge Mesh Node v0.1.26 enrolled and installed from a verified release. Securely delete the source bootstrap package.

Installer arguments​

install-node-linux.sh [--verify-only] [--bootstrap-package PACKAGE] [--material-directory DIRECTORY] [RELEASE_DIRECTORY] [OWNER/REPOSITORY]
install-node-linux.sh [--verify-only] --upgrade [RELEASE_DIRECTORY] [OWNER/REPOSITORY]
ArgumentMeaning
--verify-onlyAuthenticate the release (and package, if given) and exit. No root needed.
--bootstrap-package PACKAGEThe signed package downloaded from the console. Required for installation.
--material-directory DIRECTORYDirectory containing the five customer-held files. Required for installation.
--upgradeUpgrade an already-enrolled node in place. Cannot be combined with a package or material directory. See Upgrades.
RELEASE_DIRECTORYDirectory holding the downloaded release files. Defaults to the installer's own directory; . is typical.
OWNER/REPOSITORYSource repository pinned in the Sigstore identity. Defaults to hassard0/sharppki; pass it explicitly as the console command does.

Exit code 64 means the arguments were invalid (the usage text is printed).

Confirm the node is healthy​

mesh-node-01 (bash)
systemctl status edgepki-node --no-pager
● edgepki-node.service - Sectigo Edge Mesh Node
   Loaded: loaded (/etc/systemd/system/edgepki-node.service; enabled; preset: enabled)
   Active: active (running) since Thu 2026-10-01 14:02:11 UTC; 2min ago
 Main PID: 41873 (edgepki-node)
test -f /var/lib/edgepki/identity.json && echo enrolled
enrolled
test -e /var/lib/edgepki/enrollment-token || echo "token consumed"
token consumed

Then query the local health endpoint with the sectigo-edge CLI (download sectigo-edge-linux-amd64 from the same release). Pass the CA that issued local-api.crt so the CLI can verify the local TLS certificate:

mesh-node-01 (bash)
sectigo-edge -ca ./node-material/local-api-ca.pem status
{
"audit_head": "q3V9kM2f0bX8w1n4Ezr7cT5yHjL0pA6sDgUe2RiWoNc",
"audit_sequence": 12,
"dependency_discovery": {
  "configured_probes": 0,
  "enabled": false,
  "failed": 0,
  "queued": 0,
  "successful": 0
},
"integrations": [
  {
    "assigned": false,
    "enabled": false,
    "health": "disabled",
    "installed": true,
    "kind": "acme",
    "revision": 0
  },
  {
    "assigned": false,
    "enabled": false,
    "health": "disabled",
    "installed": false,
    "kind": "est",
    "revision": 0
  }
],
"node_id": "node_7c1e4b2a-93d5-4f61-8a0e-2b6d9f3c5e17",
"policy_last_synced_at": "2026-10-01T14:03:40Z",
"policy_sha256": "Jd8rT2qWm5Xz1vB7nK4eYc0hLpA9sF3uGiR6oE2wNtM",
"policy_version": 7,
"status": "ok"
}

Values above are examples. local-api-ca.pem stands for whichever CA bundle verifies your local-api.crt. Finally, confirm the node appears as healthy under ConsoleMesh nodes.

Logs​

The node logs structured messages to the journal:

mesh-node-01 (bash)
journalctl -u edgepki-node --since "10 min ago" --no-pager

Troubleshooting installation​

MessageCause and fix
Required verifier is not installed: jq (or cosign, xxd, …)Install the named tool and rerun.
Required regular release file is missing: <name>Download all seven release files into RELEASE_DIRECTORY. Symbolic links are rejected.
Release signature or workflow identity is invalidThe files are not from the expected repository/workflow/tag, were modified, or cosign cannot reach its trusted root. Re-download from downloads.sharppki.com and check the OWNER/REPOSITORY argument.
Release artifact digest mismatch: <name>A file does not match the signed SHA256SUMS. Re-download it.
Bootstrap package signature is invalid / Bootstrap envelope schema is invalidThe package was edited, truncated or is not a console download. Create a new package.
Bootstrap or signing-key validity window is invalidThe package has expired (or the host clock is wrong). Check the clock and create a new package.
Bootstrap payload schema or platform is invalidThe package was created for a different runtime (for example Windows service). Create a Linux package.
A local TPM 2.0 device is required by this hardware-rooted bootstrap packageNo /dev/tpmrm0 or /dev/tpm0. Enable the TPM in firmware or the hypervisor.
Required regular customer-held material is missing: <name>Add the missing file to node-material.
Bootstrap material failed node runtime validation; no system files were changedA TLS key pair does not match, workload-ca.pem contains no certificates, or a trust file is not bound to your workspace. Fix the material and rerun.
This host is already enrolled; rerun with --upgrade and no bootstrap package/var/lib/edgepki/identity.json exists. Use --upgrade instead.
Privileged installation requires --bootstrap-package; legacy config mode is verification-onlySupply the signed package; a plain config.json can only be verified.
The verified service is installed and retrying, but enrollment did not finish within 60 seconds…The service is running but could not enroll yet (network, outbound mTLS, PQC negotiation or TPM attestation). Check journalctl -u edgepki-node. The token stays protected on disk until it succeeds or expires; if it expires, uninstall and enroll with a new package.

More symptoms and fixes are collected in Troubleshooting.