> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/wazuh/wazuh-dashboard-plugins/llms.txt
> Use this file to discover all available pages before exploring further.

# Plugin System

> Understanding the OpenSearch Dashboards plugin lifecycle and Wazuh plugin architecture

## Overview

Wazuh Dashboard Plugins are built on the OpenSearch Dashboards plugin platform, which provides a standardized lifecycle and dependency management system. Each plugin is a self-contained module with defined setup, start, and stop phases.

## Plugin Lifecycle

Every plugin implements a consistent lifecycle with three main phases:

**1. Setup Phase**

Occurs during OpenSearch Dashboards initialization. Plugins register routes, UI applications, and configure integrations.

**2. Start Phase**

Runs after all plugins have completed setup. Services become available, background jobs start, and the plugin is fully operational.

**3. Stop Phase**

Called during shutdown to clean up resources, close connections, and terminate background processes.

## Plugin Manifest

Each plugin declares its metadata, dependencies, and capabilities in `opensearch_dashboards.json`:

```json theme={null}
{
  "id": "pluginId",                    // Unique identifier
  "version": "5.0.0-00",              // Plugin version
  "opensearchDashboardsVersion": "...", // Compatible platform version
  "requiredPlugins": [],              // Must be loaded before this plugin
  "optionalPlugins": [],              // Enhanced functionality if available
  "server": true,                     // Has server-side code
  "ui": true,                         // Has client-side code
  "configPath": ["wazuh"]            // Configuration namespace (optional)
}
```

## The Three Core Plugins

### 1. wazuh-core: Foundation Services

The core plugin provides essential services used by other plugins.

#### Public Plugin (Browser)

**File:** `plugins/wazuh-core/public/plugin.ts`

```typescript Setup Phase theme={null}
public async setup(core: CoreSetup): Promise<WazuhCorePluginSetup> {
  // Initialize configuration store
  this._internal.configurationStore = new ConfigurationStore(logger);

  // Register configuration providers
  this._internal.configurationStore.registerProvider(
    EConfigurationProviders.INITIALIZER_CONTEXT,
    new InitializerConfigProvider(this.initializerContext)
  );

  this._internal.configurationStore.registerProvider(
    EConfigurationProviders.PLUGIN_UI_SETTINGS,
    new UISettingsConfigProvider(core.uiSettings)
  );

  // Create configuration facade
  this.services.configuration = new Configuration(
    logger,
    this._internal.configurationStore
  );

  // Create dashboard security service
  this.services.dashboardSecurity = new DashboardSecurity(logger, core.http);
  await this.services.dashboardSecurity.setup();

  return {
    ...this.services,
    utils,
    API_USER_STATUS_RUN_AS,
    SettingsValidator,
  };
}
```

```typescript Start Phase theme={null}
public async start(core: CoreStart): Promise<WazuhCorePluginStart> {
  // Set global service references
  setChrome(core.chrome);
  setCore(core);
  setUiSettings(core.uiSettings);

  // Start configuration service
  await this.services.configuration.start({ http: core.http });

  return {
    ...this.services,
    utils,
    API_USER_STATUS_RUN_AS,
    hooks,
    SettingsValidator,
  };
}
```

**Services Provided:**

> **Configuration**
>
> Multi-provider configuration management with UI settings and initializer context

> **Dashboard Security**
>
> Security platform detection and integration utilities

> **Utilities**
>
> Shared helper functions and constants

> **Hooks**
>
> React hooks for accessing core services

#### Server Plugin (Node.js)

**File:** `plugins/wazuh-core/server/plugin.ts`

```typescript Setup Phase theme={null}
public async setup(core: CoreSetup, plugins: PluginSetup) {
  // Register UI settings for advanced configuration
  const uiSettingsDefs = getUiSettingsDefinitions(PLUGIN_SETTINGS);
  core.uiSettings.register(uiSettingsDefs);

  // Initialize services
  this.services.dashboardSecurity = createDashboardSecurity(plugins);
  this.services.configuration = new Configuration(
    this.logger.get('configuration'),
    this._internal.configurationStore
  );
  this.services.manageHosts = new ManageHosts(
    this.logger.get('manage-hosts'),
    this.services.configuration
  );
  this.services.serverAPIClient = new ServerAPIClient(
    this.logger.get('server-api-client'),
    this.services.manageHosts,
    this.services.dashboardSecurity
  );

  // Register context for route handlers
  core.http.registerRouteHandlerContext('wazuh_core', (context, request) => ({
    ...this.services,
    api: {
      client: {
        asInternalUser: this.services.serverAPIClient.asInternalUser,
        asCurrentUser: this.services.serverAPIClient.asScoped(context, request),
      },
    },
  }));

  return { ...this.services, API_USER_STATUS_RUN_AS, api: {...} };
}
```

