# Overview

This page explains the concepts and moving parts behind a KEPM integration so you have a mental model before writing any code or JSON. If you have not read the [Integration](/keeperpam/endpoint-privilege-manager/integrations.md) landing page yet, start there — it defines the two integration patterns and lists what you need to collect from your deployment team before you begin.

***

### Key Terms

Understanding how KEPM uses these terms will prevent confusion as you read the guides.

**Job** — A JSON document stored as `{job-id}.json` under the agent's `Jobs/` directory. A job defines *when* something runs (a schedule, a startup event, or a named event topic) and *what* runs (one or more tasks). Jobs are the primary way to schedule and drive custom executables.

**Task** — One step inside a job. A task points at an executable or script, specifies how to run it (`ExecutionType`), passes arguments, sets a timeout, and defines what to do if the step fails. Most custom integrations have exactly one task per job.

**Plugin** — A component registered under `Plugins/{PluginId}.json` that the agent manages as a first-class process. Plugins have an agent-controlled lifecycle (start, monitor, restart) and subscribe to MQTT topics under their own identity. This is a distinct concept from a job task binary — your executable is not a plugin simply because it is deployed alongside the agent.

**KeeperLogger** — A built-in agent component that subscribes to the MQTT topic `KeeperLogger` and writes incoming messages to the agent's log pipeline. Your executable publishes structured JSON to that topic; the agent delivers those messages to wherever operators see logs. This is the primary way a custom job task communicates output back to the platform.

**MQTT broker** — A local message broker that the agent runs on the loopback interface (default `127.0.0.1:8675`, TLS). Local components — including your task binary — connect to it to publish and subscribe. Access is controlled by process trust: only executables the agent has launched or explicitly allow-listed can connect.

**Process trust** — The mechanism by which the agent decides which local processes may connect to its MQTT broker and call Plugin-tier HTTPS endpoints. When the job runner starts your binary, it registers that process immediately so that MQTT and HTTPS calls from your binary are authorized. If your binary starts some other way (manually, from a script), it must pass a certificate check instead — see the [Custom Job Integration Guide](/keeperpam/endpoint-privilege-manager/integrations/custom-job-guide.md) for the full details.

## Integrations Flow

The flow below describes what happens from the moment your job is deployed to the moment a log line appears in the operator's view.

```
┌─────────────────────────────────────────────────────────────────┐
│  KEPM Agent (on the endpoint)                                   │
│                                                                 │
│  Job runner reads Jobs/{job-id}.json                            │
│      │                                                          │
│      ├─ Evaluates triggers (schedule / Startup / event)         │
│      │                                                          │
│      └─ Starts your binary as a task process                    │
│             │   registers PID → process trust                   │
│             │   sets KEEPER_JOB_ID, KEEPER_JOB_NAME             │
│             │                                                   │
│             │   Your binary runs                                │
│             │       │                                           │
│             │       ├─ GET /api/PluginSettings/                 │
│             │       │   KeeperPrivilegeManager                  │
│             │       │   (Plugin-tier HTTPS)                     │
│             │       │   → reads broker.host, broker.port        │
│             │       │                                           │
│             │       └─ Connects to MQTT broker (TLS, loopback)  │
│             │           publishes to KeeperLogger               │
│             │                                                   │
│  KeeperLogger component                                         │
│      subscribes to "KeeperLogger" topic                         │
│      → writes messages to agent log pipeline                    │
│          → operators see log output                             │
└─────────────────────────────────────────────────────────────────┘
```

**The agent is the gatekeeper.** Your binary gets process trust, MQTT access, and runtime settings because the agent started it — not because of anything your binary does on its own first.

**You do not hard-code the broker address.** Your binary asks the agent at startup by calling Plugin Settings over HTTPS. The agent returns the current `broker.host` and `broker.port`.

**Logging flows through MQTT, not stdout.** Your binary publishes structured JSON to the `KeeperLogger` MQTT topic. The agent handles delivery from there.

**Job JSON controls MQTT permissions.** Your binary can only publish to topics explicitly listed in the job's `mqttTopics.allowedPublications`. The broker enforces this — permissions are not inherited or assumed.

## Jobs vs. Plugins

The two integration patterns share the same agent and the same MQTT broker, but they serve fundamentally different purposes.

### Use a Job When:

