技術アーキテクチャ

対象: IT管理者および技術担当者向け。本ページではエンドポイント特権マネージャーの技術アーキテクチャとして、イベント駆動の考え方、MQTTとHTTPSの役割、プラグインの読み込みと監視、ジョブの起動と実行の流れを取り扱います。
概要
エンドポイント特権マネージャーは、各エンドポイントで動く中央オーケストレーションサービスです。単体ではポリシー評価やログ記録は行わず、以下の役割を担います。
MQTTブローカーとHTTP/HTTPS APIを内蔵し、プラグインとジョブが通信できるようにします
プラグインを読み込んで監視します (KeeperPolicy、KeeperAPI、KeeperLoggerなど別プロセス)。失敗時は再起動できます
ジョブサービスを動かし、イベントが発動したとき (MQTT経由)、スケジュールに一致したとき、またはAPI経由の手動トリガー時にジョブを実行します
システムはイベント駆動です。多くのワークフローは、何かがMQTTブローカーにメッセージをパブリッシュしたときに始まります (例: 「ポリシー評価が必要」「昇格の起動」)。サブスクライバー (プラグインまたはジョブサービス) がそれらのメッセージに反応し、リクエストを処理するか、一連のタスクを順に実行するジョブを起動します。
アーキテクチャの全体像
プラグインはMQTTブローカーに接続し、メッセージの送受信を行います。HTTP APIを呼び出す場合もあります (設定取得、ジョブ起動、プロセス起動など)。
ジョブはイベント (MQTT)、スケジュール、またはAPIでトリガーされます。実行時にはタスクの一覧が順に処理されます (実行ファイルの起動、HTTP呼び出しなど)。タスクの出力はコンテキストにマージされ、後続のタスクやルーティング判断に使われます。
イベント駆動モデル
システムはイベント駆動です。処理は単一の逐次プログラムではなく、イベントによって起動されます。
イベントの流れ
エンドポイント上で何かが起きます (例: ユーザーが昇格を要求する、フックやエージェントが検知する、またはサービスが起動する)。
特定のトピックへMQTTブローカー経由でメッセージがパブリッシュされます (例: KeeperPolicyが購読するトピックへのポリシー評価リクエスト、またはジョブサービスが待ち受けるトピックへの
PolicyEvaluationPendingやLaunchPrivilegeElevationなどのカスタムイベント)。サブスクライバーがメッセージを受け取ります。
プラグイン (例: KeeperPolicy) はトピックを購読し、リクエストを処理します (例: ポリシー評価、ALLOW/DENY/PENDINGの返却)。
ジョブサービスは、カスタムイベントがパブリッシュされると (購読または通知で) それを受け取り、そのイベント名を
eventsに持つジョブをすべて見つけ、イベントのコンテキスト付きで一致するジョブをそれぞれ起動します。
ジョブはタスクを順に実行します。タスクはさらにMQTTへパブリッシュ (例: 応答トピックへ返す)、HTTP APIを呼び出す (例: 昇格起動、設定取得)、実行ファイルを起動する (例: KeeperMFA、KeeperApproval) などが可能です。これにより後続のイベントが発動する場合があります (例: コントロール完了後に
LaunchPrivilegeElevationがパブリッシュされ、起動ジョブが動きます)。
このため、1つのイベントがジョブ実行につながり、そのジョブが別イベントをパブリッシュし、さらに別のジョブへと続くことがあります。ポリシー評価、コントロール (MFA、承認、正当な理由の入力)、起動の一連の処理は、このイベント連鎖でつながっています。
代表的なイベント名 (カスタムイベント)
PolicyEvaluationPending: ポリシー評価がPENDING (コントロール必須) になったとき。privilege-elevation-policy-controls、file-access-policy-controls、default-policy-controlsなどのポリシーコントロール用ジョブがこれを購読し、MFA/正当な理由の入力/承認のワークフローを実行します。
LaunchPrivilegeElevation: ユーザーへの昇格が許可されたとき。実際にプロセスを起動するジョブ (LaunchPrivilegeElevation) が、コンテキスト (ファイルパス、コマンドライン、ユーザーなど) 付きでトリガーされます。
Startup: サービス起動時に発動します。登録やクリーンアップなどのジョブが購読します。
LaunchApprovedRequest、ShowAgent など: UIやワークフローから特定のジョブを起動するときに使われます。
イベントにはコンテキスト (パラメータ) を付与でき、ジョブの初期コンテキストとして引き渡され、タスクから参照できます (例: {RequestId}、{FilePath}、{UserName})。
MQTTの役割
MQTTブローカーの役割
メインサービスは組み込みMQTTブローカー (既定ポート8675、localhost のみ) を動かしています。製品のメッセージバスです。
プラグインはMQTTクライアントとしてブローカーに接続します。各プラグインには購読構成 (購読するトピック) とパブリッシュ許可 (パブリッシュできるトピック) があります。
プロセスベースのセキュリティ: KeeperPrivilegeManagerによって起動されたプロセス (かつ有効な証明書を提示できるもの) だけが接続を許可されます。任意のアプリケーションがパブリッシュや購読を行えないようにします。
トピックベースのルーティング: メッセージは、そのトピックを購読しているすべてのクライアントに届きます。EventMessages (またはカスタムイベント用の同等トピック) へパブリッシュすると、ジョブサービスが受け取ってジョブを起動できます。KeeperPolicy へパブリッシュすると、KeeperPolicyプラグインが受け取ってポリシーを評価します。
代表的なトピック (概念)
KeeperPolicy: ポリシー評価リクエスト (受信)、ポリシー応答 (送信)
KeeperLogger: ログメッセージ (プラグインとジョブがここへパブリッシュしログを集約)
KeeperApi: バックエンド同期、登録、監査 (KeeperAPIプラグイン)
EventMessages (または同等): ジョブを起動するカスタムイベント (例: PolicyEvaluationPending、LaunchPrivilegeElevation)。ジョブサービスが購読し、イベント名とジョブ定義を照合
JobService: ジョブ関連メッセージ (完了、トリガーなど)
keeperAgent、KeeperClient、RequestApprovalなど: UIや承認ワークフローで使用
正確なトピック名やどのプラグインが何をパブリッシュ/購読するかは、各プラグインのJSON (Subscription、metadata.mqttTopics) で定義されます。アーキテクチャ上重要なのは、イベントおよびポリシー処理に関するコンポーネント間通信はすべてlocalhost上のMQTT経由であり、プロセスとトピックの検証が行われることです。
MQTTとイベント駆動ジョブ
カスタムイベントでジョブを起動する場合:
何らかのコンポーネント (例: KeeperPolicyまたは別ジョブ) がイベント用トピックへイベント名とペイロード (コンテキスト) を載せたメッセージをパブリッシュします。
ジョブサービスがメッセージを受け取り、TriggerJobByEvent(eventName, context) (または同等) を呼び出します。
events配列にそのイベント名を含むジョブ (例:
customEvent: "LaunchPrivilegeElevation") がすべて照合され、そのコンテキストで起動されます。それぞれのジョブがタスクリストを実行します。タスクはさらにMQTTへパブリッシュしたりHTTP APIを呼んだりし、追加のイベントや副作用を生みます。
MQTTはリクエスト/レスポンス (例: ポリシーリクエスト → KeeperPolicy → 応答) と、ジョブサービスへファイア・アンド・フォーゲット型のイベントを届けてジョブを起動する用途の両方に使われます。
HTTPS (およびHTTP) の使われ方
HTTP/HTTPS APIサーバー
メインサービスはHTTP/HTTPS API (Kestrel) をlocalhost のみ (127.0.0.1) にバインドして公開します。
HTTP既定ポート6888
HTTPS既定ポート6889 (推奨。
localhost向け自己署名証明書を使用)
APIの用途:
ヘルスと状態:
GET /health、GET /、GET /api/system/status(認証なし。監視やスクリプト用)プラグイン管理: プラグインの開始/停止/再起動、一覧 (エンドポイントに応じてAdminまたはPlugin認可)
ジョブ管理: ジョブ一覧、ジョブ実行、コンテキスト付きトリガー、ジョブJSONの検証 (PluginまたはAdmin)
設定: アプリおよびプラグイン設定の読み書き。プラグイン設定のJSONからの復元 (書き込みはAdmin)
登録: エージェントのKeeperバックエンドへの登録/登録解除 (Adminまたは構成どおり)
その他: ファイルアクセス、ユーザーセッション起動、一時アカウント、監査など。ローカルエンドポイントをご参照ください。
APIの呼び出し元
プラグイン: 設定読み込み (
GET /api/PluginSettings/{pluginName})、ジョブトリガー (POST /api/Jobs/{id}/trigger)、起動/一時アカウント系エンドポイントなど。HTTPSベースURL (構成やパラメータ由来) を使用ジョブのタスク: ジョブ内のHTTPタスクが任意のURL (多くはローカルAPI) を呼び、ジョブ起動、プロセス起動、実行許可の作成、設定の復元などを実行。Serviceタスクで実行ファイル (KeeperMFA、RedirectEvaluatorなど) を動かす場合、実行ファイルがコールバックできるようAPIベースURLが引数で渡されることがある
管理者/スクリプト: 管理スクリプトや運用者がAPIを呼び出し (必要に応じてAdmin権限またはクライアント証明書)、ヘルス確認、プラグイン再起動、ジョブ実行、設定変更を実行
認可レベル (概念): Public (ヘルス、状態)、Plugin (エンドポイント特権マネージャーによって起動されたプロセス + 証明書)、Admin (昇格済みユーザーまたは信頼済みプロセス + 証明書)。同期的な管理APIと連携にはHTTPS、プラグインとジョブまわりの非同期のイベント・メッセージにはMQTTが使われます。
プラグインの読み込みと監視
プラグインの読み込み
検出 — 起動時にメインサービスがPluginsフォルダを走査し、プラグインJSON (例:
KeeperPolicy.json、KeeperApi.json) を探します。各ファイルが1プラグインを表し、id、名前、実行パス、購読トピック、起動優先度、autoStart、その他メタデータを記述します。検証 — サービスがプラグインを検証します (例: パスの安全性、必要なら証明書)。検証に失敗したプラグインは起動されません。
起動順 — プラグインはstartupPriorityで並べられます (数値が小さいほど先)。autoStart: trueのものがその順で起動します。autoStart: falseは読み込まれますが、APIやオンデマンドで要求されるまで起動しません。
起動 — Executableプラグインでは、サービスがプラグインプロセスを起動します (executablePath)。プロセスはMQTTブローカーに接続し、通常はHTTP APIで設定を読み込みます。その後、構成どおりトピックを購読しメッセージを処理します。
プラグインはJSONから読み込まれます。 ランタイムにAPIで「登録」するのではなく、起動時の定義の根拠はJSONファイルです。プラグインを追加するにはJSON (とバイナリ) を置き、サービスを再起動します (または autoStart: false ならAPIで開始します)。
監視と再起動
ヘルスチェック — メインサービスが定期的に各プラグインプロセスの生存を確認し、必要なら生存確認 (単純なpingやヘルスコールバックなど) を行います。間隔と挙動は構成可能です (例: appsettingsのPluginMonitoring)。
自動再起動 — プラグインにautoRestart: trueがあり、監視で異常終了またはヘルス不良と判定された場合、サービスが自動再起動できます。KeeperPolicyやKeeperLoggerなど重要なプラグインの継続稼働に役立ちます。
手動制御 — 管理者はHTTP APIでプラグインを停止または再起動できます (
POST /api/plugins/{name}/stop、POST /api/plugins/{name}/restart)。サービス全体の再起動は不要です。
まとめ: プラグインは Plugins/*.json から読み込まれ、優先度順に起動され、監視されます。失敗時は自動再起動するか、API経由で手動再起動できます。
ジョブの起動と実行
ジョブ定義と登録
ジョブはJobsフォルダ内のJSONファイルで定義されます。各ファイルにid、events (任意)、schedule (任意)、parameters、tasks、condition、任意でalternateJobIdがあります。
起動時 (および実装に応じてファイル変更時)、ジョブサービスがジョブJSONをすべて読み込み検証し、各ジョブを登録します。いずれかのトリガーが発動するとジョブが「起動」されます。
トリガーの種類
ジョブは、イベント、スケジュール、手動操作のいずれかで起動されます。
Event
イベント用トピックにイベント名 (例: PolicyEvaluationPending、LaunchPrivilegeElevation) を含むメッセージがパブリッシュされます。ジョブサービスがTriggerJobByEvent(eventName, context) を呼び出します
ジョブのevents配列にその名前のイベントがあること (例: eventType: "Custom"、customEvent: "LaunchPrivilegeElevation")
Schedule
内部タイマーが動きます (例: 毎分、cron単位)。ジョブサービスが各ジョブのschedule (interval、cron、runAt、カレンダー) を評価します
現在時刻がジョブのスケジュールに合致すること
Manual
管理者またはスクリプトがPOST /api/Jobs/{jobId}/run または POST /api/Jobs/{jobId}/trigger を任意のボディ付きで呼び出します
リクエストのジョブidがジョブのidと一致すること
ジョブはeventsとscheduleの両方を持てます。イベントが一致するかスケジュールが一致するかのいずれかで実行されます。
ジョブ実行の流れ (概要)
トリガーが発動すると、ジョブサービスが一致するジョブをすべて探します (イベント名、スケジュール、またはジョブid)。
一致する各ジョブ (多くは1つ) について、サービスがトリガコンテキスト (イベントペイロード、パラメータ、既定値) でジョブ実行を開始します。
ジョブ単位のcondition (定義されている場合) を評価します。失敗ならジョブはスキップされます (またはalternateJobIdが実行されます)。成功ならタスクループに入ります。
タスクループ — 順に各タスクについて:
タスクcondition (定義されている場合) を現在のコンテキスト (トリガコンテキスト + パラメータ + 先行タスクの出力) で評価します。偽ならタスクはスキップされ、リスト順の次のタスクへ進みます。
タスクがプラグイン設定を参照する場合 (例: 「metadata.redirect.enabled が false のときスキップ」)、それを評価し、スキップならコマンドは実行せず、任意のContextWhenSkippedをコンテキストにマージします。
タスクを実行します:
Service — サービスセッションで実行ファイルを起動します (RedirectEvaluator、KeeperMFAなど)。出力 (例: stdoutのJSON) を後続タスク用にコンテキストへマージできます。
HTTP — HTTP/HTTPSリクエストを発行します (例: ローカルAPIでプロセス起動や別ジョブのトリガー)。実行ファイルは使いません。
User / UserDesktop / UserElevated — ユーザーセッションで実行します (非昇格、デスクトップ、または昇格)。
ルーティング — 成功時、次タスクはOnSuccess (明示的なタスクid) またはリストの次です。失敗時はOnFailureまたはリストの次です。ContinueOnFailureがfalseならジョブは停止します。スキップ時は常にリストの次です。
タスクリストが終わる (またはタスクが「停止」へルート) と、ジョブの実行が完了します。再度トリガーされない限り、それ以上タスクは動きません。
ジョブはイベント (MQTT)、スケジュール (タイマー)、またはAPIで起動されます。各実行は任意の条件とルーティング付きのタスク列であり、タスクは実行ファイル、HTTP、ユーザーコンテキストで動き、MQTTパブリッシュやAPI呼び出しでさらにジョブや操作を引き起こせます。
タスク実行タイプ (要約)
Service
サービスセッション (ユーザーデスクトップなし)
バックエンド実行ファイル (RedirectEvaluator、リスク評価)、スクリプト、組み込みコマンド (echo、publish-mqtt)
Http
HTTPクライアント
ローカルAPIまたは外部URLの呼び出し (ジョブのトリガー、昇格起動、設定復元)
User
ユーザーセッション、非昇格
ユーザーコンテキストでのプロセス
UserDesktop
ユーザーのデスクトップ、非昇格
ダイアログ表示が必要なUIアプリ (KeeperMFA、KeeperJustification、KeeperApproval)
UserElevated
ユーザーコンテキスト、昇格
ユーザーセッションで昇格したプロセスを実行
エンドツーエンド例: 特権昇格
MQTT、HTTPS、プラグイン、ジョブの関係を1例にまとめます。
ユーザーが昇格を要求します (例: アプリを右クリックして「管理者として実行」)。OSまたはエージェント (KeeperRunAs、フックなど) がこれを検知し、ポリシー判断が必要になります。
KeeperPolicyへのリクエスト — 判断が必要なコンポーネントがKeeperPolicyトピック (または同等) に、コンテキスト (ユーザー、マシン、アプリケーション、コマンドライン、イベント種別) を載せてメッセージをパブリッシュします。
KeeperPolicy (プラグイン) がメッセージを受け取り、ポリシーを評価し、ALLOW、DENY、またはPENDING (コントロール必須) と決めます。応答をパブリッシュします (例: 応答トピックまたはEventMessages)。
結果がPENDINGなら、ジョブサービス (またはイベントを出したコンポーネント) がコンテキスト (ControlList、SessionId、RespondToTopicなど) 付きでPolicyEvaluationPendingイベントをトリガーします。privilege-elevation-policy-controls (または同等) ジョブが一致して実行されます。
そのジョブがタスクを実行します: 例 PendingApprovals 確認、続けて KeeperMfa / KeeperJustification / KeeperApproval (UserDesktopタスク)、publish-mqttで監査送信、コントロール成功後に LaunchPrivilegeElevation イベントをパブリッシュします (コンテキストに FilePath、CommandLine、UserName など)。
LaunchPrivilegeElevationジョブがそのイベントに一致して動きます。タスク例: check-redirect (RedirectEvaluator設定を読み、リダイレクト有効ならRedirectEvaluator実行)、launch-substitute (代替exeを昇格起動するHTTP) または launch-elevated (要求されたexeを昇格起動するHTTP)、publish-mqttで最終応答 (DidElevateやDenyなど) を呼び出し元へ送ります。
呼び出し元 (フックやエージェント) が応答を受け取り、ユーザー操作を許可またはブロックします。
この一連の流れでは、MQTTがイベントとリクエスト/レスポンスを運び、HTTPSがプラグイン設定、ジョブのトリガー、起動APIに使われます。プラグインはJSONから読み込まれ監視され、ジョブはイベント (またはスケジュール/手動) で起動し、実行ファイルやHTTPを経由して処理を進めます。
まとめ
イベント駆動
処理はイベント (MQTTメッセージ) で駆動します。ポリシーリクエスト、コントロール、起動の流れはすべてブローカーへのパブリッシュで始まり、サブスクライバー (プラグイン、ジョブサービス) がロジックやジョブを実行します
MQTT
ポート8675の組み込みブローカー (localhost)。ポリシーのリクエスト/レスポンス、カスタムイベント (ジョブのトリガー)、ログ、プラグイン間メッセージに使用します。プロセスとトピックの制限があります
HTTPS
ポート6888 (HTTP) と6889 (HTTPS) のKestrel、localhost のみ。ヘルス、プラグイン/ジョブ管理、設定、登録、起動、その他API操作に使用します
プラグイン
起動時にPlugins/*.json から読み込まれ、優先度で起動し、監視と構成どおり自動再起動されます。MQTTに接続し、必要に応じHTTP APIを呼びます
ジョブ
Jobs/*.json で定義されます。イベント (MQTT)、スケジュール (タイマー)、手動 (API) で起動します。各実行は条件とルーティング付きのタスクリスト (Service、HTTP、User、UserDesktop、UserElevated) です
最終更新