```typescript Start Phase theme={null}
public async start(core: CoreStart): Promise<WazuhCorePluginStart> {
  setCore(core);

  // Start services
  await this.services.configuration.start();
  await this.services.manageHosts.start();

  return {
    ...this.services,
    API_USER_STATUS_RUN_AS,
    api: {...}
  };
}
```

**Key Components:**

| Component | Purpose |
| - | - |
| `ManageHosts` | Multi-cluster API host management |
| `ServerAPIClient` | HTTP client for Wazuh Server API with user context |
| `Configuration` | Server-side configuration aggregation |
| `DashboardSecurity` | Security plugin integration |

### 2. wazuh-check-updates: Update Notifications

A lightweight plugin for managing update notifications.

**File:** `plugins/wazuh-check-updates/public/plugin.ts`

```typescript theme={null}
export class WazuhCheckUpdatesPlugin
  implements Plugin<WazuhCheckUpdatesPluginSetup, WazuhCheckUpdatesPluginStart> {
  
  public setup(core: CoreSetup): WazuhCheckUpdatesPluginSetup {
    // No setup operations needed
    return {};
  }

  public start(
    core: CoreStart,
    plugins: AppPluginStartDependencies
  ): WazuhCheckUpdatesPluginStart {
    setCore(core);
    setWazuhCore(plugins.wazuhCore);

    // Export components and services
    return {
      UpdatesNotification,
      getAvailableUpdates,
      DismissNotificationCheck,
    };
  }

  public stop() {}
}
```

**Exports:**

**Components**

* `UpdatesNotification`: UI component for displaying update banners
* `DismissNotificationCheck`: Component to check dismissal state

**Services**

* `getAvailableUpdates()`: Fetches available updates from API

### 3. wazuh (Main): Complete Security Platform

The main plugin provides all user-facing features and security modules.

#### Public Plugin

**File:** `plugins/main/public/plugin.ts`

```typescript Application Registration theme={null}
public async setup(core: CoreSetup, plugins: WazuhSetupPlugins) {
  // Register query languages for search bar
  const languageService = plugins.data.query.queryString.languageService;
  SUPPORTED_LANGUAGES_ARRAY.forEach(language => {
    const languageInstance = languageService.getLanguage(language);
    languageService.registerLanguage({
      ...languageInstance,
      supportedAppNames: [...languageInstance.supportedAppNames, ...appIds],
    });
  });

  // Register all applications
  for (const app of Applications) {
    const { category, id, title, redirectTo, order } = app;

    core.application.register({
      id,
      title,
      order,
      mount: async (params: AppMountParameters) => {
        setWzCurrentAppID(id);
        setWzMainParams(redirectTo());
        initializeInterceptor(core);

        if (this.hideTelemetryBanner) {
          await this.hideTelemetryBanner();
        }

        setScopedHistory(params.history);
        setHeaderActionMenuMounter(params.setHeaderActionMenu);
        NavigationService.getInstance(createHashHistory());

        // Lazy load application bundle
        const { renderApp } = await import('./application');

        setErrorOrchestrator(ErrorOrchestratorService);
        setHttp(core.http);
        setCookies(new Cookies());

        params.element.classList.add('dscAppWrapper', 'wz-app');
        const unmount = await renderApp(params);

        return () => {
          unmount();
          unregisterInterceptor();
        };
      },
      category: Categories.find(({ id: categoryID }) => categoryID === category),
    });
  }

  // Register navigation links for new home page
  registerWazuhNavLinks(
    core.chrome.navGroup.addNavLinksToGroup.bind(core.chrome.navGroup),
    core.chrome.navGroup.getNavGroupEnabled()
  );

  return {};
}
```

```typescript Service Initialization theme={null}
public start(core: CoreStart, plugins: AppPluginStartDependencies): WazuhStart {
  // Hide security alerts
  if (plugins.securityOss) {
    plugins.securityOss.insecureCluster.hideAlert(true);
  }

  // Set telemetry banner hide method
  if (plugins?.telemetry?.telemetryNotifications?.setOptedInNoticeSeen) {
    this.hideTelemetryBanner = () =>
      plugins.telemetry.telemetryNotifications.setOptedInNoticeSeen();
  }

  // Set global service references
  setCore(core);
  setPlugins(plugins);
  setHttp(core.http);
  setToasts(core.notifications.toasts);
  setDataPlugin(plugins.data);
  setUiSettings(core.uiSettings);
  setChrome(core.chrome);
  setNavigationPlugin(plugins.navigation);
  setVisualizationsPlugin(plugins.visualizations);
  setSavedObjects(core.savedObjects);
  setOverlays(core.overlays);
  setErrorOrchestrator(ErrorOrchestratorService);
  setWazuhCheckUpdatesPlugin(plugins.wazuhCheckUpdates);
  setWazuhCorePlugin(plugins.wazuhCore);

  return {};
}
```