<table data-header-hidden="false" data-header-sticky><thead><tr><th>You need to...</th><th>How the job covers it</th></tr></thead><tbody><tr><td>Run a tool on a schedule or at agent startup</td><td>Define <code>schedule.intervalMinutes</code> and/or an <code>events</code> entry with <code>eventType: Startup</code></td></tr><tr><td>Publish logs to KeeperLogger</td><td>Set <code>mqttTopics.allowedPublications: ["KeeperLogger"]</code> on the job</td></tr><tr><td>Support multiple operating systems</td><td>Set <code>osFilter</code> so each platform only runs the task that matches</td></tr><tr><td>Pass runtime configuration to your binary</td><td>Use <code>{KeeperApiBaseUrl}</code> and other variable substitutions in <code>tasks[].arguments</code></td></tr><tr><td>Deploy the binary without plugin overhead</td><td>Place it under <code>Jobs/bin/{CommandName}/</code> — no plugin JSON required</td></tr></tbody></table>

A job task binary does not need to be long-running. The expected pattern is: start, do work, exit with a meaningful exit code. The agent records the exit code, captures output, and moves on.

### Use a Plugin When:

<table data-header-hidden="false" data-header-sticky><thead><tr><th>You need to...</th><th>Why a plugin fits</th></tr></thead><tbody><tr><td>Keep a process running continuously</td><td>Plugin JSON supports <code>autoStart: true</code> and <code>requiresMonitoring: true</code></td></tr><tr><td>Have the agent restart your process on failure</td><td>Set <code>autoRestart: true</code> in the plugin JSON</td></tr><tr><td>Subscribe to MQTT topics as a named, persistent identity</td><td>A plugin has a primary <code>Subscription</code> and its own topic namespace</td></tr><tr><td>Store per-component settings retrievable by plugin ID</td><td>Plugin settings are readable via <code>GET /api/PluginSettings/{yourPluginId}</code></td></tr><tr><td>Ship a component that behaves like a native part of the agent</td><td>Plugin packaging, signing, and lifecycle expectations match bundled components</td></tr></tbody></table>

### When to Use Both

The only time you need both patterns is when you genuinely have two separate lifecycles: a long-running daemon registered as a plugin (always on, monitored) and a separate scheduled job that performs periodic work using a *different* binary.

Avoid registering the same executable as both a plugin and a job task. Doing so can produce duplicate processes, conflicting MQTT client IDs, and ambiguity about which configuration path owns the binary's settings.

### Quick Reference

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Question</th><th>Answer</th></tr></thead><tbody><tr><td>Is <code>Plugins/{id}.json</code> required for a job task?</td><td>No. A job only needs <code>Jobs/{id}.json</code> and the deployed binary.</td></tr><tr><td>Can a job task publish to MQTT?</td><td>Yes, by declaring <code>mqttTopics.allowedPublications</code> on the job.</td></tr><tr><td>Can a job task call Plugin Settings over HTTPS?</td><td>Yes, when started by the agent (Plugin-tier auth).</td></tr><tr><td>When is plugin registration required?</td><td>Only when you need agent-managed lifecycle, persistent MQTT subscription, or plugin-scoped settings.</td></tr></tbody></table>

## What the Agent Provides to Your Process

When the agent starts your binary as a job task, it sets the following environment variables — but only when the job defines `mqttTopics` with at least one allowed publication or subscription:

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Variable</th><th>Value</th><th>Use</th></tr></thead><tbody><tr><td><code>KEEPER_JOB_ID</code></td><td>The <code>id</code> field from your job JSON</td><td>Required when forming the MQTT client ID</td></tr><tr><td><code>KEEPER_JOB_NAME</code></td><td>The <code>name</code> field from your job JSON</td><td>Useful for log messages and diagnostics</td></tr></tbody></table>

Your binary also receives `{KeeperApiBaseUrl}` as a substituted argument value (not an environment variable) if you include it in `tasks[].arguments`. Use it as the base URL for Plugin Settings HTTPS calls.

The agent does not inject `broker.host`, `broker.port`, or MQTT connection details as environment variables. Your binary is expected to fetch those at runtime from Plugin Settings.

***

### Now What?

For a **scheduled or event-driven tool** — the most common case — continue to the [Custom Job Integration Guide](/keeperpam/endpoint-privilege-manager/integrations/custom-job-guide.md). It covers every step from building and deploying the binary, to authoring the job JSON, to connecting to MQTT and publishing structured logs.

For a **managed, long-running component**, go to the [Custom Plugin Integration Guide](/keeperpam/endpoint-privilege-manager/integrations/custom-plugin-guide.md).

When you are ready to script job deployment or call Plugin Settings from inside your binary, the [HTTP Reference](/keeperpam/endpoint-privilege-manager/integrations/http-reference-guide.md) has the endpoints, authorization tiers, and request shapes you need.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.keeper.io/keeperpam/endpoint-privilege-manager/integrations/overview.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
