How DeskcommCRM Handles Plaintext WAHA Bearer Tokens: Security, Storage, and Implementation
DeskcommCRM handles WAHA bearer tokens as plaintext environment variables, keeping them only in memory during runtime while injecting them into the X-Api-Key header for all API requests, never persisting them to disk or logs.
The open-source DeskcommCRM repository integrates with WAHA (a self-hosted WhatsApp engine) using a straightforward plaintext authentication approach. Understanding how plaintext bearer tokens are handled and stored for WAHA integration is critical for operators deploying this CRM system securely, as the implementation prioritizes operational simplicity while enforcing strict runtime security boundaries.
Environment Variable Configuration
DeskcommCRM loads the WAHA bearer token exclusively through environment variables. In lib/env.ts (approximately line 141), the system declares WAHA_API_KEY as a required environment variable using the required() validator:
// lib/env.ts (line ~141)
WAHA_API_KEY: required("WAHA_API_KEY"),
The repository includes a placeholder value in .env.example to remind operators to configure the token before starting the container:
# .env.example
WAHA_API_KEY=dev_plaintext_change_me
If the variable is missing at startup, the getWahaClient() factory function returns null, triggering UI components to render a "Docker is not up" banner rather than crashing the application.
In-Memory Token Storage
The token resides only in memory inside WahaClient instances and is never persisted to a database or written to disk. The WahaClient class in lib/waha/client.ts receives the plaintext key through its constructor:
// lib/waha/client.ts (constructor)
constructor(
private readonly baseUrl: string,
private readonly apiKey: string,
opts: WahaClientOpts = {},
) { … }
This design ensures that sensitive credentials exist solely as runtime variables within the Node.js process, leaving no residual token data on the filesystem if the container restarts.
HTTP Header Transmission
All WAHA REST API calls transmit the token via the X-Api-Key header. The WahaClient class injects the plaintext key into every request headers object:
// lib/waha/client.ts (lines ~204, 212, 246…)
headers: { "X-Api-Key": this.apiKey }
When creating messages or managing sessions, the client automatically attaches this header. For example, sending a text message through WAHA works as follows:
import { WahaClient } from "@/lib/waha/client";
const waha = new WahaClient(
process.env.WAHA_API_BASE_URL!, // base URL of the WAHA container
process.env.WAHA_API_KEY! // plaintext API key from .env
);
await waha.sendText({
to: phoneNumber,
text: "Olá! Seu pedido está pronto.",
});
Validation and Error Handling
The integration implements defensive checks to prevent operations against unconfigured WAHA endpoints. Channel adapters such as lib/channels/transporte.ts and worker processes verify client availability before executing WhatsApp operations:
const client = getWahaClient(); // returns null if WAHA_API_KEY or BASE_URL missing
if (!client) {
// UI: show banner "Docker is not up – configure WAHA_API_KEY"
}
This pattern ensures that missing configuration results in graceful degradation rather than runtime exceptions or authentication failures against the WAHA engine.
Security Measures and Logging
DeskcommCRM enforces a strict security policy preventing token exposure in logs. The logger configuration in lib/logger.ts explicitly includes the rule: "Never log secrets, raw tokens…". Consequently, the plaintext WAHA_API_KEY is never written to log files, stdout, or error traces even when debugging is enabled.
Additionally, the codebase performs presence checks for both WAHA_API_KEY and WAHA_API_BASE_URL before client instantiation, emitting clear error messages when either value is absent.
Summary
- Environment-only configuration: The
WAHA_API_KEYvariable is declared as required inlib/env.tsand loaded from the host environment. - Memory-only storage: Tokens exist only within
WahaClientinstances and are never persisted to databases or filesystems. - Header-based transmission: All requests include the plaintext token in the
X-Api-Keyheader as implemented inlib/waha/client.ts. - Graceful degradation: Missing configuration causes
getWahaClient()to returnnull, displaying user-friendly UI banners instead of crashing. - Log sanitization: The logger configuration in
lib/logger.tsexplicitly prohibits logging raw tokens, preventing accidental credential leaks.
Frequently Asked Questions
Where is the WAHA_API_KEY stored in DeskcommCRM?
The WAHA_API_KEY is stored only as an environment variable and exists solely in memory during runtime. According to the lib/env.ts validation schema and the WahaClient constructor in lib/waha/client.ts, the token is never written to disk, databases, or configuration files beyond the initial .env injection.
What happens if WAHA_API_KEY is missing at startup?
If WAHA_API_KEY is undefined, the getWahaClient() function returns null, causing UI components to render a "Docker is not up" banner. This validation occurs across channel adapters like lib/channels/transporte.ts and background workers to prevent authentication failures against the WAHA engine.
How does DeskcommCRM prevent WAHA tokens from leaking in logs?
The project’s logger implementation in lib/logger.ts enforces a strict policy: "Never log secrets, raw tokens…". This rule ensures that even during verbose debugging or error stack traces, the plaintext bearer token remains excluded from log outputs.
Is the WAHA token encrypted at rest in DeskcommCRM?
No, the token is not encrypted at rest because DeskcommCRM does not persist the token at all. The plaintext value lives only in memory within active WahaClient instances. The system relies on container-level security and environment variable management rather than application-layer encryption for this integration.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →