-
Notifications
You must be signed in to change notification settings - Fork 5
Slave Enrollment
Enrolling a TitanX install as a slave connects it to a master's control plane. The handshake establishes mutual trust (via Ed25519 key exchange) and provisions a long-lived JWT the slave uses for subsequent master interactions.
After a successful enrollment:
- Slave has a device ID (UUID) known to master
- Slave has master's public signing key (to verify config bundles + commands)
- Slave has a JWT (typically 1-year lifetime) to authenticate subsequent polls
- Master has slave's public key (to verify slave's signed telemetry + command acks)
- Both sides have audit-log entries for the enrollment event
- Master is running and reachable from the slave's network
- Master's admin has generated an enrollment token for you (see Master Setup Guide#generate-an-enrollment-token)
- You have the master URL (e.g.,
https://10.0.0.195:8888)
If master uses a self-signed TLS cert (default for local testing), you need to either trust the cert system-wide or accept the fingerprint during enrollment.
- Click the fleet icon in the titlebar
- Select Slave in the modal
- Enter:
-
Master URL — exactly as provided, including
https://and port - Enrollment token — the one-time token from master's admin
-
Master URL — exactly as provided, including
- Save & restart
Behind the scenes during relaunch:
- TitanX generates a fresh Ed25519 keypair (device identity) if it doesn't already have one
- POSTs
/api/fleet/enrollwith the enrollment token + device public key + device metadata - Master verifies the token is valid, single-use, unexpired
- Master binds the token to the slave's device ID, stores the slave's public key
- Master returns a JWT + its own public signing key + config version
- TitanX stores all three encrypted in the secrets vault
Post-restart, you're in slave mode. Check:
-
Status bar at bottom — should read
Slave · enrolled · JWT cached - Settings → Fleet — your device ID + master URL
-
Activity log —
fleet.enrollment.successentry
If enrollment failed, the error appears as a banner. Common causes are Troubleshooting#slave-enrollment-fails-with-token-rejected.
After initial enrollment, you can flip between workforce (managed endpoint) and farm (compute node) roles without re-enrolling:
- Titlebar → second fleet icon → Slave role
- Pick new role
- Re-enroll happens automatically using the cached JWT
The master-side role record updates; destructive-command eligibility + farm provisioning eligibility update accordingly.
Note: changing role is an auditable event, logged on both sides.
For transparency — the exact payload sent by the slave to master:
{
"enrollmentToken": "<one-time token>",
"device": {
"deviceId": "<UUID, pinned forever>",
"publicKey": "<Ed25519 public key, base64>",
"hostname": "<os.hostname()>",
"platform": "darwin|linux|win32",
"arch": "arm64|x64",
"titanxVersion": "2.5.1",
"role": "workforce|farm"
},
"metadata": {
"enrolledAt": "<ISO timestamp>",
"userAgent": "TitanX/2.5.1"
}
}No API keys, no secrets, no user data. Enrollment is a pure identity exchange.
{
"ok": true,
"deviceId": "<echoed back>",
"jwt": "<JWT token, 1-year TTL default>",
"masterPublicKey": "<Ed25519 public key, base64>",
"configVersion": 42,
"serverUrl": "<master URL>",
"minSlaveVersion": "2.5.0"
}The minSlaveVersion field lets master refuse enrollment from slaves running protocol-incompatible older versions.
For production, master should run behind a real TLS cert (Let's Encrypt, corporate CA, etc.) with a domain name.
For local-network / testing, master often runs with a self-signed cert. Slave needs to either:
-
Trust the cert system-wide — add to OS keychain or
/etc/ssl/certs/ - Accept via fingerprint during enrollment — master's enrollment QR code (v2.6) or displayed fingerprint includes the cert thumbprint; slave pins it
In v2.5.1: slaves accept self-signed certs transparently (warning logged). This will change in v2.6 to require explicit trust.
JWT is stored encrypted in the slave's secrets vault. Contents:
{
"deviceId": "...",
"role": "workforce",
"iss": "titanx-master",
"sub": "<device-id>",
"iat": 1713456789,
"exp": 1744992789
}Slave includes the JWT as Authorization: Bearer <jwt> on every request. Master validates on every request.
When JWT is near expiry (< 7 days), TitanX automatically initiates a refresh:
- Slave POSTs
/api/fleet/refresh-jwtwith current JWT - Master validates, issues new JWT if device is still trusted
- Slave replaces cached JWT
If refresh fails (device was revoked), slave falls back to "requires re-enrollment" state — operator sees a banner asking for a new enrollment token.
If master revokes the slave:
- Next request returns
401 Unauthorizedwith reasondevice_revoked - Slave clears cached JWT
- Slave UI shows revocation banner
- Slave continues operating as Regular mode (single-machine) until re-enrolled
Master's revocation is final until re-enrollment with a new token.
For IT admins deploying to many machines via MDM or config management:
- Generate a template config JSON (master's admin UI produces one)
- Deploy to each slave at
~/.aionui-config/fleet-bootstrap.json:
{
"masterUrl": "https://fleet.mycompany.com:8888",
"enrollmentToken": "<token>",
"role": "workforce"
}- On next TitanX launch, if slave is not already enrolled, it reads this file and auto-enrolls
- File is deleted on success (one-time use)
See Troubleshooting#slave-enrollment-fails-with-token-rejected for the full list. Most frequent:
| Error | Cause | Fix |
|---|---|---|
token_expired |
Token TTL elapsed | Generate a new token on master |
token_already_used |
One-time token re-used | Generate a new token |
master_unreachable |
Network / URL wrong | Verify master URL; test with curl |
tls_mismatch |
Self-signed cert not trusted | Trust cert or enable fingerprint pinning |
version_mismatch |
Slave older than minSlaveVersion
|
Upgrade slave to meet master's minimum |
- Master Setup Guide — master-side setup
- Fleet Mode Overview — the big picture
- Device Identity and Signing — what the keys are used for
- Troubleshooting — enrollment-specific errors
TitanX · Enterprise AI Agent Orchestration · Apache-2.0
Docs: Wiki · Technical docs · Releases · Security
Last updated for v2.5.1 — report doc issue · contribute to the wiki
📖 Getting Started
🧩 Core Concepts
- Architecture Overview
- Agents and Teams
- Agent Gallery and Templates
- ACP Runtimes
- MCP Servers
- Workspaces
- Reasoning Bank
👤 End-User Guides
- Hiring Agents from the Gallery
- The Sprint Board
- Conversations and Chat UI
- Using Custom Assistants
- Skills Hub
- Cron and Scheduled Tasks
- Observability
- Caveman Mode
🌐 Fleet Mode
- Fleet Mode Overview
- Master Setup Guide
- Slave Enrollment
- Agent Farm Setup
- Publishing Agent Templates
- Command Center
- Device Forensics and Revocation
🌙 Dream Mode
- Dream Mode Overview
- Enabling Dream Mode
- Dream Pass Internals
- Consolidated Learnings Dashboard
- Privacy and Redaction
🔒 Security
- Security Model
- IAM Policies
- Audit Logging
- Device Identity and Signing
- Secrets Management
- Compliance and Data Residency
🛠 Developer
- Development Setup
- Project Structure
- Code Conventions
- Testing
- Adding an ACP Runtime
- Adding an MCP Server
- Pull Request Workflow
📘 Reference
- Configuration Keys
- Environment Variables
- IPC Channels
- Database Schema
- Fleet Command Types
- Telemetry Shape
- CLI and Keyboard Shortcuts
❓ Help
🔗 Outside the wiki
v2.5.1 · 50+ pages · Contribute