# プラグインとジョブの登録

**対象**: プラグインとジョブの検出・登録・読み込みを把握する必要があるIT管理者向けです。

***

### プラグインの登録

#### プラグインの登録方法

プラグインは**Plugins**ディレクトリ内の**構成ファイル**から**検出**されます。各プラグインには、プラグインの内容と実行方法を記述したJSONファイルがあります。

* **場所**: `{approot}/Plugins/` (例: `C:\Program Files\KeeperPrivilegeManager\Plugins`)
* **ファイル名**: `{PluginName}.json` (例: `KeeperPolicy.json`、`KeeperAPI.json`)
* **内容**: プラグインID、名前、種別 (Executable または Service)、実行ファイルのパス (該当する場合)、MQTTサブスクリプション、起動優先度、autoStart、その他のメタデータ

起動時にメインサービスがこれらのJSONファイルを読み取り、検証したうえで、**startupPriority**と**autoStart**に従ってプラグインを起動します。**Executable**のプラグインは別プロセスとして起動され、**Service**のものはメインプロセス内で動きます。

#### プラグインJSON (主なフィールド)

**代表的な構造**

```
{
  "id": "KeeperPolicy",
  "name": "Keeper Policy Service",
  "pluginType": "Executable",
  "executablePath": "{pluginroot}/KeeperPolicy/bin/Release/net8.0/KeeperPolicy",
  "supportedPlatforms": ["Windows", "Linux", "macOS"],
  "Subscription": {
    "Topic": "KeeperPolicy",
    "Qos": 2,
    "CleanSession": true
  },
  "startupPriority": 20,
  "autoStart": true,
  "executionContext": "Service"
}
```

* **id**: 一意のプラグインID。システム上のプラグイン識別子と一致必須
* **pluginType**: `Executable` (別プロセス) または `Service` (同一プロセス内)
* **executablePath**: プラグイン実行ファイルへのパス。`{pluginroot}` などの変数可。プロセス内プラグインでは省略
* **supportedPlatforms**: OS名の一覧。非対応プラットフォームではエージェントがプラグインをスキップする場合あり
* **Subscription**: メッセージング用のMQTTトピックとオプション
* **startupPriority**: 数値が小さいほど先に起動
* **autoStart**: trueのとき、サービス起動時に当該プラグインを起動
* **executionContext**: Service、User、または Interactive (プラグインの実行コンテキスト)
* **requiresMonitoring**: trueのとき、エージェントがプロセスを監視し、予期しない終了を検出します
* **autoRestart**: trueのとき、監視で停止を検出した場合にエージェントがプラグインを再起動します

新しいプラグインを追加する場合は、プラグインのバイナリを `Plugins/bin/{PluginName}/` に置き、プラグインJSONファイルを `Plugins/{PluginName}.json` に追加します。サービス再起動後 (または対応している場合はプラグインの再読み込み後)、新しいプラグインが登録され、起動できるようになります。

#### プラグインのライフサイクル

* **起動**: メインサービスがプラグインを起動します (実行ファイルの起動、またはプロセス内コンポーネントの読み込み)。プラグインはMQTTにサブスクライブし、処理を行います。
* **停止/再起動**: 管理者はローカル管理API経由でプラグインを停止または再起動できます (例: `/api/plugins/{name}/stop` または `/restart` へのPOST)。サービスは、クラッシュ時にプラグインを再起動する場合もあります (autoRestart が有効なとき)。
* **設定**: プラグイン設定は統合ストレージまたはプラグインJSONに保存できます。ダッシュボードまたは構成ポリシーからの更新は、反映にプラグインの再起動が必要な場合があります。

#### プラグイン登録: MQTTサブスクリプションとパブリッシュ設定

Keeper特権マネージャーのプラグインは、**プラグイン登録の一環として** (プラグインのJSON定義内で) MQTTアクセスを宣言します。各プラグインは、必須の `Subscription.Topic` に**主たるサブスクリプショントピック**を登録し、任意で `metadata.mqttTopics` に**追加のサブスクライブトピック**と**パブリッシュ許可**を定義します。サービス起動時にプラグイン定義を読み込み、自動起動プラグインを立ち上げ、これらのMQTT設定に基づき、当該プラグインが購読・送信してよいトピックを決定します。

**1) 主サブスクリプション (必須)**\
各プラグインは `Subscription` ブロックを使って、主となるMQTTトピックを1つ登録する必要があります。リクエスト/制御メッセージ向けの、プラグインの主な受信トピックです (例: ポリシープラグインが `KeeperPolicy` を使う場合)。

```json
"Subscription": {
  "Topic": "KeeperPolicy",
  "Qos": 2,
  "CleanSession": true
}
```

**2) 追加のトピック権限 (任意)**\
プラグインは `metadata.mqttTopics` にトピック権限を追加登録できます。

* `metadata.mqttTopics.subscribe`: `Subscription.Topic` に加えてサブスクライブしてよい追加トピック
* `metadata.mqttTopics.publish`: パブリッシュが許可されるトピック

