Understanding the Dual Authentication System in FreeLLMAPI: Dashboard vs. Unified API Key

FreeLLMAPI separates human-operator access from automated client requests by implementing two distinct authentication mechanisms: session-based email-password login for the web dashboard and encrypted unified API keys for the LLM proxy endpoints.

The tashfeenahmed/freellmapi repository enforces a strict security boundary between administrative functions and public API access. Its dual authentication system ensures that dashboard users authenticate via ephemeral session tokens while client applications use unified API keys to access the /v1/* proxy endpoints. This architecture prevents credential overlap and allows independent security controls for human operators versus automated clients.

Dashboard Authentication: Session-Based Access

Login Flow and Token Generation

Dashboard authentication follows a traditional email-password flow designed for human operators. When a user submits credentials to POST /api/auth/login, the system validates them via verifyCredentials in server/src/services/auth.ts. Upon successful validation, createSession (lines 55-60) generates a cryptographically random 64-hex character token.

The server stores only the SHA-256 hash of this token in the sessions table, while returning the plaintext token to the client. This hash-based approach ensures that even if the database is compromised, active session tokens cannot be replayed. The users table maintains salted password hashes separately, completing the credential segregation.

Session Validation and Middleware Protection

Every subsequent dashboard request must include the session token in either the Authorization: Bearer <token> or x-dashboard-token header. The requireAuth middleware intercepts all /api/* routes and invokes validateSession (lines 62-77 in server/src/services/auth.ts) to verify access.

The validation process hashes the incoming token and queries the sessions table for a matching entry. Sessions expire after 30 days by default, after which the user must re-authenticate. This short-lived nature reduces the attack window for stolen tokens while maintaining convenience for dashboard users.

Unified API Key Authentication: Client Application Access

Encrypted Storage Architecture

Client applications authenticate using a unified API key system that operates independently of dashboard sessions. Unlike the session tokens, these keys persist in the api_keys table as encrypted values. Each row stores encrypted_key, iv, and auth_tag fields generated via AES-GCM encryption implemented in server/src/lib/crypto.ts.

The raw plaintext key never touches the database. When an administrator creates a new API key through the dashboard, the system immediately encrypts it and discards the plaintext version from memory. This just-in-time decryption model ensures that database breaches do not expose usable API credentials.

Proxy Request Processing

The /v1/* endpoints handle LLM proxy requests without requiring dashboard session validation. Instead, server/src/services/router.ts extracts the bearer token or x-api-key header from incoming requests. The selectKeyForModel function (lines 84-86) retrieves the encrypted row for the requested model and calls decrypt to reconstruct the plaintext key on-the-fly.

After decryption, the system passes the raw key to the appropriate provider driver (OpenAI, Anthropic, etc.) while simultaneously executing quota checks via canMakeRequest and canUseTokens. This architecture allows the proxy to authenticate requests and enforce rate limits without maintaining persistent clear-text credentials in memory or storage.

Architectural Comparison and Security Models

Feature Dashboard Sessions Unified API Key
Purpose Protect admin API (/api/*) and web interface Authenticate public LLM proxy (/v1/*)
Credential type Email + Password → session token Plain-text API key (encrypted at rest)
Storage SHA-256 hash in sessions table AES-GCM encrypted in api_keys table (encrypted_key, iv, auth_tag)
Verification validateSession in auth.ts (lines 62-77) selectKeyForModel in router.ts (lines 84-86)
Access control requireAuth middleware None (direct key validation)
Lifespan 30 days Indefinite (until revoked)

Dashboard Sessions prioritize ephemeral access and human convenience through short-lived tokens that mitigate replay attacks. Unified API Keys prioritize automated client access with long-term credentials protected by strong encryption rather than temporal expiration.

Implementation Examples

Authenticating with the Dashboard

Request a session token via the login endpoint:

curl -X POST http://localhost:3000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"SuperSecret123"}'

Response:

{
  "token": "a1b2c3d4e5f6... (64-hex chars)",
  "email": "[email protected]"
}

Access protected dashboard routes using the returned token:

curl http://localhost:3000/api/models \
  -H "Authorization: Bearer a1b2c3d4e5f6..."

Using the Unified API Key

Send requests to the LLM proxy using an API key:

curl http://localhost:3000/v1/chat/completions \
  -H "Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
        "model": "gpt-4",
        "messages": [{"role":"user","content":"Hello"}]
      }'

The proxy extracts the key, decrypts it via selectKeyForModel, and forwards the request to the underlying provider.

Initial Administrator Setup

Create the first dashboard user when userCount() returns zero:

curl -X POST http://localhost:3000/api/auth/setup \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"VeryStrongPass"}'

This endpoint triggers the setup logic in server/src/routes/auth.ts lines 29-42, creating the initial admin account before regular authentication becomes available.

Summary

  • FreeLLMAPI maintains separate auth systems: Dashboard sessions for human operators via server/src/services/auth.ts and unified API keys for clients via server/src/services/router.ts.
  • Dashboard tokens are ephemeral: 64-hex session tokens hashed with SHA-256, validated by validateSession, and expiring after 30 days.
  • API keys use AES-GCM encryption: Stored as encrypted_key, iv, and auth_tag in the api_keys table, decrypted on-the-fly by selectKeyForModel only when proxying requests.
  • Route isolation: /api/* requires requireAuth middleware with session validation, while /v1/* relies solely on encrypted API key decryption without session checks.
  • Security defense in depth: Database breaches expose only hashed session tokens or encrypted API keys, never plaintext credentials.

Frequently Asked Questions

How does FreeLLMAPI store API keys securely?

API keys are encrypted using AES-GCM before storage. The api_keys table contains only the encrypted_key, initialization vector (iv), and auth_tag. The decrypt function in server/src/lib/crypto.ts reconstructs the plaintext key only when processing proxy requests, ensuring the raw key never persists in the database.

Why does the dashboard use session tokens instead of API keys?

Dashboard sessions prioritize human security patterns. The createSession function generates short-lived tokens (30 days) stored as SHA-256 hashes, forcing periodic re-authentication that limits exposure if a token is compromised. This differs from API keys, which must remain stable for automated client integrations and therefore rely on encryption rather than expiration for protection.

Can the unified API key be used to access dashboard endpoints?

No. The /api/* routes are protected by requireAuth middleware that specifically validates session tokens against the sessions table. Unified API keys authenticate only the /v1/* proxy endpoints. This strict separation prevents client applications from accessing administrative functions even if they possess a valid API key.

How long do dashboard sessions last before expiring?

Sessions expire 30 days after creation by default. The validateSession function in server/src/services/auth.ts checks the token hash and expiration timestamp on every request. Once expired, the user must re-authenticate via POST /api/auth/login to receive a fresh token.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →