How the Enterprise Edition of Rocket.Chat Handles Services: Proxy Architecture Explained

The Enterprise Edition of Rocket.Chat handles services through a proxy-based architecture that validates licenses at runtime, exposing premium features like LDAP, Livechat, and VoIP only when a valid license is present.

The Rocket.Chat Enterprise Edition extends the open-source core with premium services that require specific licensing to function. Understanding how the Enterprise Edition of Rocket.Chat handles services reveals a sophisticated proxy pattern that keeps the codebase modular while strictly enforcing license compliance. This design ensures that unlicensed deployments cannot access paid features, while allowing seamless integration for properly licensed users.

The Proxy Architecture at the Core of Enterprise Services

The foundation of Enterprise service handling lies in packages/core-services/src/index.ts, which exports a proxify helper that creates thin wrappers around each Enterprise implementation. This proxy layer intercepts all method calls to check license validity before delegating to the actual service code.

How the Proxify Helper Guards Access

The proxify function generates a dynamic wrapper that validates the license state on every property access. When the server attempts to invoke an Enterprise service, the proxy first queries the License singleton to verify the specific module is enabled:

// packages/core-services/src/index.ts (excerpt)
export const LDAPEnterprise = proxify<ILDAPEEService>('ldap-enterprise');
export const FederationEE = proxify<IFederationServiceEE>('federation-enterprise');

The wrapper implements runtime guards using JavaScript's Proxy API:

function proxify<T>(moduleName: string): T {
  return new Proxy({}, {
    get(_, prop) {
      if (!License.hasModule(moduleName)) {
        throw new Error('This is an enterprise feature [error-action-not-allowed]');
      }
      // Dynamically require the real implementation
      const service = require(`../${moduleName}`);
      return service[prop];
    },
  }) as T;
}

This design ensures that lazy loading occurs only after license validation succeeds, preventing the core application from loading Enterprise code into memory unnecessarily.

Enterprise Service Implementation Locations

Enterprise-specific implementations reside in the ee/ directory, isolated from the open-source core. Key service locations include:

Each module follows a consistent naming convention (e.g., livechat-enterprise, ldap-enterprise) that corresponds to the license module identifiers checked by License.hasModule().

Startup Registration and Service Initialization

During server initialization, the Enterprise startup script at apps/meteor/ee/server/startup/services.ts registers these proxied services with the main application container. This registration occurs regardless of license status, but the proxy ensures that actual service activation happens only for licensed modules.

The startup process follows this sequence:

  1. License detection – The encrypted license token loads and parses via ee/packages/license/src/applyLicense.ts
  2. Module registration – Each Enterprise module lists its granted capabilities
  3. Proxy exposure – Services become available through stable exports like LDAPEnterprise
  4. Runtime enforcement – Every call validates against the current license state

Runtime Guard Behavior and Error Handling

When unlicensed code attempts to access Enterprise functionality, the proxy throws a standardized error before executing any business logic. This prevents accidental usage of premium features in community editions.

The specific error message follows the pattern: "This is an enterprise feature [error-action-not-allowed]".

Calling Enterprise Services from Core Code

Core application code interacts with Enterprise services through the proxy exports without checking license status explicitly:

import { LDAPEnterprise } from '@rocket.chat/core-services';

async function testLdap() {
  try {
    // The proxy verifies the license before forwarding the call
    const result = await LDAPEnterprise.checkConnection();
    console.log('LDAP OK:', result);
  } catch (e) {
    console.error('Enterprise feature blocked:', e.message);
  }
}

Handling License Violations

When the license lacks the required module, the proxy rejects the operation immediately:

import { LDAPEnterprise } from '@rocket.chat/core-services';

LDAPEnterprise.checkConnection()
  .catch(err => {
    // Expected output when license excludes "ldap-enterprise"
    // → "This is an enterprise feature [error-action-not-allowed]"
    console.log(err.message);
  });

Summary

  • Proxy Pattern: Enterprise services use a proxify wrapper in packages/core-services/src/index.ts to intercept all access attempts.
  • License Validation: The License.hasModule() method checks granted modules before allowing service execution.
  • Lazy Loading: Real implementations load only after successful license validation, keeping community editions lightweight.
  • Error Handling: Unlicensed access attempts receive immediate "Enterprise feature not allowed" errors.
  • Code Isolation: All Enterprise logic lives under the ee/ directory, separate from the open-source core.

Frequently Asked Questions

What happens if I call an Enterprise service without a license?

The proxy layer throws an error with the message "This is an enterprise feature [error-action-not-allowed]" before any actual service code executes. This runtime guard ensures that community edition deployments cannot accidentally trigger premium functionality, as implemented in the proxify helper within packages/core-services/src/index.ts.

Where are Enterprise services physically located in the codebase?

Enterprise services reside in the ee/ directory, with specific implementations under paths like ee/app/livechat-enterprise/server/, ee/app/ldap-enterprise/server/, and ee/packages/omni-core-ee/. The proxy definitions that expose these services live in packages/core-services/src/index.ts.

How does the proxy pattern benefit testing?

The proxy architecture allows the open-source test suite to mock Enterprise services easily without importing the actual implementation code. Since the core code references only the proxy interface, tests can stub these exports without requiring the ee/ directory dependencies, simplifying the testing of code paths that optionally use Enterprise features.

Can Enterprise services be accessed directly without the proxy?

No. The codebase intentionally exports only the proxied versions (e.g., LDAPEnterprise, FederationEE) from packages/core-services/src/index.ts. Direct imports of the implementation files would circumvent license checks and violate the architectural design that enforces compliance through the proxify layer.

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 →