これらのリストでは、必要に応じてMQTTワイルドカード (`+`および`#`) を使えます。

```json
"metadata": {
  "mqttTopics": {
    "subscribe": [ "AuditMessage", "EventMessages" ],
    "publish": [ "KeeperLogger", "EventMessages" ]
  }
}
```

**Keeper特権マネージャーでの設定の適用**\
Keeper特権マネージャーは、プラグインの**主サブスクリプショントピック** (`Subscription.Topic`) と**追加サブスクライブトピック** (`metadata.mqttTopics.subscribe`) を組み合わせて実効的なサブスクリプション集合を構成し、`metadata.mqttTopics.publish` によりパブリッシュ権限を強制します。登録構成で許可されたトピックに限りサブスクライブ/パブリッシュできるよう、トピックの検証が行われます。

***

### ジョブの登録

#### ジョブの登録方法

ジョブは**Jobs**ディレクトリから**検出**されます。各ジョブは1つのJSONファイルです。

* **場所**: `{approot}/Jobs/` (例: `C:\Program Files\KeeperPrivilegeManager\Jobs`)
* **命名**: `{job-id}.json`。ファイル内の**id**はファイル名と一致させる必要があります
* **読み込み**: ジョブサービス (または同等の処理) が起動時およびファイル変更時にディレクトリをスキャンし、各JSONを解析・検証してジョブを登録します。有効なジョブはイベントとスケジューリングに利用可能になります。無効なファイルはスキップされ、エラーがログに記録される場合があります。

#### ジョブにおける「登録」の意味

* **登録済み** = ジョブが読み込まれ、構造が有効で、ジョブランナーに認識されている状態。**有効**であり、必要なら**条件**も満たしていれば、トリガー (イベントまたはスケジュール) が発火したときに実行されます。
* **未登録** = ファイルがない、無効、または読み込まれていない (例: ディレクトリ違い、解析エラー)。ジョブは実行されません。

ジョブを別手順で「登録」する必要はありません。有効な `{id}.json` を `Jobs/` ディレクトリに置くだけで十分です。次回の再スキャンまたは再起動でジョブランナーが取り込みます。ジョブはHTTP API (`POST /api/Jobs`、`PUT /api/Jobs/{id}`) から作成・更新することもでき、この場合JSONの書き込みとラストノウングッドストアの更新が一度に行われます。ラストノウングッドが有効な場合は、ファイルを直接置くより API または `JobUpdate` ポリシーを優先してください。手編集したファイルは元に戻る場合があります。詳しくは[カスタムジョブ統合ガイド](https://claude.ai/integration/custom-job-guide#part-3-author-the-job-json)をご参照ください。

#### ジョブの読み込み順と優先

* ジョブの読み込み順序は一般に保証されません。依存関係は**イベント**と**alternateJobId**で表現し、読み込み順に頼らないでください。
* 同一のジョブ**id**が複数箇所に存在する場合 (例: ファイルとAPI)、最終更新優先やファイル優先などの挙動は実装依存です。単一の正とするソースを推奨します (例: エージェント上ジョブはファイル、管理下ジョブはダッシュボード/API)。

#### ジョブ登録: MQTTサブスクリプションとパブリッシュ設定

MQTT で通信する必要があるジョブタスクは、**個々のタスク定義の内側ではなく**ジョブルートオブジェクトの `mqttTopics` ブロックでトピック権限を宣言します。

```json
"mqttTopics": {
  "allowedPublications": ["KeeperLogger"],
  "allowedSubscriptions": []
}
```

`mqttTopics` が少なくとも1エントリ付きで存在する場合、エージェントはタスクプロセスを起動する前に `KEEPER_JOB_ID` と `KEEPER_JOB_NAME` を環境変数として注入します。接続用の正しい MQTT クライアント ID を構成するために必要です。

ブローカーは実行時に `allowedPublications` と `allowedSubscriptions` を適用します。MQTT 接続自体は成功していても、宣言リストにないトピックへの publish または subscribe は拒否されます。適用モデル全体およびプラグイン宣言との比較については、[ジョブとプラグイン: MQTTトピックの権限](https://github.com/Keeper-Security/gitbook-jp-secrets-manager/blob/main/endpoint-privilege-manager/reference/job-and-plugin-mqtt-topic-permissions.md)をご参照ください。

***

### まとめ

* **プラグイン**: `Plugins/*.json` の読み取りにより登録。各ファイルが1プラグイン (id、executablePath、Subscription、autoStart など) を記述。プラグインJSONの追加・編集後、再起動 (または再読み込み) で登録または変更を反映。
* **ジョブ**: `Jobs/*.json` の読み取りにより登録。各ファイルが1ジョブ (id、tasks、スケジュールまたはイベント)。JobsディレクトリにジョブJSONを追加・編集するか (対応時はAPI経由)、ジョブランナーが読み込んで実行できるようにする。


---

# 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/jp/endpoint-privilege-manager/reference/plugin-and-job-registration.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.
