Token Rotation

Rotate account tokens, per-agent relay tokens, and E2E secrets without confusing the distinct trust boundaries in WakeLink.

The 3-Token Model

WakeLink authenticates three distinct actor types with three distinct secret types. Each secret carries the minimum privilege required for its role.

Secret typePrefixScopeStorageOrigin
Master API tokenwl_Full account access — Android app account auth, CLI, dashboardAndroid Keystore / CLI config (Hashed on Server)Server-generated
Agent Relay tokenwla_Single-agent WebSocket relay auth onlyESP32 NVS (Hashed on Server)Server-generated
EWSP E2E Secret(none)End-to-end encryption — never sent to the relayAndroid Keystore / ESP32 NVSClient-generated
Note
Key security property: Your master wl_ API token is never sent to agent hardware. Only the per-agent wla_ relay token lives on the chip — so a stolen or compromised agent cannot be used to access your account.

WebSocket Auth Logic

When an agent connects to the relay, the server inspects the token prefix to determine how to authenticate it:

Token prefixLookup pathNotes
wla_SHA-256 hash → nodes.agent_api_token_hashRecommended path for all new firmware
wl_SHA-256 hash → users.api_token_hashLegacy path; discouraged for firmware

Tokens are never stored in plaintext server-side — only their SHA-256 hashes are persisted.

Agent Identity (agent ID)

Unlike other systems, the WakeLink relay does not assign IDs to agents. The agent_id (e.g., WL12AB34CD) is generated by the agent hardware itself based on its unique MAC address. This ensures consistent identity even if the agent is moved between different relay accounts.

Android Provisioning Flow

The Android app's "Wizard Setup" handshake ensures the master token and E2E secret stay off the relay:

1 Agent provides ID, User names it

The app discovers the agent on the local network. The agent provides its hardware-generated agent_id. The user gives it a human-readable name in the app.

2 App registers agent on Relay

The app calls POST /api/v1/agents/ authenticated with the master wl_ token, passing the agent's agent_id. The server registers the agent and returns a fresh Relay Access Token (wla_…). This is the only time this token is returned in plaintext.

3 App generates E2E Secret

The app generates a random EWSP E2E Secret (agent_token) locally. This secret is never sent to the relay.

4 Secrets delivered to Agent over local TCP

The app sends both the wla_ token and the agent_token secret to the agent over a local secure channel.

5 Agent stores secrets in NVS

The agent saves both secrets to Non-Volatile Storage. It uses wla_ to authenticate with the relay and agent_token to decrypt commands from the user.
Warning
The agent_token is returned once at agent creation. If you lose it before provisioning the ESP, rotate the token to issue a new one — the old one is discarded.

Rotating an Agent Token

Rotate a per-agent relay token at any time without affecting your master credentials or other agents:

POST /api/v1/agents/{agent_id}/rotate-token
Authorization: Bearer wl_your_master_api_token
# Response
{
  "agent_id": "esp32-living-room",
  "agent_token": "wla_new_..."
}

Requirements:

  • The Authorization header must carry your master wl_ token — not the agent token being rotated
  • The agent_id must belong to your account

After Rotation

Careful
The old agent token is immediately invalidated. The ESP32 will be disconnected from the relay as soon as rotation completes. All other agents and your master token are unaffected.

After rotating, re-provision the new wla_ token to the ESP32 using one of these methods:

  1. Android app — use the local provisioning flow on the same network
  2. ESP32 AP portal / JSON API — reset the agent back to provisioning mode, reconnect to WakeLink-Setup, and save the new token alongside the rest of the relay settings

The ESP32 reconnects to the relay automatically once the new token is saved.

Rotating Your Master API Token

To rotate the account-level wl_ token:

POST /api/v1/auth/token/rotate
Authorization: Bearer wl_your_current_api_token

After rotation:

  • The old wl_ token is immediately invalid
  • Active login and WebSocket sessions are invalidated — the relay clears all sessions for the user after rotation
  • Update the token in your CLI config (~/.wakelink/env) and any automation scripts
  • The Android app will prompt you to re-authenticate once it detects the token has changed
  • Per-agent wla_ tokens are not affected — agents stay online

Password Change & Revocation

Changing your password triggers a full account credential rotation:

Warning
All active sessions and the current wl_ master API token are immediately invalidated on password change. Per-agent wla_ tokens are not invalidated — they are not derived from your password and remain valid until explicitly rotated.

If you suspect your account is compromised, rotate all agent tokens individually after changing your password to achieve full revocation across all hardware.

Curl Example: Rotating an Agent Token

# Rotate the relay token for agent "esp32-living-room"
curl -X POST https://wakelink-project.org/api/v1/agents/esp32-living-room/rotate-token \
  -H "Authorization: Bearer wl_your_master_api_token" \
  -H "Content-Type: application/json"

# Response:
# {
# "agent_id": "esp32-living-room",
# "agent_token": "wla_new_..."
# }

# The new token is shown once — store it before re-provisioning the ESP32
NEW_AGENT_TOKEN="wla_new_..."

# Re-provision the ESP32 with the new token through the Android setup flow
# or by resetting the board to AP mode and re-entering the provisioning fields

Continue reading