**Application Structure:**

Each application registered by the main plugin represents a security module:

```typescript theme={null}
// Example application definition from applications.ts
export const configurationAssessment = {
  category: 'wz-category-endpoint-security',
  id: 'configuration-assessment',
  title: 'Configuration Assessment',
  order: 200,
  euiIconType: 'managementApp',
  showInOverviewApp: true,
  showInAgentMenu: true,
  redirectTo: () => `/overview/?tab=sca&tabView=dashboard${...}`,
};
```

#### Server Plugin

**File:** `plugins/main/server/plugin.ts`

```typescript Route Registration theme={null}
public async setup(core: CoreSetup, plugins: PluginSetup) {
  // Register custom route handler context
  core.http.registerRouteHandlerContext('wazuh', (context, request) => ({
    logger: this.logger.get(
      `${request.route.method.toUpperCase()} ${request.route.path}`
    ),
    server: { info: serverInfo },
    plugins,
    security: plugins.wazuhCore.dashboardSecurity,
    api: context.wazuh_core.api,
  }));

  // Add security headers
  core.http.registerOnPreResponse((request, response, toolkit) => {
    const additionalHeaders = {
      'x-frame-options': 'sameorigin',
    };
    return toolkit.next({ headers: additionalHeaders });
  });

  // Create router and register routes
  const router = core.http.createRouter();
  setupRoutes(router, plugins.wazuhCore);

  // Register health checks (shown in next section)
  // ...

  return {};
}
```

```typescript Background Jobs theme={null}
public async start(core: CoreStart, plugins: any) {
  const globalConfiguration: SharedGlobalConfig =
    await this.initializerContext.config.legacy.globalConfig$
      .pipe(first())
      .toPromise();

  const contextServer = {
    config: globalConfiguration,
  };

  // Start initialization job
  jobInitializeRun({
    core,
    wazuh: {
      logger: this.logger.get('initialize'),
      api: plugins.wazuhCore.api,
    },
    wazuh_core: plugins.wazuhCore,
    server: contextServer,
  });

  // Start queue processing job
  jobQueueRun({
    core,
    wazuh: {
      logger: this.logger.get('queue'),
      api: plugins.wazuhCore.api,
    },
    wazuh_core: plugins.wazuhCore,
    server: contextServer,
  });

  return {};
}
```

## Health Check System

The main plugin's server implements extensive health checks during setup:

### Index Pattern Health Checks

Example from `plugins/main/server/plugin.ts` (lines 261-296):

```typescript theme={null}
core.healthCheck.register(
  initializationTaskCreatorIndexPattern({
    services: plugins.wazuhCore,
    taskName: HEALTH_CHECK_TASK_INDEX_PATTERN_AGENTS_MONITORING,
    indexPatternID: WAZUH_MONITORING_PATTERN, // 'wazuh-monitoring*'
    options: {
      savedObjectOverwrite: defineTimeFieldNameIfExist('timestamp'),
      hasTimeFieldName: true,
      fieldsNoIndices: IndexPatternMonitoringKnownFields,
    },
  })
);
```

The system registers health checks for:

> **Events Index Patterns (10 patterns)**
>
> * System Activity Events
> * Security Events
> * Access Management Events
> * Applications Events
> * Other Events
> * Network Activity Events
> * Cloud Services Events (Generic, AWS, Azure, GCP)

> **States Index Patterns (20 patterns)**
>
> * Vulnerabilities
> * FIM (Files, Registry Keys, Registry Values)
> * SCA (Security Configuration Assessment)
> * Inventory (System, Hardware, Networks, Packages, Ports, Processes, Protocols, Users, Groups, Services, Interfaces, Hotfixes, Browser Extensions)

> **Operational Index Patterns (2 patterns)**
>
> * Monitoring (Agent status and metrics)
> * Statistics (Server performance data)

> **API Health Checks**
>
> * Connection compatibility
> * Run-as configuration validation

> **Saved Objects**
>
> * Required dashboards and visualizations

## Plugin Dependencies

### Dependency Graph

