Director
The director is the central management service. It runs on a server and provides the REST API, admin web UI, CA authority, and user authentication for the dcvix session broker.

Responsibility
- Manage agent registrations and certificate lifecycle (auto-registration, renewal, revocation)
- Authenticate users via PAM, LDAP, RADIUS, or external commands (with optional OTP via PrivacyIDEA or external scripts)
- Issue and verify PASETO v4 encrypted tokens for user and admin sessions
- Maintain session and server state by collecting updates from agents
- Enforce access policy via JSON-based user-to-server and pool-to-server mappings
- Act as DCV auth token verifier for DCV sessions and DCV Gateway session resolution
- Serve the React-based admin web UI for agent lifecycle management
Lifecycle
flowchart LR
A[Config Load] --> B[CA Init]
B --> C[DB Init]
C --> D[Agent DB Init]
D --> E[Server Start]
E --> F[SIGHUP Reload Policy]
- Config load - reads
dcvix-director.conf, applies defaults
- CA init -
ca.NewSigner(dataDir) loads existing CA or auto-generates ECDSA P-256 CA + server cert (see ca/signer.go). The server cert's CN/SAN includes the hostname from hostname -f - agents verify this against the hostname they connect to, so they must match.
- DB init - runtime session DB (in-memory SQLite) and policy DB (in-memory loaded from JSON files)
- Agent DB init - persistent SQLite at
{dataDir}/agents.db for agent registrations
- Server start - HTTPS + mTLS listener on
director_host:director_port, routes registered
- Runtime - serves API, collects agent updates, runs housekeeper cleanup
- SIGHUP - reloads policy JSON files without restart
| Direction |
Method |
Content |
| Agent in |
POST /v1/agent/register |
CSR + GUID + hostname (plain HTTPS) |
| Agent in |
POST /v1/agent/renew |
CSR (mTLS) |
| Agent in |
POST /v1/agent/update |
Session list + system stats + tags (mTLS) |
| User in |
POST /v1/user/login |
UserID + password + optional OTP |
| Admin in |
POST /v1/admin/login |
Admin credentials |
| Launcher in |
GET /v1/user/servers |
Server list for authenticated user |
| Out to agent |
POST /v1/sessions |
Create session request (forwarded from user) |
| Out |
Signed cert |
To agent on successful register/renew |
| Out |
PASETO token |
To user/admin on successful login |
Internal Packages
| Package |
Role |
ca/ |
CA auto-generation, CSR signing (14-day agent certs, 10-year CA) |
database/ |
SQLite via GORM - runtime sessions (in-memory) + agents (persistent) |
auth/ |
PAM, LDAP, RADIUS, external command authentication |
token/ |
PASETO v4.local token creation (2h expiry) and verification |
client/ |
mTLS HTTP client for outbound agent communication |
housekeeper/ |
Periodic cleanup - runtime sessions (40s default) + stale agent registrations (hourly) |
models/ |
GORM models including AgentRegistration (agents table) |
server/ |
HTTP + mTLS with GetCertificate callback for hot-reload |
frontend/ |
React SPA embedded via frontend.go |
API Endpoints
| Method |
Endpoint |
Auth |
Description |
| GET |
/v1/health |
None |
Health check |
| GET |
/v1/auth-health |
Auth |
Health check with authentication |
| POST |
/v1/logout |
None |
Clears session cookie |
| POST |
/v1/agent/register |
None (TOFU) |
Agent registration via CSR + GUID + hostname. Returns 403 pending until admin approves, then returns signed cert + CA + agentId. |
| POST |
/v1/agent/renew |
mTLS |
Agent certificate renewal. Sends base64 DER CSR, returns signed PEM cert. |
| POST |
/v1/agent/update |
mTLS |
Receives agent updates (sessions + stats + tags) |
| POST |
/v1/admin/login |
None |
Admin authentication, checks IsAdmin policy, sets session cookie |
| GET |
/v1/admin/agents |
Admin |
List agent registrations. Query: ?state=pending|registered|revoked |
| POST |
/v1/admin/agents/{guid}/approve |
Admin |
Approve a pending agent |
| POST |
/v1/admin/agents/{guid}/deny |
Admin |
Deny and remove a pending agent |
| POST |
/v1/admin/agents/{guid}/revoke |
Admin |
Revoke a registered agent |
| POST |
/v1/user/login |
None |
User authentication, sets session cookie |
| POST |
/v1/user/authtokenverify |
None |
DCV auth token verification (reads form value authenticationToken, returns XML) |
| GET |
/v1/user/servers |
Auth |
Server list (and pool members) accessible to the authenticated user |
| GET |
/v1/user/connectiontoken |
Auth |
PASETO token for DCV connection. Query: ?sessionId=X&serverId=Y |
| POST |
/v1/user/sessions |
Auth |
Create a session on an agent. Body: {"serverId": "...", "sessionType": "..."} |
| POST |
/v1/user/servers/{server}/config |
Auth |
Set DCV config parameters on a server |
| GET |
/v1/sessions |
Admin |
List all known sessions |
| POST |
/v1/sessions |
Admin |
Create a new session on an agent. Body: {"serverId": "...", "userId": "...", "sessionId": "...", "sessionType": "..."} |
| DELETE |
/v1/sessions/{id} |
Admin |
Close a session (sends close to agent) |
| GET |
/v1/servers |
Admin |
List all known servers with their associated sessions |
| POST |
/resolveSession |
Gateway IP |
DCV Gateway session resolution |
curl Examples
Admin Login
curl --cacert ca.pem \
--cookie-jar cookies.txt \
-X POST https://127.0.0.1:8445/v1/admin/login \
-d '{"userID": "'$USERNAME'", "password": "'$PASSWORD'"}'
List Sessions
curl --cacert ca.pem \
--cookie cookies.txt \
https://127.0.0.1:8445/v1/sessions
Close Session
curl --cacert ca.pem \
--cookie cookies.txt \
-X DELETE \
https://127.0.0.1:8445/v1/sessions/SESSION_ID
Agent Update
curl --cert agent.crt --key agent.key --cacert ca.pem \
-X POST \
-H "Content-Type: application/json" \
-d '{
"sessions": [],
"stats": {
"hostname": "server.domain.com",
"free_memory": 54545088512,
"total_memory": 66996871168,
"cores": 8,
"cpu_usage": 1.16,
"load1": 0.11,
"load5": 0.13,
"load15": 0.15
},
"tags": ["tag1", "tag2"]
}' \
https://127.0.0.1:8445/v1/agent/update
DCV Gateway Session Resolution
curl --noproxy '*' --cacert ca.pem \
-X POST \
-H "Content-Type: application/json" \
-d '{"sessionId": "autosession", "transport": "XXXX", "clientIpAddress": "127.0.0.1"}' \
https://127.0.0.1:8445/resolveSession
Failure Modes
| Scenario |
Behavior |
agents.db lost |
Recreated empty on startup. Agents re-register with their persisted GUID; admin must re-approve. |
CA (ca.key) lost |
Auto-regenerated on startup. All existing agents must re-register (old certs signed by different CA are invalid). |
token_key not set |
Generated ephemerally on each startup - all existing PASETO tokens become invalid on restart. Set token_key in config for persistence. |
| Agent unreachable |
Session create/close operations fail. Director returns error to the caller. |
| Policy JSON corrupt |
SIGHUP logs error, keeps last valid policy in memory. |