Docs/Enrollment

Enrollment Process

How agents establish trust with the collector through token-based enrollment and certificate management.

Version 1.0
~12 min read

Overview

Enrollment is a one-time process that establishes trust between an agent and the collector. After enrollment, all communication uses mTLS (mutual TLS) with certificates signed by the collector's internal CA.

Security Model

ComponentPurpose
Enrollment Token One-time use, proves admin authorized this enrollment
Machine Fingerprint Binds certificate to specific hardware, prevents cert theft
CSR Agent generates its own private key - never leaves the machine
Internal CA Collector signs agent certificates, enabling mTLS

Enrollment Flow

      ADMIN                      COLLECTOR                         AGENT
        │                            │                               │
   ┌────┴────┐                       │                               │
   │ Step 1  │                       │                               │
   │ Create  │                       │                               │
   │ Token   │                       │                               │
   └────┬────┘                       │                               │
        │                            │                               │
        │── token create ───────────►│                               │
        │   --manifest "standard"    │                               │
        │   --allowed "std,monitor"  │                               │
        │                            │                               │
        │◄─── Token: ENROLL-7842 ────│                               │
        │                            │                               │
   ┌────┴────┐                       │                               │
   │ Step 2  │                       │                               │
   │ Deploy  │ (out-of-band: SSH, config management, etc.)           │
   │ Token   │─────────────────────────────────────────────────────► │
   └─────────┘                       │                               │
        │                            │               ┌───────────────┤
        │                            │               │ Step 3        │
        │                            │               │ Agent Init    │
        │                            │               │ • Fingerprint │
        │                            │               │ • Key pair    │
        │                            │               │ • CSR         │
        │                            │               └───────────────┤
        │                            │                               │
        │                            │◄──────────────────────────────│
        │                            │  EnrollRequest                │
        │                            │  • token                      │
        │                            │  • csr                        │
        │                            │  • fingerprint                │
        │                            │                               │
        │                      ┌─────┤                               │
        │                      │ Step 4: Validate & Sign             │
        │                      │ • Token valid?                      │
        │                      │ • Sign CSR with CA                  │
        │                      │ • Load manifest from token          │
        │                      └─────┤                               │
        │                            │                               │
        │                            │───────────────────────────────►
        │                            │  EnrollResponse               │
        │                            │  • agent_id                   │
        │                            │  • certificate                │
        │                            │  • manifest_signing_pubkey    │
        │                            │  • suggested_manifest  ◄──────┼─ Manifest attached
        │                            │  • allowed_manifests          │
        │                            │                               │
        │                            │               ┌───────────────┤
        │                            │               │ Step 5        │
        │                            │               │ PENDING_MANIFEST
        │                            │               │ (dormant)     │
        │                            │               └───────────────┤
        │                            │                               │
   LOCAL ADMIN ──────────────────────┼───────────────────────────────►
        │  sudo eyelog-agent         │               │ Step 6        │
        │  manifests review          │               │ Approve       │
        │                            │               │ → ACTIVE      │
        │                            │               └───────────────┤
        │                            │                               │
        │                            │◄══════════════════════════════╡
        │                            │    FULLY OPERATIONAL          │
        │                            │══════════════════════════════►│

Step 1: Create Token with Manifest

$ eyelog-collector token create \
    --name "web-server-01" \
    --group "production" \
    --manifest "standard" \
    --allowed "standard,monitor-only"

Token created!

  Token:     ENROLL-7842
  Manifest:  standard v1.0.0
  Allowed:   standard, monitor-only
  Expires:   2026-01-24 15:30:00

Token Properties:

  • Short display code (e.g., ENROLL-7842) - Easy to type
  • Attached manifest - What the agent should use
  • Allowed list - What alternatives are permitted
  • Single use only
  • Configurable expiration (default 24h)

Machine Fingerprint

The agent generates a hardware fingerprint using hardware-burned identifiers that survive OS reinstalls:

ComponentSourceWhy
SMBIOS Product UUID Motherboard firmware Primary identifier, set at manufacturing
System Serial Number OEM assigned Unique per machine from manufacturer
Board Serial Number Motherboard Additional uniqueness factor

Platform-specific collection:

  • Linux: /sys/class/dmi/id/*
  • macOS: IOKit (IOPlatformUUID, IOPlatformSerialNumber)
  • Windows: WMIC (csproduct, baseboard)

Design Decision: We explicitly avoid MAC addresses, OS machine-id, disk serials, and hostname. These can change for legitimate reasons (NIC replacement, OS reinstall, disk upgrade) and shouldn't affect agent identity. Only motherboard replacement triggers a new agent.

Certificate Storage

/etc/eyelog/
├── agent.yaml         # Configuration
└── certs/
    ├── agent.key      # Private key (0600, never transmitted)
    ├── agent.crt      # Signed certificate from collector
    ├── ca.crt         # Collector's CA certificate
    └── agent.id       # Agent ID (for reference)

Re-Enrollment

If an agent with the same fingerprint enrolls again:

  • Same machine, new token → Returns same agent_id, new certificate
  • Different machine, stolen cert → Fingerprint won't match, rejected
  • VM clone → Different fingerprint, treated as new agent

Certificate Renewal

Before the certificate expires (default 7 days), the agent requests renewal using mTLS with the existing certificate:

rpc RenewCertificate(RenewRequest) returns (RenewResponse);

message RenewRequest {
    bytes csr = 1;                  // New CSR
    string machine_fingerprint = 2; // Must match original
}