Worker Authentication Flow¶
Overview¶
The MicroDC worker uses a multi-step authentication process to securely connect to the server. The authentication flow supports both initial registration with a bootstrap token and subsequent reconnections using saved credentials.
Authentication Steps¶
1. Initial Registration (First Time Setup)¶
When a worker starts for the first time, it needs to register with the server using a bootstrap token:
The registration process follows these steps:
- Check Saved Credentials: Worker first checks if valid credentials exist in
~/.microdc/worker_credentials.json - Bootstrap Registration: If no saved credentials, worker registers using the bootstrap token
- Receive Credentials: Server returns
node_idandsecret_key - Login: Worker uses
node_idandsecret_keyto get aworker_token - Save Credentials: Worker saves the
worker_tokenfor future use
2. Subsequent Connections (Using Saved Credentials)¶
After initial registration, the worker can reconnect without the bootstrap token:
- Load Saved Credentials: Worker loads credentials from
~/.microdc/worker_credentials.json - Verify Credentials: Worker sends a test heartbeat to verify the token is still valid
- Use Existing Token: If valid, worker uses the saved
worker_tokenfor all API calls - Re-register if Needed: If token is invalid/expired, worker falls back to bootstrap token
Authentication Flow Diagram¶
┌─────────────┐
│ Worker │
│ Starts │
└──────┬──────┘
│
▼
┌──────────────────┐ ┌─────────────────┐
│ Check for Saved │────►│ Credentials │
│ Credentials │ No │ Not Found │
└────────┬─────────┘ └────────┬────────┘
│ │
│ Yes, Found │
▼ ▼
┌──────────────────┐ ┌─────────────────┐
│ Test Heartbeat │ │ Use Bootstrap │
│ (Verify Token) │ │ Token │
└────────┬─────────┘ └────────┬────────┘
│ │
│ Valid ▼
│ ┌─────────────────┐
│ │ Register with │
│ │ Server │
│ └────────┬────────┘
│ │
│ ▼
│ ┌─────────────────┐
│ │ Get node_id & │
│ │ secret_key │
│ └────────┬────────┘
│ │
│ ▼
│ ┌─────────────────┐
│ │ Login to Get │
│ │ worker_token │
│ └────────┬────────┘
│ │
│ ▼
│ ┌─────────────────┐
│ │ Save Credentials│
│ │ to Disk │
│ └────────┬────────┘
│ │
▼ ▼
┌─────────────────────────────────────────┐
│ Worker Authenticated │
│ (Uses Bearer token for all API calls) │
└──────────────────────────────────────────┘
Code Implementation¶
Registration Process (src/core/client.py)¶
async def register(self) -> None:
# 1. Try saved credentials first
if await self.server_client.try_load_credentials():
self.worker_id = self.server_client.worker_id
self.worker_token = self.server_client.auth_token
self.registered = True
return
# 2. Get bootstrap token from config
token = self.config.get("server.api_key")
if not token:
raise RegistrationError("No API key/token configured")
# 3. Register with bootstrap token
registration = WorkerRegistration(
token=token,
node_name=f"{hostname}-{worker_id}",
hardware_specs=hardware_specs,
supported_models=model_ids,
# ... other fields
)
response = await self.server_client.register_worker(registration)
# 4. Login with credentials from registration
node_id = response.node_id
secret_key = response.credentials["secret_key"]
login_response = await self.server_client.login_worker(node_id, secret_key)
# 5. Save worker token
self.worker_token = login_response.worker_token
self.server_client.credential_store.save_credentials(
worker_id=node_id,
auth_token=self.worker_token,
server_url=server_url
)
Server Communication (src/api/server_client.py)¶
class ServerClient:
async def register_worker(self, registration: WorkerRegistration):
# POST /api/v1/workers/register
# Bootstrap token in request body
response = await client.post(url, json=registration.model_dump())
return WorkerRegistrationResponse.model_validate(response.json())
async def login_worker(self, node_id: str, secret_key: str):
# POST /api/v1/workers/auth/login
# Returns worker_token for future API calls
response = await client.post(url, json={
"node_id": node_id,
"secret_key": secret_key
})
return WorkerLoginResponse.model_validate(response.json())
async def try_load_credentials(self) -> bool:
# Load from ~/.microdc/worker_credentials.json
credentials = self.credential_store.load_credentials(self.base_url)
if credentials:
self.auth_token = credentials["auth_token"]
# Test with heartbeat
if await self.send_simple_heartbeat(...):
return True
return False
Credential Storage¶
Credentials are stored in ~/.microdc/worker_credentials.json:
{
"worker_id": "worker_afl3BfE1Xzok0fSGn7TsnQ",
"auth_token": "wt_xxxxxxxxxxxxx",
"server_url": "http://localhost:8000",
"saved_at": "2025-09-23T10:30:00Z",
"status": "valid",
"secret_key": "ws_xxxxxxxxxxxxx",
"bootstrap_token": "mdc_wrk_xxxxx"
}
Credential Status Tracking¶
The credentials file includes a status field that tracks validity:
"valid": Credentials are working and can be used"invalid": Credentials failed authentication and worker has shut down
When credentials become invalid, they are preserved (not deleted) to allow:
- Remote credential updates via microDC console
- Manual credential repair without physical server access
- Credential inspection for troubleshooting
Security Features¶
- Token Types:
- Bootstrap Token (
mdc_wrk_): One-time use for initial registration - Secret Key (
ws_): Worker-specific secret for login -
Worker Token (
wt_): Bearer token for API authentication -
Credential Protection:
- Stored with 0700 permissions (owner read/write only)
- Located in user's home directory
-
Never logged in plaintext
-
Token Validation:
- Worker verifies saved tokens with heartbeat before use
- Automatic re-registration if token is invalid
- Graceful fallback to bootstrap token
API Endpoints Used¶
| Endpoint | Method | Purpose | Authentication |
|---|---|---|---|
/api/v1/workers/register |
POST | Initial registration | Bootstrap token in body |
/api/v1/workers/auth/login |
POST | Get worker token | node_id + secret_key |
/api/v1/workers/heartbeat |
POST | Send status updates | Bearer token |
/api/v1/jobs/claim |
POST | Claim jobs | Bearer token |
/api/v1/jobs/{id}/complete |
POST | Submit results | Bearer token |
Common Authentication Scenarios¶
Scenario 1: Fresh Installation¶
- Admin provides bootstrap token
- Worker registers and saves credentials
- Worker operates normally
Scenario 2: Worker Restart¶
- Worker loads saved credentials
- Verifies token is still valid
- Continues without re-registration
Scenario 3: Token Expiration (Automatic Refresh)¶
- Worker loads saved credentials
- Token expires during operation
- Worker automatically refreshes token using
secret_key - Updates saved credentials with new token
- Continues operating without interruption
Scenario 4: Failed Credential Refresh (Worker Shutdown)¶
- Worker loads saved credentials
- Token refresh fails (no
secret_keyor refresh error) - Worker marks credentials as
"invalid"in the file - Worker shuts down gracefully to prevent repeated failed auth attempts
- Credentials remain in file for console/manual updates
- Recovery requires console update, new bootstrap token, or manual credential fix
Scenario 5: Server Restart¶
- Worker's saved credentials remain valid
- Worker reconnects automatically
- No re-registration needed
Troubleshooting¶
"No API key/token configured"¶
- Set
MICRODC_API_KEYenvironment variable - Or add
api_key: your-tokento config file underserversection
"Invalid API key or authentication failed"¶
- Bootstrap token may be expired or wrong
- Check with server admin for new token
"Saved credentials invalid" / "FATAL CREDENTIAL ERROR"¶
- Credentials marked as invalid and worker has shut down
- Credentials are preserved in
~/.microdc/worker_credentials.jsonwith"status": "invalid" - Worker will not repeatedly attempt authentication to avoid server load
Recovery Options:
- Console Update (Recommended): Update credentials via microDC console/dashboard
- New Bootstrap Token: Set
MICRODC_BOOTSTRAP_TOKENenvironment variable and restart - Manual Repair: Edit
~/.microdc/worker_credentials.jsonand set"status": "valid"with correct credentials
Credential File Location¶
- Linux/Mac:
~/.microdc/worker_credentials.json - Windows:
%USERPROFILE%\.microdc\worker_credentials.json
Best Practices¶
- Keep Bootstrap Token Secure: Only use in initial setup
- Don't Share Credentials: Each worker has unique credentials
- Monitor Token Expiry: Check logs for authentication failures
- Backup Credentials: Save credential file when migrating workers
- Rotate Tokens Periodically: Re-register workers for security
- Console Management: Use microDC console to update worker credentials remotely when possible
- Credential Preservation: Never manually delete credential files - they enable remote recovery