Job & Plugin: Registration

Audience: IT admins who need to know how plugins and jobs are discovered, registered, and loaded by the KEPM agent.

Plugin Registration

How Plugins Are Registered

Plugins are discovered from JSON files in the Plugins/ directory. The agent reads these files at startup, validates them, and launches plugins according to their startupPriority and autoStart settings. Plugins with pluginType: Executable run as separate processes; those with pluginType: Service run inside the main agent process.

  • Location: {approot}/Plugins/ — for example, C:\Program Files\KeeperPrivilegeManager\Plugins

  • File name: {PluginName}.json — for example, KeeperPolicy.json

To add a new plugin, place the plugin's binaries under Plugins/bin/{PluginName}/ and add the plugin JSON file at Plugins/{PluginName}.json. After a service restart (or plugin reload if supported), the new plugin is registered and available to be started.

Plugin JSON Fields

The following fields appear in plugin JSON files. Your plugin may not require all of them — validate against the Custom Plugin Integration Guide and your administrator documentation for your agent version.

Field
Description

id

Unique plugin identifier. Must match the filename and the key used in /api/PluginSettings/{id}.

pluginType

Executable for a separate process; Service for an in-process component.

executablePath

Path to the plugin binary. Can be relative to the agent root or absolute. Omit for in-process plugins.

supportedPlatforms

Array of OS names. The agent skips the plugin on unsupported platforms.

Subscription

Primary MQTT subscription: Topic, Qos, and CleanSession.

metadata.mqttTopics

Additional subscribe and publish topic permissions beyond the primary subscription.

startupPriority

Controls startup order. Lower numbers start earlier.

autoStart

When true, the agent launches the plugin at startup.

executionContext

Service, User, or Interactive — where the plugin process runs.

requiresMonitoring

When true, the agent watches the process and detects unexpected exits.

autoRestart

When true, the agent restarts the plugin if monitoring detects it has stopped.

Example plugin JSON:

Plugin Lifecycle

  • Start — The agent launches the plugin executable or loads the in-process component. The plugin subscribes to MQTT and begins its work.

  • Stop / Restart — Admins can stop or restart a plugin via the local management API — for example, POST /api/plugins/{name}/stop or /restart. When autoRestart: true is set, the agent restarts the plugin automatically if it exits unexpectedly.

  • Settings — Plugin settings can be stored in unified storage or in the plugin JSON. Updates delivered by policy or API may require a plugin restart to take effect.

MQTT Subscription and Publish Permissions

Plugins declare their MQTT access in the plugin JSON. The agent loads these declarations at startup and uses them to enforce which topics the plugin may subscribe to and publish to.

Primary subscription — Every plugin must declare one primary MQTT topic in the Subscription block. This is the plugin's main inbound topic for requests and control messages.

Additional topic permissions — Plugins can declare extra subscribe and publish permissions under metadata.mqttTopics:

The agent combines the primary subscription topic with any additional subscribe topics to form the plugin's effective subscription set. Topic validation is enforced at the broker — a plugin can only subscribe or publish to topics permitted by its registration. Both subscribe and publish arrays support MQTT wildcards (+ and #) where appropriate.

Job Registration

How Jobs Are Registered

Jobs are discovered from JSON files in the Jobs/ directory. The job runner scans this directory at startup and when files change, parses each JSON file, validates it, and registers the job. Valid jobs are then available for scheduling and event triggers. Invalid files are skipped and an error is logged.

  • Location: {approot}/Jobs/ — for example, C:\Program Files\KeeperPrivilegeManager\Jobs

  • File name: {job-id}.json — the id field inside the file must match the filename without the .json extension

What Registration Means for Jobs

A registered job is loaded, has a valid structure, and is known to the job runner. It will execute when its trigger fires, provided enabled is true and any declared condition is met.

An unregistered job is one whose file is missing, unparseable, or not yet loaded. It will not run regardless of any trigger.

You do not need to register jobs in a separate step. Placing a valid {id}.json file in the Jobs/ directory is sufficient — the job runner picks it up at the next rescan or restart. Jobs can also be created and updated via the HTTP API (POST /api/Jobs, PUT /api/Jobs/{id}), which writes the JSON and updates the Last Known Good store in a single operation. When Last Known Good is enabled, prefer the API or a JobUpdate policy over dropping files directly — hand-edited files may be reverted. See the Custom Job Integration Guide for details.

Job Loading Order and Precedence

Jobs are loaded in no guaranteed order. Dependencies between jobs should be expressed via events and alternateJobId, not assumed from load sequence.

If the same job id appears in more than one source (for example, both a file and an API write), the agent's last-write-wins behavior determines which definition is active. Prefer a single source of truth — either files managed by policy, or the API — to avoid ambiguity.

MQTT Subscription and Publish Permissions

Job tasks that need to communicate over MQTT declare their topic permissions in the mqttTopics block on the job root object — not inside the individual task definition.

When mqttTopics is present with at least one entry, the agent injects KEEPER_JOB_ID and KEEPER_JOB_NAME as environment variables before starting the task process. These are required to form the correct MQTT client ID for the connection.

The broker enforces allowedPublications and allowedSubscriptions at runtime. A publish or subscribe to a topic not in the declared lists will be denied, even if the MQTT connection itself succeeded. See Job & Plugin: MQTT Topic Permissions for the full enforcement model and a comparison with plugin topic declarations.

Summary

Plugins
Jobs

Configuration file

Plugins/{PluginName}.json

Jobs/{job-id}.json

Discovery

Scanned at startup from Plugins/

Scanned at startup from Jobs/ and on file change

MQTT permissions

Subscription + metadata.mqttTopics

mqttTopics on the job root

Lifecycle management

autoStart, requiresMonitoring, autoRestart

Triggered by schedule, events, or API

Adding a new component

Place JSON + binary, restart the agent

Place JSON in Jobs/ or use POST /api/Jobs

Last updated