Skip to main content
TrayLinx uses JWT-based authentication with automatic token refresh, combined with layered defenses including rate limiting, input sanitization, and CORS/CSRF protections.

JWT authentication

When you sign in, TrayLinx issues two tokens:
  • Access token — a short-lived JWT included as a Bearer token on all authenticated API requests.
  • Refresh token — a longer-lived token used to obtain a new access token when the current one expires.
Both tokens are stored in localStorage under the keys accessToken and refreshToken. TrayLinx validates the token format before every request — if the token contains non-alphanumeric characters outside the JWT character set (a–z, A–Z, 0–9, -, _, .), it is treated as corrupted and you are logged out immediately.

Token refresh

TrayLinx uses an Axios response interceptor to detect 401 Unauthorized responses. When one occurs:
  1. The interceptor checks for an available refresh token.
  2. If found, it calls the token refresh endpoint via AuthenticationClient.
  3. On success, the new accessToken and refreshToken are stored and the original request is retried automatically.
  4. If the refresh fails, TrayLinx calls unifiedLogout to clear all session state and redirect you to the login page.
To prevent race conditions from multiple simultaneous token refresh calls, the refresh state is centralized — only one refresh request is in flight at a time.

Session management and timeouts

On login, TrayLinx:
  1. Clears any cached data from the previous session.
  2. Stores your access token, refresh token, and user profile.
  3. Calls the User Settings API to restore your preferences, organizations, and project context in a single request.
  4. Sets a showWelcomeMessage flag in localStorage for new or returning users.
On logout, TrayLinx:
  1. Calls GET /oauth/token/revoke with your access token to invalidate it server-side.
  2. Runs secureSessionCleanup to remove all cached data from localStorage.
  3. Preserves only your currentOrganizationId, currentProjectId, and betaGatePassed values so you return to the same context on next login.
If the server-side revoke call fails with a 401 (token already expired), TrayLinx continues with local cleanup. Your session data is always cleared regardless of the API response.

Multi-factor authentication

TrayLinx supports multi-factor authentication (MFA) during account registration and activation. After submitting a registration form, TrayLinx sends a 6-digit verification code to your email address or phone number depending on your chosen registration method.
  • Email activation — enter the code sent to your inbox to activate your account.
  • Phone activation — enter the SMS code to activate your account.
If a code expires before you enter it, use Resend code to request a new one. Codes expire with HTTP 410 Gone responses and the service returns a clear message prompting you to request a new code.

Password security

TrayLinx applies the following password protections:
  • All form inputs, including usernames and passwords, are passed through sanitizeFormData before any API call to strip potentially dangerous characters.
  • Password change requests require an active authenticated session; unauthenticated resets use a time-limited reset token delivered by email.
  • Authenticated users can change their password without knowing the current one, as long as their session is valid.

OAuth security

TrayLinx integrates OAuth 2.0 both as a consumer (Google and GitHub login) and as a provider (Sentinel Pass). Client secrets are never stored as permanent values — the CredentialService replaces them with short-lived JWT tokens fetched from a credential endpoint:
  1. On request, CredentialService calls POST /credentials/token with the client_id.
  2. The returned jwt_client_secret is cached in memory for up to 50 seconds (JWTs expire after 60 seconds).
  3. Subsequent requests within the window use the cached value; expired credentials are automatically refreshed.
The client_secret field is never included in API responses. Credential values are displayed once at creation and cannot be retrieved again — store them immediately in a secure location.

Rate limiting

TrayLinx enforces rate limits on authentication endpoints using the rateLimiters utility. Limits apply per username or email:
OperationBehavior when limit exceeded
LoginBlocked with a message showing minutes remaining before retry
RegistrationBlocked with a message showing minutes remaining before retry
Password resetBlocked with a message showing minutes remaining before retry
Email / phone validationBlocked with a message showing seconds remaining before retry
All rate limit violations are logged as security events via sessionSecurityMonitor.

HTTPS, CORS, and XSS protection

All API communication uses HTTPS. TrayLinx sets the following on every outbound request:
Authorization: Bearer <accessToken>
Api-Key: <apiKey>
Content-Type: application/json
Additional security headers are applied via getSecurityHeaders() on sensitive operations such as token revocation. Client-side XSS protection is enforced by passing all user-supplied form data through sanitizeFormData before it reaches the API or the DOM.

CSRF protection

TrayLinx uses token-based authentication (JWT) rather than session cookies for API authentication, which eliminates the primary CSRF attack vector. All state-changing requests require a valid Authorization: Bearer header that an attacker-controlled page cannot read due to browser same-origin policy.

Security event logging

The sessionSecurityMonitor records the following events for auditing and incident response:
EventTrigger
login_attemptEvery login form submission
login_successSuccessful authentication
login_failedFailed login (rate limit, wrong credentials, etc.)
login_rate_limitedLogin blocked by rate limiter
registration_attemptEvery registration form submission
registration_successAccount created successfully
registration_activation_requiredAccount created, awaiting verification
logout_attempt / logout_successUser-initiated or forced logout
tokens_updatedAccess and refresh tokens refreshed
password_reset_requestPassword reset email requested
validation_requestEmail or phone availability checked

Login & Authentication

Sign in with email, phone, Google, or GitHub OAuth.

Sentinel Pass

Issue and manage OAuth credentials for agents and integrations.

API Keys

Create and manage project and LLM provider API keys.

Projects & Assets

Manage projects, members, and permissions.

Build docs developers (and LLMs) love