Authentication

How authentication works in Valvet

Valvet uses a dual-token authentication system for the web UI and a separate bearer token system for node agents.

User Authentication

Login Flow

  1. User submits username and password to POST /api/v1/auth/login
  2. Password is verified against the argon2id hash stored in the database
  3. On success, the API returns a JWT access token and sets an HTTP-only refresh cookie

Access Tokens

  • Type: JWT (JSON Web Token)
  • Expiry: 15 minutes
  • Transport: Authorization: Bearer <token> header
  • Contents: User ID, username, role, issued/expiry timestamps

Refresh Tokens

  • Expiry: 30 days
  • Transport: HTTP-only cookie (not accessible to JavaScript)
  • Rotation: Each refresh issues a new token pair and invalidates the old refresh token

Session Management

Users can view and revoke active sessions from Settings → Sessions. Revoking a session invalidates its refresh token immediately.

Node Authentication

Enrollment Tokens

Enrollment tokens are created by admins in the web UI or via the API. They are one-time-use by default and can have an expiry date.

When a node enrolls:

  1. Node sends the enrollment token to POST /api/v1/auth/enroll
  2. Hub verifies the token, creates a node record, generates a permanent bearer token
  3. The permanent token is returned to the node and stored in its local config
  4. The enrollment token is consumed (uses decremented)

Node Bearer Tokens

  • Type: Random token, SHA-256 hashed in the database
  • Expiry: None (permanent until revoked)
  • Transport: Authorization: Bearer <token> header on API calls and WebSocket connections

WebSocket Token Rotation

For WebSocket connections, nodes use short-lived tokens:

  1. Node requests a WebSocket token via POST /api/v1/nodes/:id/ws-token
  2. Hub returns a token valid for 60 seconds
  3. Node connects to /api/v1/ws?token=<ws-token>
  4. Tokens are rotated periodically during the connection lifetime

Password Security

All passwords are hashed with argon2id using the default recommended parameters. Plaintext passwords are never stored or logged.