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

> Discover how Rocket.Chat Enterprise Edition manages services using a proxy architecture that enables premium features like LDAP, Livechat, and VoIP upon license validation.

- Repository: [Rocket.Chat/Rocket.Chat](https://github.com/RocketChat/Rocket.Chat)
- Tags: architecture
- Published: 2026-06-18

---

**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`](https://github.com/RocketChat/Rocket.Chat/blob/main/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:

```ts
// 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:

```ts
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:

- **Livechat** – `ee/app/livechat-enterprise/server/*` (e.g., [`ee/app/livechat-enterprise/server/lib/requestPdfTranscript.ts`](https://github.com/RocketChat/Rocket.Chat/blob/main/ee/app/livechat-enterprise/server/lib/requestPdfTranscript.ts))
- **LDAP** – `ee/app/ldap-enterprise/server/*`
- **VoIP** – `ee/app/voip-enterprise/server/*`
- **Omnichannel** – `ee/packages/omni-core-ee/*` (e.g., [`ee/packages/omni-core-ee/src/isDepartmentCreationAvailable.ts`](https://github.com/RocketChat/Rocket.Chat/blob/main/ee/packages/omni-core-ee/src/isDepartmentCreationAvailable.ts))

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`](https://github.com/RocketChat/Rocket.Chat/blob/main/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`](https://github.com/RocketChat/Rocket.Chat/blob/main/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:

```ts
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:

```ts
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`](https://github.com/RocketChat/Rocket.Chat/blob/main/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`](https://github.com/RocketChat/Rocket.Chat/blob/main/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`](https://github.com/RocketChat/Rocket.Chat/blob/main/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`](https://github.com/RocketChat/Rocket.Chat/blob/main/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.