Installing the Cosigner

Regular mode on Linux with Docker. Nitro Enclave support is coming soon.

Install, verify, pair, connect
Click to open the full-size diagram

Prerequisites

  • Host: Linux amd64 or arm64 for production. macOS or WSL 2 for development.
  • Docker: Engine 20.10+ with Compose v2.
  • cosign: v3+. The installer adds it if missing.
  • From Fystack: a pairing token (cps_...) and your Apex endpoint.
  • Callback server: required for production. See Approval Callback.

Network: no inbound ports. Outbound HTTPS to Apex, the Fystack Gateway, ghcr.io, your callback and (unattended profile) AWS KMS.


Step 1: Install cosigner-cli

curl -sSL https://cosigner.fystack.io/install.sh | sh

Checks the binary's SHA-256 and Sigstore signature, then installs to /usr/local/bin (or ~/.local/bin).

Option Env var Effect
--version vX.Y.Z COSIGNER_VERSION Install a specific release
--dir DIR COSIGNER_INSTALL_DIR Install location
--skip-docker-checkSkip Docker checks

Step 2: Create the instance directory

export COSIGNER_HOME=/srv/cosigner
mkdir -p $COSIGNER_HOME/secrets && chmod 700 $COSIGNER_HOME/secrets

Step 3: Write the config

Pick a profile:

  • manual (default): storage key wrapped with a password. Enter it on every start. No auto-restart.
  • unattended: storage key wrapped by your AWS KMS key. Starts on boot.

Keep the file outside the instance directory; up copies it in.

config.yaml

storage:
  backend: sqlite
  sqlite:
    path: data/cosigner.db
  encryption:
    kek:
      type: password_envelope
      config:
        path: /run/secrets/storage-kek.enc
approval:
  require_callback: true
audit:
  type: file
  config:
    path: /var/lib/cosigner/audit.jsonl
callback:
  url: https://YOUR-CALLBACK-HOST/cosigner/approve
  timeout: 30s
  retry_count: 1
  private_key:
    type: file
    config:
      path: /run/secrets/cosigner-private.der.hex
  response_public_key_path: /run/secrets/server-public.pem
  • /var/lib/cosigner maps to $COSIGNER_HOME/state; /run/secrets maps to $COSIGNER_HOME/secrets (read-only).
  • Unattended: encrypt a random 32-byte key with your KMS key, save the base64 ciphertext as secrets/storage-kek.kms. The container needs kms:Decrypt via an IAM role.
  • Callback keys: place them in secrets/ (mode 600), or run cosigner-cli callback add after setup.

Step 4: Check the host

cosigner-cli doctor

Checks Docker, cosign and config. Reports unconfigured, configured but unpaired or paired.

Step 5: Pair and start

cosigner-cli up \
  --apex-endpoint https://YOUR-APEX-HOST \
  --config /secure/config.yaml

Add --profile unattended for KMS. up then:

  1. Verifies the newest ghcr.io/fystack/cosigner release with cosign and pins its digest, before asking for any secret.
  2. Prompts for the storage password (manual) and pairing token. Use --token-file to pass the token non-interactively.
  3. Pairs: generates an Ed25519 identity, registers it with Apex, saves state/pairing.yaml.
  4. Starts the container, unlocks it and connects to the Gateway.

Pin a release with --image ghcr.io/fystack/cosigner@sha256:.... Digests are on cosigner.fystack.io.

Step 6: Verify

cosigner-cli status
cosigner-cli info
cosigner-cli logs -f

Once status shows ready, the cosigner is online and can join keygen.

Instance layout

Path Contents
cosigner-cli.yaml Apex endpoint, pinned image digest, profile
config.yaml Runtime config (read-only)
docker-compose.yaml Generated, hardened Compose file
secrets/ Wrapped storage key and callback keys
state/pairing.yaml Pairing record from Apex
state/cosigner.key Ed25519 identity key
state/data/cosigner.db Encrypted key shares and session state
state/audit.jsonl Signed audit log

Run on boot

Unattended profile only. Adapt the bundled systemd unit:

/etc/systemd/system/cosigner.service

[Unit]
Description=Fystack Cosigner (KMS unattended profile)
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
User=cosigner
Group=cosigner
SupplementaryGroups=docker
ExecStart=/usr/local/bin/cosigner-cli --home /var/lib/fystack-cosigner start
ExecStop=/usr/local/bin/cosigner-cli --home /var/lib/fystack-cosigner stop
TimeoutStartSec=360
TimeoutStopSec=60
UMask=0077

[Install]
WantedBy=multi-user.target

For the manual profile, pass the password through a file descriptor:

COSIGNER_PASSWORD_FD=3 cosigner-cli start 3< /run/secrets/cosigner-pw

Troubleshooting

Symptom Fix
Image signature verification failed Don't bypass. Check the image reference and contact security@fystack.io.
identity already registered Restore the original pairing data from backup instead of re-pairing.
Exits right after start Startup callback ping failed. Check the callback is reachable and trusts cosigner-public.pem.
AlreadyExists Another instance with this identity is connected. Stop it.
PermissionDenied Cosigner was revoked. It will not reconnect.
Not ready after first start Generating ECDSA pre-parameters. Wait up to 5 minutes.