MidnightDocumentation

RUNTIME AGENT

Connect the trusted host without sharing authority.

The packaged single-host path runs one root-level agent beside Docker. It receives desired state, reconciles owned containers, and signs observations with a credential bound to its exact agent ID.

Per-agent credentialDockercgroup v2systemd
On this page

HOST AUTHORITY

Treat agent access as root access.

One identity per host
Use a stable, unique agent ID. A credential listed for one ID cannot authenticate requests for another.
Encrypted transport
Use an HTTPS control-plane URL for any non-loopback connection and a CA bundle when the installation uses a private CA.
Owner-only secret
The agent credential file must not be group- or world-readable. Mode 0400 is the recommended baseline.
Fail closed
Production Postgres startup rejects absent, empty, unreadable, or weak agent keyrings.

PROVISION

Verify the package-created credential pair.

On the supported single-host path, Debian post-install generates both files when they are absent. The server reads /etc/midnight/agent-credentials.json through MIDNIGHT_AGENT_CREDENTIALS_FILE; the local agent reads only /etc/midnight/agent.credential through MIDNIGHT_AGENT_CREDENTIAL_FILE.

Server keyring shapejson
{
  "version": 1,
  "agents": {
    "local-agent": ["<at-least-32-random-bytes>"]
  }
}
Verify without printing secret valuesbash
sudo test -s /etc/midnight/agent-credentials.json
sudo test -s /etc/midnight/agent.credential
sudo stat -c '%a %U:%G %n'   /etc/midnight/agent-credentials.json   /etc/midnight/agent.credential
sudo jq -e   '.version == 1 and (.agents["local-agent"] | length > 0)'   /etc/midnight/agent-credentials.json >/dev/null
sudo grep -E   '^MIDNIGHT_AGENT_CREDENTIALS_FILE=/etc/midnight/agent-credentials.json$|^MIDNIGHT_AGENT_CREDENTIAL_FILE=/etc/midnight/agent.credential$'   /etc/midnight/midnight.env

The expected permissions are 0440 root:midnight for the server keyring and 0400 root:root for the local agent file. If either already exists but the pair is incomplete, stop and rotate or restore it—never truncate one side.

ENVIRONMENT

Bind the ID, server, secret, and runtime root.

MIDNIGHT_AGENT_ID
Stable ID that exactly matches the server keyring entry.
MIDNIGHT_SERVER_URL
Control-plane origin. Use HTTPS outside loopback development.
MIDNIGHT_AGENT_CREDENTIAL_FILE
Preferred path to the agent-local credential.
MIDNIGHT_RUNTIME_ROOT
Agent-owned state root; the Debian package uses /var/lib/midnight/agent.
--ca-bundle
Optional PEM CA bundle for a private control-plane certificate authority.
--client-cert / --client-key
Optional mTLS identity; configure the certificate and key together.

CONTROL LOOP

Start, observe, and prove registration.

  1. 1

    Validate host prerequisites

    Run midnight-doctor --json --live; cgroup v2, Docker reachability, permissions, and clock synchronization must pass.

  2. 2

    Restart the server

    Load the updated server keyring before allowing the new agent to authenticate.

  3. 3

    Start the agent

    The agent recovers previously owned state, registers, heartbeats, polls desired state, reconciles, and reports signed observations.

  4. 4

    Inspect both sides

    Check the systemd journal and the console host inventory. Verify the intended ID, fresh heartbeat, Docker facts, and healthy status.

Start and inspectbash
sudo systemctl restart midnight-server
sudo systemctl enable --now midnight-agent
sudo systemctl --no-pager --full status midnight-agent
sudo journalctl -u midnight-agent --since "10 minutes ago" --no-pager

ZERO-DOWNTIME ROTATION

Overlap, switch, then revoke.

  1. 1

    Add the new value

    Temporarily list the old and new credential values for the same agent ID in the server keyring.

  2. 2

    Reload the server

    Restart or reload the server so both values are accepted.

  3. 3

    Update the host

    Replace the owner-only credential file and restart the agent. Confirm a new heartbeat.

  4. 4

    Remove the old value

    Delete the retired value from the server keyring and reload once more.