```mermaid theme={null}
graph LR
    OSD[OpenSearch Dashboards Core]
    Nav[navigation]
    Data[data]
    Utils[opensearchDashboardsUtils]
    React[opensearchDashboardsReact]
    Dash[dashboard]
    Disc[discover]
    Viz[visualizations]
    Sec[securityDashboards]
    
    WC[wazuh-core]
    WCU[wazuh-check-updates]
    WM[wazuh main]
    
    OSD --> Nav
    OSD --> Data
    OSD --> Utils
    OSD --> React
    OSD --> Dash
    OSD --> Disc
    OSD --> Viz
    OSD --> Sec
    
    Nav --> WC
    Utils --> WC
    Sec -.optional.-> WC
    
    Nav --> WCU
    Utils --> WCU
    React --> WCU
    WC --> WCU
    Sec -.optional.-> WCU
    
    Nav --> WM
    Data --> WM
    Dash --> WM
    Disc --> WM
    Viz --> WM
    Utils --> WM
    React --> WM
    WC --> WM
    WCU --> WM
    Sec -.optional.-> WM
```

### Required vs Optional Dependencies

**Required**

**Must be present for plugin to load:**

All plugins require:

* `navigation` - Menu and navigation services
* `opensearchDashboardsUtils` - Common utilities

Main plugin additionally requires:

* `data` - Search and aggregations
* `dashboard` - Dashboard embedding
* `discover` - Event exploration
* `visualizations` - Chart rendering
* `charts` - Chart configuration
* `savedObjects` - Saved object management
* `wazuhCore` - Foundation services
* `wazuhCheckUpdates` - Update notifications

**Optional**

**Enhanced features if present:**

* `securityDashboards` - RBAC and authentication
* `searchguard` - Alternative security plugin
* `telemetry` - Usage analytics
* `notificationsDashboards` - Alert notifications
* `alertingDashboards` - Alert management
* `reportsDashboards` - Report generation

## Service Architecture

### Public Services (Browser)

Services are made globally available through module-level setters:

```typescript theme={null}
// Example from plugins/main/public/kibana-services.ts
let http: CoreStart['http'];
let data: DataPublicPluginStart;
let navigation: NavigationPublicPluginStart;

export const setHttp = (h: CoreStart['http']) => { http = h; };
export const getHttp = () => http;

export const setDataPlugin = (d: DataPublicPluginStart) => { data = d; };
export const getDataPlugin = () => data;

export const setNavigationPlugin = (n: NavigationPublicPluginStart) => { navigation = n; };
export const getNavigationPlugin = () => navigation;
```

**Benefits:**

* Avoid prop drilling through deep component trees
* Access platform services from any component
* Testable through service mocking

### Server Services (Node.js)

Services are provided through request context:

```typescript theme={null}
// Accessing services in route handlers
router.get(
  { path: '/api/wazuh/example', validate: false },
  async (context, request, response) => {
    // Core services from wazuh-core
    const apiClient = context.wazuh_core.api.client.asCurrentUser;
    const config = await context.wazuh_core.configuration.get();
    
    // Wazuh-specific context
    const logger = context.wazuh.logger;
    const security = context.wazuh.security;
    
    // Use services
    const apiResponse = await apiClient.request(
      'GET',
      '/agents',
      {},
      { apiHostID: 'default' }
    );
    
    return response.ok({ body: apiResponse });
  }
);
```

## Plugin Communication

Plugins communicate through:

> **Direct API**
>
> Setup/start return values expose services to dependent plugins

> **Shared Context**
>
> Request context provides scoped service access

> **Events**
>
> Core event bus for lifecycle and state events

> **HTTP API**
>
> REST endpoints for cross-plugin communication

## Development Workflow

### Creating a New Plugin

**1. Create Plugin Structure**

```bash theme={null}
mkdir -p plugins/my-plugin/{public,server,common}
```

**2. Add Manifest**

Create `opensearch_dashboards.json` with plugin metadata

**3. Implement Plugin Classes**

Create `public/plugin.ts` and `server/plugin.ts`

**4. Export Plugin**

Create `public/index.ts` and `server/index.ts`

**5. Build and Test**

```bash theme={null}
yarn build
yarn test
```

### Plugin Development Best Practices

> [!WARNING]
>
> **Avoid These Anti-Patterns:**
>
> * Don't access services before they're initialized
> * Don't create circular dependencies between plugins
> * Don't bypass the plugin lifecycle (setup → start → stop)
> * Don't store request-specific data in plugin instance variables

> [!TIP]
>
> **Follow These Patterns:**
>
> * Use TypeScript interfaces for plugin contracts
> * Implement proper error handling in all lifecycle methods
> * Clean up resources in stop() method
> * Use dependency injection for testability
> * Keep plugins focused on single responsibilities

## Related Pages

> **[Architecture](./architecture)**
>
> Overall system architecture and design

> **[Security Modules](./security-modules)**
>
> Implemented security and monitoring features

> **[Data Sources](./data-sources)**
>
> Index patterns and data organization

> **[Development Guide](../development/setup)**
>
> Set up your development environment


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.