Skip to main content

Overview

Rexec provides multiple authentication methods to suit different use cases:
  • JWT Authentication - Session-based authentication with configurable duration
  • OAuth 2.0 (PipeOps) - Federated authentication with PKCE flow
  • API Tokens - Long-lived tokens for programmatic access
  • Guest Access - Temporary 50-hour sessions without authentication
  • Multi-Factor Authentication (MFA) - TOTP-based 2FA for enhanced security

Authentication Methods

JWT Authentication

JWT tokens are issued after successful authentication and include user identity, tier, and subscription status. Token Claims:
{
  "user_id": "uuid",
  "email": "[email protected]",
  "username": "username",
  "tier": "free|pro|enterprise|guest",
  "subscription_active": true,
  "guest": false,
  "exp": 1234567890,
  "iat": 1234567890,
  "sid": "session-id"
}
Session Duration:
  • Guest users: 50 hours (fixed)
  • Authenticated users: Configurable (default 90 days)
  • Custom duration: Set via session_duration_minutes in user profile

Using JWT Tokens

Include the JWT token in the Authorization header:
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  https://api.rexec.io/api/profile

Guest Login

Create a temporary 50-hour session without OAuth authentication.
POST /api/auth/guest
Content-Type: application/json

{
  "username": "johndoe",
  "email": "[email protected]"
}
username
string
required
Username (2-30 characters, alphanumeric with underscores/hyphens)
email
string
Optional email for returning guest recognition
token
string
JWT token valid for 50 hours
expires_in
number
Token expiration in seconds (180000 = 50 hours)
returning_guest
boolean
True if email matched an existing guest session
Guest sessions are limited to 50 hours and have restricted resource limits. For production use, authenticate via OAuth.

OAuth 2.0 Flow (PipeOps)

Rexec uses OAuth 2.0 with PKCE for secure federated authentication through PipeOps.

Step 1: Get Authorization URL

GET /api/auth/oauth/url
auth_url
string
PipeOps authorization URL with PKCE challenge
state
string
CSRF protection state parameter (stored in secure cookie)

Step 2: User Authorization

Redirect the user to the auth_url. After authorization, PipeOps redirects back to:
GET /api/auth/callback?code=AUTH_CODE&state=STATE

Step 3: Token Exchange

The callback endpoint automatically:
  1. Validates the state parameter
  2. Exchanges the authorization code for an access token
  3. Fetches user info from PipeOps
  4. Creates or updates the user account
  5. Returns a JWT token
Response: The callback renders an HTML page that posts the token to the parent window:
{
  token: "eyJhbGciOiJIUzI1NiIs...",
  user: {
    id: "uuid",
    email: "[email protected]",
    username: "username",
    tier: "pro",
    subscription_active: true
  }
}
Security: OAuth uses PKCE (Proof Key for Code Exchange) to prevent authorization code interception attacks. The code verifier and state are stored in secure HTTP-only cookies.

Multi-Factor Authentication (MFA)

Rexec supports TOTP-based MFA (compatible with Google Authenticator, Authy, etc.) with backup codes.

Setup MFA

Initiate MFA setup and receive a secret for your authenticator app.
POST /api/mfa/setup
Authorization: Bearer YOUR_TOKEN
secret
string
Base32-encoded TOTP secret (store securely)
otp_url
string
OTP URL for QR code generation (otpauth:// URI)

Verify and Enable MFA

Verify the TOTP code to enable MFA and receive backup codes.
POST /api/mfa/verify
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
  "secret": "JBSWY3DPEHPK3PXP",
  "code": "123456"
}
secret
string
required
TOTP secret from setup endpoint
code
string
required
6-digit TOTP code from authenticator app
backup_codes
string[]
10 one-time backup codes (save securely!)
Save backup codes immediately! They are only shown once and cannot be retrieved later. Each backup code can only be used once.

MFA Login Flow

When MFA is enabled, the OAuth callback returns an intermediate MFA token:
  1. Complete OAuth flow normally
  2. If MFA is enabled, receive a 10-minute MFA token
  3. Prompt user for TOTP code
  4. Complete MFA login to receive full auth token
POST /api/mfa/complete-login
Authorization: Bearer MFA_TOKEN
Content-Type: application/json

{
  "code": "123456"
}
code
string
required
6-digit TOTP code or 8-character backup code

Disable MFA

DELETE /api/mfa/disable
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
  "code": "123456"
}

Regenerate Backup Codes

POST /api/mfa/backup-codes/regenerate
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
  "code": "123456"
}

User Profile

Retrieve the authenticated user’s profile and resource limits.
GET /api/profile
Authorization: Bearer YOUR_TOKEN

Update Profile

PUT /api/profile
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
  "username": "newusername",
  "first_name": "John",
  "last_name": "Doe",
  "allowed_ips": ["192.168.1.0/24", "10.0.0.1"],
  "session_duration_minutes": 43200
}
username
string
Username (2-50 characters)
allowed_ips
string[]
IP whitelist (CIDR notation supported: 192.168.1.0/24)
session_duration_minutes
number
Session duration in minutes (default 129600 = 90 days)
IP Whitelisting: When allowed_ips is set, only requests from those IPs/subnets are allowed. Empty array clears the whitelist.

Session Management

Rexec tracks active sessions for security and supports single-session mode.

Session Features

  • Session Tracking: All logins create a tracked session with IP and user agent
  • Session Revocation: Tokens with revoked sessions are rejected
  • Single Session Mode: Optionally limit user to one active session
  • Screen Lock: Enforce screen lock after inactivity (blocks old tokens)
  • Last Seen: Sessions update last seen timestamp on each request

Session ID in Token

JWT tokens include a sid claim with the session ID. The auth middleware:
  1. Validates the session exists and isn’t revoked
  2. Updates last seen timestamp
  3. Enforces screen lock if enabled

WebSocket Authentication

For WebSocket connections, pass the token via the Sec-WebSocket-Protocol header:
const ws = new WebSocket('wss://api.rexec.io/ws/containers/abc123/exec', [
  'rexec.v1',
  `rexec.token.${token}`
]);
Alternatively, pass as a query parameter (legacy):
wss://api.rexec.io/ws/containers/abc123/exec?token=YOUR_TOKEN

Error Responses

401 Unauthorized

{
  "error": "Invalid or expired token"
}
Reasons:
  • Token expired
  • Invalid signature
  • Session revoked
  • User not found
  • MFA required

403 Forbidden

{
  "error": "Access denied from this IP address"
}
Reason: IP not in allowed list

423 Locked

{
  "error": "session_locked"
}
Reason: Screen lock required (token issued before lock was enabled)

Security Best Practices

Token Storage: Store JWT tokens securely. For web apps, use httpOnly cookies. For mobile/desktop, use secure storage (Keychain, Keystore).
Token Rotation: Tokens are reissued on profile updates. Update your stored token when you receive a new one.
IP Whitelisting: For sensitive environments, restrict access by IP using the allowed_ips profile field.
API Tokens: API tokens bypass MFA and screen lock. Use them only for automated systems and rotate regularly.
MFA Recovery: Store backup codes securely offline. If you lose access to your authenticator app, backup codes are your only recovery method.

Build docs developers (and LLMs) love