このガイドでは、新しいリスク交換プラグインを作成する方法と、リスク交換モジュール内で提供される機能を活用してリスクエコシステムから最大限の価値を引き出す方法について説明します。このガイドに従えば、開発者は技術的な問題なく、独自に新しいプラグインを作成できるようになるはずです。
前提条件
- Python 3.xのプログラミング経験(中級レベル)。
- Netskope Cloud Exchangeプラットフォームへのアクセス。
- プラグインを作成する必要のある製品またはソリューションへのAPIまたはPython SDKへのアクセス。
- 製品に対する最低限の権限を持つアカウント。
Compatibility
このプラグイン開発ガイドは、コアバージョンv5.1.0でサポートされているリスクエクスチェンジプラグインの開発に特化したものです。
リスク交換モジュール
Cloud Exchangeプラットフォームとその Risk Exchange モジュールには、高度なカスタマイズを可能にする豊富な機能セットが付属しているため、以下に示すプラットフォームのさまざまな側面についてよく理解しておくことをお勧めします。
このモジュールは、サードパーティのプラットフォームからのレコードの取得をサポートし、プラットフォーム上のグループへのユーザーの追加などのアクションを実行します。
Netskopeの概念と用語
- コア:Cloud Exchangeのコアエンジンは、サードパーティ製プラグインとそのライフサイクルメソッドを管理します。プラットフォームと対話してさまざまなタスクを実行するための API エンドポイントがあります。
- モジュール:さまざまなワークフローを実行するために、モジュール固有のプラグインを呼び出す機能的なコード領域。Risk Exchangeは、Cloud Exchangeで動作するモジュールの1つです。
- プラグイン:プラグインは、サードパーティの脅威インテリジェンスシステムからユーザー、デバイス、アプリケーションの詳細、およびリスク/脅威情報を取得するロジックを備えたPythonパッケージであり、取得された情報はRisk Exchangeに保存されます。Risk Exchangeプラグインは、サードパーティプラットフォームでサポートされている場合、ユーザーをグループに追加したり、グループからユーザーを削除したり、デバイスレコードやアプリケーションレコードに対してその他の操作を実行したりすることもできます。
- プラグイン構成:プラグイン構成とは、必要なパラメータで構成され、ユーザーとスコアを取得するためにCloud Exchangeコアエンジンによってスケジュールされるプラグインクラスオブジェクトのことです。
- スキーマエディタ:書き込み権限を持つユーザーは、スキーマエディタからリスクエクスチェンジのスキーマとエンティティフィールドを管理できます。
- エンティティ:エンティティとは、特定のスキーマのフィールドの集合であり、レコードはこのエンティティに格納されます。エンティティは、リスク交換モジュールのスキーマエディタページから管理できます。
- レコード: レコード (ユーザー、デバイス、またはアプリケーション) は、プラグイン構成のエンティティ ソースステップでマッピングされたフィールドを持つオブジェクトであり、サードパーティ プラットフォームから収集され、Cloud Exchange データベースのマッピングされたエンティティに保存されます。
開発ガイドライン
- すべての Python コードのプラグイン ディレクトリ構造を使用します。
- プラグインパッケージに同梱されているすべてのサードパーティライブラリについて、既知の脆弱性がないか確認してください。
- 標準的なPythonのコーディング規約を必ず守ってください。(https://peps.python.org/pep-0008/)
- flake8のLintチェックを実行し、ドキュメント文字列チェックを有効にした状態で合格することを確認してください。行の最大長は80です。
- タイムスタンプ値を人間が読みやすい形式に変換します(エポックからDateTimeオブジェクトへ)。UIに表示される時刻が、現地のタイムゾーンであることを確認してください。
- 可能であれば、プラグインで設定パラメータを追加する際に、デフォルト値を追加してください。
- プラグインアーキテクチャでは状態の保存は可能ですが、状態管理のために巨大なオブジェクトを保存することは避けてください。
- Pythonコードに脆弱性がないか確認してください。
- プラグインのアイコンは10KB未満でなければなりません。必ず会社のロゴ(製品のロゴではなく)を透明なバックグランドで使用してください。 ロゴの推奨サイズは300×50ピクセル、またはそれに近いアスペクト比です。
- CEコアが提供するチェックポイントを使用する方が、独自に実装するよりも良いでしょう。
- ロガーメッセージとトーストメッセージには、APIトークンとパスワードタイプのフィールド値を含めてはいけません。
- プラグインの機能開発においては、ページネーションを常に考慮に入れるべきです。
- ステータスコード429に対する再試行メカニズムを必ず追加してください。
- CE プラットフォームによって渡されるロガー オブジェクトを使用して、適切なロギング メカニズムを実装してください。 運用チームがトラブルシューティングを行う際に役立つよう、十分なログ記録が行われるようにしてください。通知に機密データが記録されたり、漏洩したりしないようにしてください。
- すべてのパラメータに対して適切なヘルプテキスト(ツールチップ)を提供してください。可能であれば、ツールチップでそのパラメータの重要性を説明するようにしてください。
- プラグイン設定パラメータには必ず意味のある名前とデスクリプションを指定してください。
- デスクトップリプションにリンクが含まれている場合は、プレーンテキストではなくハイパーリンクにする必要があります。
- パラメータには、適切な設定タイプ(テキスト、数値、パスワード、選択式、複数選択式)を指定してください。
- アウトバウンド リクエスト (API/SDK) の作成中に、CE プラットフォームによって渡されるプロキシ構成辞書と SSL 証明書検証フラグを必ず使用してください。
- 必須ではないパラメーターの値を取得するようにしてください .get() メソッドとデフォルト値の提供 .get() 方法。
- API トークンとパスワード フィールドでは、strip() を使用しないでください。
- ログ メッセージは「 <module> <plugin_name> [configuration_name]: 」で始まるはずです。 例:「 CRE CrowdStrike [ CrowdStrike設定名]: <log_message> 」。(これは提案であり、設定名は使用しないことも可能です。) [logger.info(“<module> <plugin_name>: <message>”)]
- エラーログを記録する際には、可能であれば例外のトレースバックも追加すべきです。使う: logger.error(error, 詳細=traceback.format_exc())
- The Toast message should not contain the <app_name> <module>: in the message.
- API呼び出し中および呼び出し後に、適切な例外とステータスコードを捕捉するようにしてください。可能であれば、開発者はリクエストを行うためのヘルパーメソッドを作成し、必要に応じて適切なパラメータを指定してこのメソッドを呼び出すことができます。
- 必ず APIヘルパーを使用してサードパーティAPI呼び出しを実行してください。 APIヘルパーの例については、 fetch_recordsのコードスニペットセクションを参照してください。ヘルパーファイルのリファレンスを確認してください( https://github.com/netskopeoss/ta_cloud_exchange_plugins/blob/main/crowdstrike_ztre/utils/helper.py )
- ベアラートークン認証の場合、検証メソッド内のリクエストを除き、すべてのAPIリクエストのステータスコードが401 Unauthorizedときに認証トークンを再読み込みします。APIヘルパーで認証トークンを再読み込みするタイミングを示すフラグを維持します。
- APIヘルパーでexceptions.ReadTimeoutエラーを処理します。
- CHANGELOG.md ファイルには、追加、変更、修正などの適切なタグと、ユーザーにとって分かりやすいメッセージを追加して更新する必要があります。ファイル名がCHANGELOG.mdと完全に一致していることを確認してください。
- For Action parameters validation:
- アクション パラメーターがソース フィールドから選択された場合は、そのフィールドの値を検証します。 execute_action
- アクションパラメータのタイプが「 choice 」の場合、検証メッセージは次のようになります。「 {Parameter}にはソースフィールドが含まれています。静的フィールドのドロップダウンリストから{field}のみを選択してください。 」
- プラグインがdatetimeフィールドをサポートしている場合は、レコードを返す際にfetch_recordsメソッド内でそのフィールドをdatetimeオブジェクトに変換します。
- API呼び出しで受け取った、プラグインがサポートするすべてのフィールドの値を含むレコードを返すようにしてください。レコード内のスコアのようなフィールドは、SOCユーザーがデータを分析する際に、より理解しやすいものとなる。SOCアナリストにとってより詳細な情報が得られるよう、Netskopeの正規化スコアフィールドを必ずマッピングしてください。Netskopeの正規化スコアのフィールドは整数である必要があります。
- validateメソッドに渡されるパラメータを適切に検証し、すべてのパラメータに対して適切なヘルプテキストを提供します。
- プラグインディレクトリ名(例:sample_plugin)がmanifest.jsonと一致していることを確認してください。ID。
- API呼び出しを行う際には、ユーザーエージェントをヘッダーに追加する必要があります。ユーザーエージェントのフォーマット: Netskope -ce-<ce_version>-<module>-<plugin_name>-<plugin_version> 。
プラグインの作成
このセクションでは、プラグインをゼロから作成するプロセスについて説明します。
サンプルプラグインは NetskopeOSSの公開Githubリポジトリ またはCloud Exchangeナレッジベース(こちら)からダウンロードできます: https://support.netskope.com/hc/en-us/articles/360052128734-Cloud-Threat-Exchange。
開発環境のセットアップ
Python
当システムはPython3(バージョン3.11以降)を使用しています。開発環境にPython3がインストールされていることを確認してください。Pytest は単体テストを実行するために使います。
含まれるPythonライブラリ
これらの Python ライブラリは、 Netskope Cloud Exchangeプラットフォームに含まれています。
| 図書館名 | バージョン |
|---|---|
| aiofiles | 22.1.0 |
| amqp | 5.1.1 |
| annotated-types | 0.5.0 |
| anyio | 3.6.2 |
| asgiref | 3.6.0 |
| attrs | 22.2.0 |
| azure-core | 1.26.2 |
| azure-storage-blob | 12.14.1 |
| bcrypt | 4.0.1 |
| billiard | 4.2.0 |
| boto3 | 1.26.51 |
| botocore | 1.29.51 |
| cabby | 0.1.23 |
| cachetools | 5.2.1 |
| celery | 5.3.6 |
| certifi | 2024.7.4 |
| cffi | 1.15.1 |
| chardet | 5.1.0 |
| charset-normalizer | 3.0.1 |
| click | 8.1.3 |
| click-didyoumean | 0.3.0 |
| click-plugins | 1.1.1 |
| click-repl | 0.2.0 |
| colorama | 0.4.6 |
| colorlog | 6.7.0 |
| cryptography | 42.0.5 |
| cybox | 2.1.0.21 |
| Cython | 0.29.37 |
| defusedxml | 0.7.1 |
| dnspython | 2.6.1 |
| docker | 6.0.1 |
| email_validator | 2.2.0 |
| fastapi | 0.111.0 |
| fastapi-cli | 0.0.5 |
| furl | 2.1.3 |
| google-api-core | 2.11.0 |
| google-auth | 2.16.0 |
| google-cloud-core | 2.3.2 |
| google-cloud-pubsub | 2.13.12 |
| google-cloud-pubsublite | 1.6.0 |
| google-cloud-storage | 2.7.0 |
| google-crc32c | 1.5.0 |
| google-resumable-media | 2.4.0 |
| googleapis-common-protos | 1.58.0 |
| grpc-google-iam-v1 | 0.12.6 |
| grpcio | 1.62.2 |
| grpcio-status | 1.51.1 |
| gunicorn | 22.0.0 |
| h11 | 0.14.0 |
| httpcore | 1.0.5 |
| httptools | 0.6.1 |
| httpx | 0.27.0 |
| hvac | 1.1.0 |
| idna | 3.7 |
| importlib-metadata | 6.0.0 |
| isodate | 0.6.1 |
| Jinja2 | 3.1.4 |
| jmespath | 1.0.1 |
| jsonpath | 0.82.2 |
| jsonschema | 4.17.3 |
| kombu | 5.3.7 |
| libtaxii | 1.1.119 |
| lxml | 5.3.0 |
| markdown-it-py | 3.0.0 |
| MarkupSafe | 2.1.2 |
| mdurl | 0.1.2 |
| memory-profiler | 0.61.0 |
| mixbox | 1.0.5 |
| mongoengine | 0.25.0 |
| mongoquery | 1.4.2 |
| more-itertools | 9.0.0 |
| msrest | 0.7.1 |
| multidict | 6.0.4 |
| mypy-extensions | 0.4.3 |
| netskopesdk | 0.0.38 |
| numpy | 1.26.2 |
| oauthlib | 3.2.2 |
| onelogin | 3.1.0 |
| ordered-set | 4.1.0 |
| orderedmultidict | 1.0.1 |
| orjson | 3.10.7 |
| overrides | 6.5.0 |
| packaging | 23.0 |
| pandas | 2.1.3 |
| passlib | 1.7.4 |
| prompt-toolkit | 3.0.36 |
| proto-plus | 1.22.2 |
| protobuf | 4.21.12 |
| psutil | 5.9.4 |
| py-expression-eval | 0.3.14 |
| pyasn1 | 0.4.8 |
| pyasn1-modules | 0.2.8 |
| pycparser | 2.21 |
| pydantic | 2.4.0 |
| pydantic_core | 2.10.0 |
| Pygments | 2.18.0 |
| pyhcl | 0.4.4 |
| PyJWT | 2.6.0 |
| pymongo | 4.6.3 |
| Pympler | 1.0.1 |
| pyparsing | 3.0.9 |
| pyrsistent | 0.19.3 |
| python-dateutil | 2.8.2 |
| python-dotenv | 1.0.1 |
| python-multipart | 0.0.7 |
| python3-saml | 1.15.0 |
| pytz | 2022.7.1 |
| PyYAML | 6.0.1 |
| requests | 2.32.0 |
| requests-oauthlib | 1.3.1 |
| rich | 13.7.1 |
| rsa | 4.9 |
| s3transfer | 0.6.0 |
| shellingham | 1.5.4 |
| six | 1.16.0 |
| sniffio | 1.3.0 |
| starlette | 0.37.2 |
| stix | 1.2.0.11 |
| taxii2-client | 2.3.0 |
| typer | 0.12.3 |
| typing-inspect | 0.8.0 |
| typing-utils | 0.1.0 |
| typing_extensions | 4.12.2 |
| tzdata | 2023.3 |
| ujson | 5.10.0 |
| urllib3 | 1.26.19 |
| uvicorn | 0.23.1 |
| uvloop | 0.19.0 |
| vine | 5.1.0 |
| watchfiles | 0.23.0 |
| wcwidth | 0.2.6 |
| weakrefmethod | 1.0.3 |
| websocket-client | 1.4.2 |
| websockets | 12.0 |
| Werkzeug | 3.0.3 |
| wheel | 0.44.0 |
| xmlsec | 1.3.14 |
| zipp | 3.19.1 |
カスタムプラグインライブラリを含む
Netskopeは、プラグインが必要とするサードパーティ製のPythonライブラリはすべて、プラグインパッケージ自体に同梱することを推奨しています。このバンドル化を実現するには、pipインストーラーを使用します。ディレクトリを入力として受け取るスイッチが用意されています。 ディレクトリが指定されている場合、pipはそのディレクトリにパッケージをインストールします。
例えば、このコマンドは「cowsay」パッケージを「lib」ディレクトリにインストールします。
> pip install cowsay --target ./lib
これに関する公式ドキュメントについては、 https://pip.pypa.io/en/stable/reference/pip_install/#cmdoption-tを参照してください。
上記のlibフォルダからモジュールをインポートするには、プラグインパッケージの__init__.pyファイルでカスタムモジュールのPythonシステムパスを設定する必要があります。
__init__.py
import sys from pathlib import Path src_path = Path(__file__).resolve() src_dir = src_path.parent sys.path.insert(0, str(src_dir / "lib"))
カスタムライブラリのシステムパスを設定した後、以下に示すようにライブラリをインポートします。
import cowsay
IDE
推奨されるIDEはPyCharmまたはVisual Studio Codeです。プラグインコードの一貫性と可読性を高めるために、flake8リンティングとblackフォーマッターをインストールしてください。Flake8 Blackを参照してください。
プラグインディレクトリ構造
このセクションでは、リスクエクスチェンジプラグインの典型的なディレクトリ構造について説明します。
/sample_plugin/ ├── __init__.py ├── Changelog.md ├── icon.png ├── main.py └── manifest.json
- __init__.py:CREコードでは、すべてのプラグインパッケージはPythonモジュールとして扱われます。すべてのプラグインパッケージに空の「__init__.py」が含まれていることを確認してください。ファイル。プラグインにカスタムモジュールが必要な場合、プラグインのカスタムライブラリのシステムパスを設定するコードを追加します。詳細については、上記の__init__.pyのセクションを参照してください。
- CHANGELOG.md:このファイルにはプラグインの更新に関する詳細が含まれており、追加、変更、修正などの適切なタグと、ユーザーにとって分かりやすいメッセージを追加して更新する必要があります。
- icon.png: プラグインのアイコンロゴ。これは、UI 上のプラグインのチクレットと設定カードに表示されます。ロゴには透明なバックグランドがあり、推奨サイズは 300*50 ピクセルまたは同様のアスペクト比で、サイズは 10kb 未満である必要があります。
- main.py:このPythonファイルには、レコードの取得、レコードの更新、アクションの実行、検証、および検証アクションのメソッドの具体的な実装を含むPluginクラスが含まれています。
- manifest.json:プラグインパッケージのマニフェストファイル。設定可能なすべてのパラメータとそのデータ型に関する情報が含まれています。このファイルには、プラグインの統合に関する詳細情報も記載されています。
ここに記載されているファイルは、プラグインの統合に必須ですが、開発者は特定の統合要件に基づいて他のファイルを追加することもできます。
以下のファイルは必須ではありませんが、プラグインフォルダに追加することをお勧めします。
- /utils/constants.py:このファイルには、プラグイン実装におけるすべての定数が含まれています。 プラグイン実装におけるすべての定数が含まれています。 必要なファイルにpyファイルから定数をインポートします。
- utils/helper.py:このファイルには、api_helper、add user agent、およびプラグインで必要とされるその他のヘルパーメソッドの実装を含むプラグインヘルパークラスが含まれています。
ヘルパーファイルの参照先を確認してください: https://github.com/netskopeoss/ta_cloud_exchange_plugins/blob/main/crowdstrike_ztre/utils/helper.py
注記
プラグインディレクトリ名(sample_plugin)がmanifest.jsonと一致していることを確認してください。IDフィールド。
Changelog.md
これはプラグインの更新に関する詳細情報を含むファイルであり、追加、変更、修正などの適切なタグと、ユーザーにとって分かりやすい適切なメッセージで更新する必要があります。
- 追加: 新しい機能が追加されたときに使用します。
- 修正済み: バグやエラーが修正されたときに使用します。
- 変更: プラグインの既存の実装に変更があった場合に更新します。
- 削除済み: プラグインからパラメータまたは機能が削除された場合
変更履歴のサンプル.md
# 1.1.0 ## Removed - Removed priority from the syslog message for the logs that are not transformed in CEF. # 1.0.1 ## Changed - Changed error logs to warning if a single field is skipped. ## Fixed - Fixed JSON format of raw data. # 1.0.0 ## Added - Initial release.
Manifest.json
これは、プラグインに関連するメタ情報を格納する JSON ファイルです。このファイルは、Risk Exchange モジュールによって読み込まれ、UI にプラグインを表示するとともに、Risk Exchange モジュールがプラグインに関する詳細情報(必要な構成パラメータ、プラグイン ID、プラグイン名など)を把握できるようにします。
- すべてのプラグインには、Risk Exchangeがプラグインオブジェクトを適切にインスタンス化できるように、必要な情報を含むこのファイルが含まれている必要があります。
- マニフェスト.json の一般的なパラメーターには次のものがあります。
- name: (文字列) プラグインの名前。(必須)
- Netskope :(ブール値) です プラグインがNetskopeプラグインかどうかを確認します(例: Netskopeプラグインの場合はTrue、それ以外の場合はFalse)
- デスクリプション: (文字列) プラグインのデスクリプション。 プラグインの機能と使用手順について説明した詳細なデスクリプションを提供します。 ユーザー/デバイスの詳細情報とスコアを取得し、各種アクションを実行します。プラグインがサードパーティプラットフォームからのスコア取得をサポートしている場合は、Netskope正規化スコアの計算式も追加してください。このデスク リプションは、プラグイン設定カードに表示されます。 (必須)こちらを確認してください( https://github.com/netskopeoss/ta_cloud_exchange_plugins/blob/main/crowdstrike_ztre/manifest.json )デスクリプションの参考にしてください。
- ID: (文字列) プラグインパッケージのID。Cloud Exchangeにインストールされているすべてのプラグインで、一意であることを確認してください。IDはプラグインパッケージのディレクトリ名と一致する必要があります。(必須)
- version: (文字列) プラグインのバージョン。MAJOR.MINOR.PATCH の使用 (例:1.0.1)バージョン管理方式を推奨しますが、特に制限はありません。(必須)
- minimum_version: (string) このプラグインを実行するために必要な最小の Cloud Exchange バージョン。5.1.0Risk Exchangeプラグイン用。(必須)
- module: (string) CE Module name for the plugin, like CRE, CTO, CTE, CLS. (Required)
- 設定: (配列) プラグインに必要なすべてのパラメーターに関する情報 (名前、タイプ、ID など) を含む JSON オブジェクトの配列。ネストされた JSON オブジェクトによくあるパラメーターについては、以下で説明します。
- ラベル:パラメータの名前。これはプラグインの設定ページに表示されます。(必須)
- key: プラグイン設定が使用される Python dict オブジェクト内のキーとして使用される一意のパラメーター キー。 (必須)
- type: Value type of the parameter. Allowed values are text, password, number, choice, and multichoice. (Required) Refer to the Plugin Configuration Parameter Types below for more details.
- default: The default value for this parameter. This value will appear on the plugin configuration page on the Risk Exchange UI. Supported data-types are text, number, and list (for multichoice type). (Required)
- mandatory: このパラメータが必須かどうかを示すブール値。パラメータが必須の場合、リスク取引所のUIでは、そのパラメータに空の値を指定することはできません。許容される値はtrueとfalseです。(必須)
- デスクリプション: パラメータと期待値に関する詳細を提供する、パラメータのヘルプ テキスト レベルのデスクリプション。 この文字列は、プラグインの設定ページにヘルプテキストとして表示されます。(必須)
- 選択肢:キーと値をJSONキーとして含むJSONオブジェクトのリスト。このパラメータは、タイプ: choice および multichoiceでのみサポートされています。
Plugin Configuration Parameter types
プラグインのmanifest.jsonファイルのconfigurationセクションに、必要なプラグイン設定パラメータがすべて記載されていることを確認してください。
Password Parameter
このパラメータは、API エンドポイントでの認証のためのシークレット/パスワードを保存するために使用されます。 パスワードを型とするパラメータは、プラグイン設定ページにパスワード入力欄が表示され、プラットフォームによって難読化および暗号化されます。
サンプルJSON
"configuration": [
{
"label": "API Token",
"key": "api_token",
"type": "password",
"mandatory": true,
"default": "",
"description": "API Token for the platform."
},
]
プラグイン設定ビュー

Text Parameter
このパラメータは、ベースURL、ユーザー名などの文字列情報を格納します。 このパラメータは、プラグイン設定ページに通常のテキスト入力欄として表示されます。
サンプルJSON
"configuration": [
{
"label": "Tenant Name",
"key": "tenant_name",
"type": "text",
"mandatory": true,
"default": "",
"description": "Tenant Name of the platform."
},
]
プラグイン設定ビュー

Number Parameter
このパラメータは数値/浮動小数点値を保存するために使用されます。 このパラメータは、プラグイン設定ページに数値入力ボックスとして表示されます。(ハッシュリストは脅威情報交換モジュールにあります。)
"configuration": [
{
"label": "Maximum File hash list size in MB.",
"key": "max_size",
"type": "number"
"mandatory": true,
"default": 12,
"description": "File hash list size in MB."
},
]
プラグイン設定ビュー

Choice Parameter
このパラメータは、列挙パラメータの値を格納するために使用されます。 このパラメータは、プラグイン設定ページにドロップダウンボックスとして表示されます。
サンプルJSON
"configuration": [
{
"label": "Base URL",
"key": "base_url",
"type": "choice",
"choices": [
{
"key": "Commercial cloud (api.crowdstrike.com)",
"value": "https://api.crowdstrike.com"
},
{
"key": "US 2 (api.us-2.crowdstrike.com)",
"value": "https://api.us-2.crowdstrike.com"
},
{
"key": "Falcon on GovCloud (api.laggar.gcw.crowdstrike.com)",
"value": "https://api.laggar.gcw.crowdstrike.com"
},
{
"key": "EU cloud (api.eu-1.crowdstrike.com)",
"value": "https://api.eu-1.crowdstrike.com"
}
],
"default": "https://api.crowdstrike.com",
"mandatory": true,
"description": "API Base URL."
},
]
プラグイン設定ビュー
入力を選択した後:

Multichoice Parameter
このパラメータは、複数の選択肢の値を保存するために使用します。 このパラメータは、プラグイン設定ページにドロップダウンボックスとして表示され、複数の値を選択できるようになります。(深刻度は脅威情報交換モジュールに記載されています。)
サンプルJSON
"configuration": [
{
"label": "Severity",
"key": "severity",
"type": "multichoice",
"choices": [
{
"key": "Unknown",
"value": "unknown"
},
{
"key": "Low",
"value": "low"
},
{
"key": "Medium",
"value": "medium"
},
{
"key": "High",
"value": "high"
},
{
"key": "Critical",
"value": "critical"
}
],
"default": [
"critical",
"high",
"medium",
"low",
"unknown"
],
"mandatory": false,
"description": "Only indicators with matching severity will be saved."
}
]
プラグイン設定ビュー

Toggle Parameter
このパラメータはブール値を格納します。トグル有効はTrue、トグル無効はFalseです。
システムプロキシ(「プロキシ」)を使う: Use system proxy configured in Settings. (Default: False)
プラグイン設定ビュー

注記
このパラメータはCoreによって提供されるものであり、プラグインのmanifest.jsonファイルから追加することはできません。
Main.py
このPythonファイルには、プラグインの中核となる実装が含まれています。
標準輸入
from netskope.integrations.crev2.plugin_base import ( PluginBase, ValidationResult, Entity, EntityField, EntityFieldType ) from netskope.integrations.crev2.models import ( Action, ActionWithoutParams )
PluginBase変数
PluginBase は、プラグインのライフサイクル メソッド中に使用できる変数へのアクセスを提供します。 以下は変数の一覧です。
| 変数名 | Usage | デスクリプション |
|---|---|---|
| self.logger | self.logger.error(“メッセージ”) self.logger.warn(“メッセージ”) self.logger.info(“メッセージ”) | コアによって提供されるロガーハンドル。このオブジェクトを使用して重要なイベントを記録します。 ログはCloud Exchange監査ログに表示されます。 ロガーオブジェクトのドキュメントを参照してください。 |
| self.configuration | self.configuration.get()<attribute-key-name> | プラグインインスタンスの設定オブジェクトのJSON表現。これを使用して、認証クレデンシャル、サーバーの詳細などの構成属性にアクセスします。manifest.json に記載されている属性のキー名を使用します。 |
| self.last_run_at | self.last_run_at: の場合self.last_run_at.timestamp() この形式は、最後の実行時間をエポック形式に変換するためのものです。 | プラグインのプルメソッドが最後に正常に実行された時刻のタイムスタンプを提供します。Cloud Exchange コアは、pull() の実行が成功するたびにチェックポイント時刻を保持します。初回実行時の値はNoneになります。オブジェクトのデータ型はdatetimeです。 |
| self.notifier (optional) | self.notifier.info(“message”) self.notifier.warn(“message”) self.notifier.error(“message”) | このオブジェクトは、リスクエクスチェンジコアの通知機能へのハンドルを提供します。このオブジェクトを使用して、プラットフォームに通知をプッシュします。 通知はリスクエクスチェンジのユーザーインターフェースに表示されます。ユーザーが読んで必要な行動を取れるよう、メッセージ は要約された情報が含まれていることを確認してください。 Netskopeプラグインの通知機能。push()メソッドが製品の8MB制限を超えた場合に通知します。 |
| self.proxy | requests.get(url=url,プロキシ=self.proxy) | システムのプロキシ設定が設定されている場合はそのハンドル、設定されていない場合は {}。 |
| self.ssl_validation | requests.get(url=url,verify=self.ssl_validation) | REST API呼び出しに対してSSL検証が強制されるかどうかを示すブール値。 |
プラグインクラス
- プラグインクラスはPluginBaseクラスを継承する必要があります。PluginBase クラスはNetskope .integrations.crev2.plugin_baseで定義されています。
- Make sure the Plugin class provides implementation for the get_entities, fetch_records, update_records, validate, get_actions, get_action_params, validate_action, and execute_action.
- プラグインクラスには、サードパーティAPIとの接続および認証を確立するために必要なすべてのパラメータが含まれます。
- プラグインの機能開発においては、ページネーションを常に考慮に入れるべきです。
"""Sample plugin implementation.
This is a sample implementation of the base PluginBase class. Which explains the concrete implementation of the base class.
"""
from netskope.integrations.crev2.models import (
Action,
ActionWithoutParams
)
from netskope.integrations.crev2.plugin_base import (
PluginBase,
ValidationResult,
Entity,
EntityField,
EntityFieldType
)
from .utils.helper import SamplePluginException, SamplePluginHelper
class SamplePlugin(PluginBase):
"""SamplePlugin class having concrete implementation for fetching information and performing actions.
This class is responsible for implementing pull, perform actions and validate methods with proper return types, so that it's lifecycle execution can be scheduled by the CRE core engine.
"""
def __init__(
self,
name,
*args,
**kwargs,
):
"""Init method.
Args:
name (str): Configuration name.
"""
super().__init__(
name,
*args,
**kwargs,
)
self.plugin_name, self.plugin_version = self._get_plugin_info()
self.log_prefix = f"{MODULE_NAME} {self.plugin_name} [{name}]"
self.sample_plugin_helper = SamplePluginHelper(
logger=self.logger,
log_prefix=self.log_prefix,
plugin_name=self.plugin_name,
plugin_version=self.plugin_version,
configuration=self.configuration,
)
def _get_plugin_info(self) -> tuple:
"""Get plugin name and version from metadata.
Returns:
tuple: Tuple of plugin's name and version fetched from metadata.
"""
try:
metadata_json = SamplePlugin.metadata
plugin_name = metadata_json.get("name", PLATFORM_NAME)
plugin_version = metadata_json.get("version", PLUGIN_VERSION)
return (plugin_name, plugin_version)
except Exception as exp:
self.logger.error(
message=(
"{} {}: Error occurred while"
" getting plugin details. Error: {}".format(
MODULE_NAME, PLATFORM_NAME, exp
)
),
details=traceback.format_exc(),
)
return (PLATFORM_NAME, PLUGIN_VERSION)
def validate()
引数:
設定 (dict) : プラグイン設定パラメータをすべて含む辞書オブジェクト。
戻り値:
ValidationResult : 成功フラグとメッセージを含む ValidationResult オブジェクト。
これはPluginBaseクラスの抽象メソッドです。
- このメソッドは、プラグイン構成を作成する際に渡されたプラグイン構成および認証パラメータを検証します。
- このメソッドは、新しい設定が作成または更新された場合にのみ呼び出されます。
- 必須パラメータがすべて適切なデータ型で渡されていることを検証します。
- 認証パラメータと API エンドポイントを検証して、プラグインのライフサイクルがスムーズに実行されるようにします。
- 検証の成功または失敗を示す成功フラグと、検証失敗の理由を含む検証メッセージを含むValidationResultオブジェクト( ValidationResultデータモデルを参照)を返します。
def validate(self, configuration):
"""Validate the Plugin configuration parameters.
Validation for all the parameters mentioned in the manifest.json
for the existence and data type. Method returns the
netskope.integrations.crev2.plugin_base.ValidationResult object
with success = True in the case of successful validation and
success = False and an error message in the case of failure.
Args:
configuration (dict): Dict object having all the Plugin configuration parameters.
Returns:
netskope.integrations.crev2.plugin_base.ValidationResult:
ValidationResult object with success flag and message.
"""
# Validate Base URL
instance_url = configuration.get("base_url", "").strip().strip("/")
if not instance_url:
err_msg = "Base URL is required configuration parameter."
self.logger.error(
f"{self.log_prefix}: Validation error occurred. {err_msg}"
)
return ValidationResult(success=False, message=err_msg)
elif not (isinstance(instance_url, str) and self._validate_url(instance_url)):
err_msg = "Invalid Base URL provided in configuration parameters."
self.logger.error(
f"{self.log_prefix}: Validation error occurred. {err_msg}"
)
return ValidationResult(success=False, message=err_msg)
# Validate client_id
client_id = configuration.get("client_id", "").strip()
if not client_id:
err_msg = "Client ID is a required field."
self.logger.error(f"{{self.log_prefix}}: Validation error occurred. Error: {err_msg}")
return ValidationResult(success=False, message=err_msg,)
elif not isinstance(client_id, str):
err_msg = "Invalid Client ID value provided."
self.logger.error(f"{{self.log_prefix}}: {err_msg}")
return ValidationResult(success=False, message=err_msg)
return ValidationResult(
success=True,
message="Validation successful for Sample Plugin."
)
def _validate_url(self, url: str) -> bool:
"""Validate the given URL.
Args:
url (str): URL to validate.
Returns:
bool: True if URL is valid else False.
"""
parsed_url = urlparse(url.strip())
return parsed_url.scheme and parsed_url.netloc
def get_entities()
引数:
なし
戻り値:
List[Entity] : プラグインでサポートされているエンティティ、フィールド、および型を持つエンティティクラスのリスト。
これはPluginBaseクラスの抽象メソッドです。
- このメソッドは、プラグインでサポートされているエンティティ、フィールド、および型を含むエンティティクラスのリストを返す必要があります。
- プラグインがどのエンティティもサポートしていない場合は、空のリストを返します。
def get_entities(self) -> list[Entity]:
"""Get available entities."""
return [
Entity(
name="Users",
fields=[
EntityField(name="User Email", type=EntityFieldType.STRING, required=True),
EntityField(name="Netskope Normalized Score", type=EntityFieldType.NUMBER),
],
),
Entity(
name="Applications",
fields=[
EntityField(name="Application ID", type=EntityFieldType.STRING, required=True),
EntityField(name="Tags", type=EntityFieldType.LIST),
],
)
]
def fetch_records()
引数:
エンティティ (str) : 取得するエンティティ。
戻り値:
リスト: プラットフォームに保存されるレコードのリスト。
これはPluginBaseクラスの抽象メソッドです。
- このメソッドは、サードパーティ API エンドポイントからレコード () を取得するロジックを実装します。 このメソッドは定期的に呼び出されます。
- self.proxyを呼び出して、CE プラットフォームによって渡されたプロキシ構成を使用します。 これは、Pythonの辞書オブジェクトを返します。 requestsモジュールで直接使用できます。
- API認証のすべての設定パラメータは、 self.configuration .を呼び出すことでPython辞書が受け取る形で渡されます。
- すべてのログは、適切なログレベル(info、warn、error)を指定して、 self.loggerオブジェクトによって記録できます。このオブジェクトはログをMongoDBに記録し、API呼び出しを介してアクセスできます。
- Use self.ssl_validation bool to enable/disable validation of the SSL server certificate.
- プラグインが複数のエンティティをサポートしている場合は、エンティティに応じてプル処理を行います。
- 同じAPIレスポンスにリスクの詳細情報が含まれている場合は、このメソッドでリスク情報を取得します。
- プラグインエンティティフィールドにマッピングされたAPIエンドポイントから受信したデータを含む辞書のリストを返します。
- 失敗した場合は、適切なメッセージとともに、適切な種類のエラーまたは例外を発生させてください。
- 必ず すべてのAPIリクエストのためのAPIヘルパー。 参照する
- APIエンドポイントがサポートする最大ペイロードサイズを超えた場合は必ず対処してください。 このケースに対処する方法は複数考えられます。
- API エンドポイントがペイロード サイズが固定された複数のリクエストをサポートしている場合は、データをチャンクで送信します。 この概念はページネーションと呼ばれます。
def fetch_records(self, entity: str):
"""Fetches entity records from a third party API.
Implement the logic of fetching data based on entity from third party apis
and return the list of dictionary objects containing plugin supported entity
fields and their values on a successful fetch otherwise raises an exception.
Returns:
List[{}]: List of dictionary objects of entity data
fetched from the third party platform.
"""
# Load all the configured plugin parameters as python dict objects.
# Use the key name provided in the manifest.json file for the
# configuration parameters to get the value of that particular parameter.
# See api_helper for API requests method to check
# how to use proxy dict and ssl_validation flag.
# check entity type and fetch records accordingly
# if plugin supports multiple entity types
headers = {
"Authorization": "<>",
}
if entity == "Users":
resp_json = self.sample_plugin_helper.api_helper(
url="www.example.com/users",
method="GET",
headers=headers,
proxies=self.proxy,
verify=self.ssl_validation,
logger_msg=f"fetching {entity_name} from the platform",
)
records = resp_json.get("value", [])
elif entity == "Applications":
resp_json = self.sample_plugin_helper.api_helper(
url="www.example.com/applications",
method="GET",
headers=headers,
proxies=self.proxy,
verify=self.ssl_validation,
logger_msg=f"fetching {entity_name} from the platform",
)
records = resp_json.get("value", [])
# Get the logger object for logging purposes. This logger object logs
# all the logs to mongodb under the core database logs collection.
# Log timestamp is automatically recorded by the logger library.
# Supported logging levels are info, warn and error.
self.logger.info(f"{self.log_prefix}: Successfully fetched {
len(records)}{entity} from the platform.")
return records
def update_records()
Arguments:
entity (str): Entity to be updated.
records (list): Records to be updated.
Returns:
List: List of updated records.
This is an abstract method of PluginBase Class.
- このメソッドは、サードパーティ API エンドポイントから保存されたレコードを更新するロジックを実装します。 このメソッドは定期的に呼び出されます。
- 取得したレコードのサードパーティAPIからフィールド値を更新します。 この方法では、エンティティに固有かつ必須のフィールドを除き、すべてのフィールドを更新する必要があります。
- update_recordsメソッドで Netskope 正規化スコアを計算し、fetch_record メソッドでリスク情報が取得された場合は、レコード辞書にフィールドを追加します。スコアは必ず0~1000の整数にマッピングしてください。
- どのフィールドに対してもNone値を返さないようにしてください。
- self.proxyを呼び出して、CE プラットフォームから渡されたプロキシ構成を使用します。 これは、Pythonの辞書オブジェクトを返します。 requestsモジュールで直接使用できます。
- API認証のすべての設定パラメータは、 self.configurationを呼び出すことでPython辞書が受け取る形で渡されます。
- すべてのログは、適切なログレベル(info、warn、error)を指定して、 self.loggerオブジェクトによって記録できます。このオブジェクトはログをMongoDBに記録し、API呼び出しを介してアクセスできます。
- Use self.ssl_validation bool to enable/disable validation of the SSL server certificate.
- API エンドポイントから受信したデータを含むスコアのリストを返します。このデータは Record オブジェクトに保存されます。 注:このリストにはレコードオブジェクトが含まれます。
- 失敗した場合は、適切なメッセージとともに、適切な種類のエラーまたは例外を発生させる。
- APIエンドポイントがサポートする最大ペイロードサイズを超えた場合は必ず対処してください。 このケースに対処する方法は複数考えられます。
- API エンドポイントがペイロード サイズが固定された複数のリクエストをサポートしている場合は、データをチャンクで送信します。 この概念はページネーションとも呼ばれます。
- レコードを更新する前に、まずプラグインエンティティの一意/必須フィールドが取得されたレコードに存在することを確認し、リストを作成します。例:
if entity == "Users":
user_email = []
for record in records:
if record.get("User Email"):
user_email.append(record.get("User Email"))
Note:
リスクの詳細が利用可能な場合は、正規化されたスコアをfetch_recordsではなくupdate_recordメソッドで計算するようにしてください。
def update_records(self, entity: str, records: list[dict]):
"""Update entity records from a third party API.
Implement the logic of fetching updated data based on entity
from third party apis and return the list of updated values
for all fetched records dictionary containing plugin supported entity
fields and Netskope Normalize Score if risk information available on
a successful fetch otherwise raises an exception.
Returns:
List[{}]: List of records with updated values of entity data
fetched from the third party platform.
"""
# Load all the configured plugin parameters as python dict objects.
# Use the key name provided in the manifest.json file for the
# configuration parameters to get the value of that particular parameter.
# See api_helper for API requests method to check
# how to use proxy dict and ssl_validation flag.
# check entity type and fetch records accordingly
# if plugin supports multiple entity types
headers = {
"Authorization": "<>",
}
updated_records = {}
if entity == "Users":
user_email = []
for record in records:
if record.get("User Email"):
user_email.append(record.get("User Email"))
resp_json = self.sample_plugin_helper.api_helper(
url="www.example.com/users",
method="GET",
headers=headers,
proxies=self.proxy,
verify=self.ssl_validation,
logger_msg=f"updating {entity_name} from the platform",
)
updated_records = resp_json.get("value", [])
for record in records:
user_email = record.get("User Email")
if user_email and user_email in updated_records:
record.update(updated_records[user_email])
count += 1
elif entity == "Applications":
app_id = []
for record in records:
if app_id.get("Application ID"):
app_id.append(record.get("Application ID"))
resp_json = self.sample_plugin_helper.api_helper(
url="www.example.com/applications",
method="GET",
headers=headers,
proxies=self.proxy,
verify=self.ssl_validation,
logger_msg=f"updating {entity_name} from the platform",
)
updated_records = resp_json.get("value", [])
for record in records:
app_id = record.get("Application ID")
if app_id and app_id in updated_records:
record.update(updated_records[app_id])
count += 1
self.logger.info(
f"{self.log_prefix}: Successfully updated {count} "
f"{entity} from the platform."
)
return records
def get_actions()
引数:
なし
戻り値:
List[ActionWithoutParams] : ラベルと値が定義されている ActionWithoutParams のリスト。
これはPluginBaseクラスの抽象メソッドです。
- このメソッドは、サポートされているすべてのアクションのリストを返す必要があります。
- ActionWithoutParamsクラスにサポートされているすべてのアクションを追加し、ActionWithoutParams クラスのオブジェクトのリストを返します。
- If the plugin does not support any action, No action should be implemented.
def get_actions(self):
"""Get available actions.
Returns:
List[ActionWithoutParams]: List of ActionWithoutParams objects
that are supported by the plugin.
"""
return [
ActionWithoutParams(label="Add to group", value="add"),
ActionWithoutParams(label="Remove from group", value="remove"),
ActionWithoutParams(label="No action", value="generate"),
]
def get_action_params():
Arguments:
action (Action): The type of action
Returns:
List: Returns a list of selected action parameters.
This is an abstract method of PluginBase Class.
- このメソッドは、ドロップダウンリストからターゲットが選択されたときにUIに表示されるフィールドのリストを返す必要があります。
- このメソッドは、ユーザーがいずれかのアクションを選択した後に呼び出す必要があります。
- 選択されたアクションにパラメータが必要な場合は、辞書のリスト(各辞書は設定可能な入力)を返し、そうでない場合は空のリストを返します。プラグイン設定パラメータの種類を確認して、フィールドがどのように定義されているかを確認してください。
- プラグインがどのアクションもサポートしていない場合、get_action_fields メソッドではアクションを実装せず、空のリストを返す必要があります。
def get_action_params(self, action: Action):
"""Get fields required for an action.
Args:
action (Action): Action object which is selected as Target.
Return:
List[Dict]: List of configurable fields based on selected action.
"""
if action.value in ["generate"]:
return []
if action.value == "add":
return [
{
"label": "Email",
"key": "email",
"type": "text",
"default": "",
"mandatory": True,
"description": "Email ID of the user to perform the action on.",
},
{
"label": "Group Name",
"key": "group_name",
"type": "choice",
"choice": [{key: "name", value: "id"}, ...],
"default": "",
"mandatory": True,
"description": "Name of group."
}
]
else:
return []
def validate_action():
引数:
action (Action):アクションパラメータを持つアクションのタイプ
戻り値:
ValidationResult : 成功フラグとメッセージを含む ValidationResult オブジェクト。
これはPluginBaseクラスの抽象メソッドです。
- このメソッドは、アクション構成を作成する際に渡されるアクションパラメータを検証します。
- このメソッドは、新しいアクション設定が作成または更新された場合にのみ呼び出されます。
- プラグイン設定の検証メソッドでは、空欄の検証と型チェックの検証を別々に行う必要があります。
- 必須パラメータがすべて適切なデータ型で渡されていることを検証します。
- 検証中は、 APIトークンとパスワードフィールドを除く、URL、ユーザー名、テキストタイプなどのアクションパラメータに対してstrip()を実行します。
- 検証の成功または失敗を示す成功フラグと、検証失敗の理由を含む検証メッセージを含むValidationResultオブジェクト( ValidationResultデータモデルを参照)を返します。
- プラグインにアクションがない場合は、成功フラグ付きのValidationResultオブジェクトを返し、そうでない場合は検証をチェックします。
def validate_action(self, action: Action):
"""Validate Action Parameters.
Args:
action (Action): Action object having all the configurable parameters.
Return:
netskope.integrations.crev2.plugin_base.ValidationResult:
ValidationResult object with success flag and message.
"""
action_params = action.parameters
if action.value not in ["generate", "add", "remove"]:
err_msg = "Unsupported action provided."
self.logger.error(f"{self.log_prefix}: {err_msg}")
return ValidationResult(
success=False, message=err_msg
)
if action.value in ["generate"]:
return ValidationResult(
success=True, message="Validation successful."
)
email = action_params.get("email", "")
if not email:
err_msg = "Email is a required action parameter."
self.logger.error(f"{self.log_prefix}: {err_msg}")
return ValidationResult(success=False, message=err_msg)
elif not isinstance(email, str):
err_msg = "Invalid Email provided in action parameters."
self.logger.error(f"{self.log_prefix}: {err_msg}")
return ValidationResult(success=False, message=err_msg)
if "$" in email:
log_msg = (
"Email contains the Source Field"
" hence validation for this field will be performed"
" while executing the action."
)
self.logger.info(f"{self.log_prefix}: {log_msg}")
if action.value == "add":
if action_params.get("group_name") is None:
err_msg = "Group Name can not be an empty field."
self.logger.error(f"{self.log_prefix}: {err_msg}")
return ValidationResult(success=False, message=err_msg)
self.logger.debug(f"{self.log_prefix}: Validation successful.")
return ValidationResult(
success=True, message="Validation successful."
)
def execute_action():
引数:
action (アクション):アクションパラメータとともに実行する必要のあるアクション。
戻り値:
なし
これは PluginBase クラスの抽象メソッドです。
- このメソッドは、アクションを実行するためのロジックを実装します。
- メソッドがグループへの追加やグループからの削除といったアクションを実行することを確認してください。
- サードパーティAPI呼び出しを実行するには、ヘルパーメソッドを使用するのが望ましい。
Note:
「ユーザーをグループに追加」および「ユーザーをグループから削除」アクションの場合、プラットフォームがexecute_actionメソッドでユーザー検証用のAPIをサポートしている場合は、まずプラットフォーム上にユーザーが存在するかどうかを検証します。
def execute_action(self, action: Action):
"""Execute action on the record.
Calls _add_to_group helper methods in the case of add action.
Return when action is generate.
Args:
action (Action): Action object having all the configurable parameters.
"""
action_label = action.label
action_params = action.parameters
if action.value == "generate":
self.logger.debug(
f'{self.log_prefix}: Successfully executed "{action_label}" action.'
" Note: No processing will be done from plugin for "
f'the "{action_label}" action.'
)
return
email = action_params.get("email", "").strip()
if not email:
err_msg = (
"Email not found in the action parameters. "
f"Hence, skipping execution of '{action_label}' action."
)
self.logger.error(f"{self.log_prefix}: {err_msg}")
return
elif not isinstance(email, str):
err_msg = (
"Invalid Email found in the action parameters. "
f"Hence, skipping execution of '{action_label}' action."
)
self.logger.error(f"{self.log_prefix}: {err_msg}")
return
if action.value == "add":
group_id = action_params.get("group")
email = action_params.get("email", "").strip()
self.logger.info(f"{log_prefix}: Adding user with email '{email}' to group.")
self._add_to_group(email, group_id)
self.logger.info(f"{log_prefix}: Successfully added user with email '{email}' to group.")
データモデル
このセクションでは、データモデルとそのプロパティを一覧表示します。
Entity
- このクラスは、サポートされているプラグインエンティティを表します。
- 通常はユーザー、デバイス、またはアプリケーションが含まれますが、要件に応じて異なる場合があります。
- これは Risk Exchangeプラグインの設定ページで、プラグインがサポートするエンティティとフィールドに値を入力することになります。
データモデルの特性
| 名前 | タイプ | デスクリプション |
|---|---|---|
| name | string | UIに表示されるエンティティのラベルを表示します。 |
| フィールド | リスト[エンティティフィールド] | サポートされているエンティティフィールドのリストが含まれています |
from netskope.integrations.crev2.plugin_base import (
Entity,
EntityField,
EntityFieldType
)
def get_entities(self) -> list[Entity]:
"""Get available entities."""
return [
Entity(
name="Users",
fields=[
EntityField(name="User Email", type=EntityFieldType.STRING, required=True),
EntityField(name="Netskope Normalized Score", type=EntityFieldType.NUMBER),
],
)
]
EntityField
- このクラスは、エンティティのフィールドと、文字列、数値などのフィールドタイプを表します。
- それは get_entities メソッド内にあります。
- これは プラグイン設定ページにサポートされているフィールドを表示することです。
データモデルの特性
| 名前 | タイプ | デスクリプション |
|---|---|---|
| name | string | UIに表示されるフィールドのラベルを表示します。 |
| タイプ | EntityFieldType | Eumクラスでフィールドタイプを定義する |
| required | bool | true の場合、プラグイン設定でマッピングするフィールドが必要です。 |
EntityField(name="User Email", type=EntityFieldType.STRING, required=True)
EntityFieldType
- このクラスは、文字列、数値などのエンティティフィールドの型を表します。
- それは get_entities メソッドでフィールドタイプを定義します。
データモデルのプロパティ(列挙型)
| 名前 |
|---|
| STRINGNUMBER LIST DATETIME CALCULATED IPV4 IPV6 電子メール REFERENCE VALUE_MAP RANGE_MAP |
EntityField(name="Netskope Normalized Score", type=EntityFieldType.NUMBER)
アクション
- このクラスは、実行したいアクションを表します。
- 通常、生成、追加、削除、またはそれ以上のアクションを実行する必要があります。
- それは validate_action、execute_actions、およびget_action_paramsで行われます。
データモデルの特性
| 名前 | タイプ | デスクリプション |
|---|---|---|
| label | string | UIに表示されるアクションのラベルを表示する |
| value | string | それにアクセスするための鍵 |
| parameters | Dict | それぞれのプラグインに必要なアクションフィールドがすべて含まれます。 |
| generateAlerts | Bool | 条件が真の場合にCTOにアラートを生成する |
| performLater | Bool | 真の場合にアクションを同期する |
| requireApproval | Bool | アクションページからの承認が必要な場合、アクションは承認を必要とします。 |
ActionWithoutParams
- このクラスは、パラメータなしで実行したいアクションを表します。 パラメータなし。
- それは get_actions メソッド内にあります。
- これは サポートされているアクションをユーザーに表示します。
データモデルの特性
| 名前 | タイプ | デスクリプション |
|---|---|---|
| label | string | UIに表示されるアクションのラベルを表示する |
| value | string | プラグインコード内でアクセスするためのアクションキー |
from netskope.integrations.crev2.models import ActionWithoutParams
return [
ActionWithoutParams(label="Add to group", value="add"),
ActionWithoutParams(label="Remove from group", value="remove"),
ActionWithoutParams(label="No actions", value="generate"),
]
ValidationResult
- このクラスには、プラグインの新しい設定を作成する際にPluginオブジェクトに渡されるプラグイン設定パラメータに対する検証プロセスの結果が含まれています。
- validate メソッドに渡されるすべてのパラメータが、データ型と値に対して検証されていることを確認してください。
- validate メソッドは、検証操作の結果を示す成功フラグと、検証が失敗した場合に適切なエラーメッセージを含むメッセージフィールドを持つ、このクラスのオブジェクトを返します。 (成功した場合は、成功フラグがTrueのシンプルな成功メッセージが返されます。)
- Validate Action もこのクラスのオブジェクトを返すことに注意してください。
データモデルの特性
| 名前 | タイプ | デスクリプション |
|---|---|---|
| success | bool | 成功フラグは、検証操作が成功したか失敗したかの結果を示します。 |
| message | string | メッセージフィールドは失敗の場合のエラーを示します。 成功のケースでは、シンプルな成功メッセージで十分な場合もある。 |
from netskope.integrations.crev2.plugin_base import ValidationResult
ValidationResult(
success=True,
message="Validation Successful for Sample plugin"
)
ログ記録
Risk Exchangeは、ログ記録用のロガーオブジェクトへのハンドルを提供します。
- コード内でprint文を使用することは避けてください。
- このオブジェクトは、タイムスタンプフィールドを使用して中央のCloud Exchangeデータベースにログを記録します。 サポートされているログレベルは、info、debug、warn、errorです。
- API認証情報やその他の機密情報がログメッセージに漏洩しないようにしてください。
- Cloud Exchangeプラットフォームによって渡されるロガー オブジェクトを使用して、適切なログ メカニズムを実装してください。
- 運用チームがトラブルシューティングを行う際に役立つよう、十分なログ記録が行われるようにしてください。
- 通知やログに機密データが記録されたり、漏洩したりしないようにしてください。
- すべてのロガーのログ接頭辞フォーマットを参照してください。
- ログ メッセージは「 <module> <plugin_name> [configuration_name]: 」で始まるはずです。 例:「 CRE CrowdStrike [ CrowdStrike設定名]: <log_message> 」。(これは提案であり、設定名は使用しないことも可能です。) [logger.info(“<module> <plugin_name>: <message>”)]
- 可能な限り、エラーログに詳細情報を追加するようにしてください。
- エラーログには、エラーのトレースバックを詳細に追加することをお勧めします。
import traceback
self.logger.error(
message=f"{self.log_prefix}: Error log-message goes here.",
details=str(traceback.format_exc())
)
self.logger.warn(
f"{self.log_prefix}: Warning log-message goes here."
)
self.logger.info(
f"{self.log_prefix}: Info log-message goes here."
)
self.logger.debug(
f"{self.log_prefix}: Debug log-message goes here."
)
通知(任意)
Risk Exchange は、リスク Exchange UI で通知を生成するために使用できる通知オブジェクトのハンドルを提供します。
- このオブジェクトは、 Cloud Exchangeプラットフォームから Plugin オブジェクトに渡されます。 すべてのプラグイン統合は ユーザーに即座に通知する必要のある障害が発生した場合はいつでもこのオブジェクトを使用できます。 通知のタイムスタンプは、 Cloud Exchangeプラットフォームによって管理されます。
- このオブジェクトは、障害の深刻度に応じて色分けされた通知をUI上に表示します。サポートされている通知の重要度は、情報、警告、エラーです。
- 通知メッセージに、API認証情報やその他の機密情報が含まれていないことを確認してください。
- 障害や重大な状況(レート制限、ペイロードサイズの超過など)が発生した場合に通知を発生させ、プラグインの状態をユーザーに通知するための通知オブジェクト。
self.notifier.info(
f"{log_prefix}: Info notification-message goes here."
)
self.notifier.error(
f"{log_prefix}: Error notification-message goes here."
)
self.notifier.warn(
f"{log_prefix}: Warning notification-message goes here."
)
https://github.com/netskopeoss/ta_cloud_exchange_plugins/tree/main/microsoft_entra_id_ztreを参照してください。Risk Exchangeプラグインの開発、プラグインメソッド、開発のベストプラクティス、および複数のエンティティの処理に関するプラグイン。
Testing
Linting
ビルドプロセスの一環として、いくつかのリンターを実行して、 プログラミングエラー、スタイルエラー、および潜在的なセキュリティ問題を検出します。
Flake8
これは基本的なリンターです。必要な依存関係がすべて揃っていなくても実行でき、不要なエラーを検出します。 また このリンターを使用して、標準的な Python PEP8 フォーマットスタイルを強制することもできます。 まれに、このリンターから返されるエラーや警告を無効にする必要が生じる場合があります。エラーを無効にしたい行に、次のようなインラインコメントを追加することで、この操作を実行できます。
# noqa: <error-id>
例えば、
example = lambda: 'example' # noqa: E731
インラインコメントを追加する際は、必ず無効化するエラーコードを含めてください。そうすれば、同じ行に他のエラーがあった場合、それらが報告されます。
詳細については、 https ://flake8.pycqa.org/en/latest/user/violations.html#in-line-ignoring-errors を参照してください
Flake8リンターでは、PEP8スタイルのドキュメント文字列チェックも有効になっています。すべての関数/モジュールに適切なドキュメンテーション文字列が追加されていることを確認してください。
Cloud Exchangeへのプラグイン展開
プラグインをパッケージ化する
Cloud Exchangeでは、開発されたプラグインはzipまたはtar.gz形式で提供されることを想定しています。
パッケージを圧縮するには、次のコマンドを実行してください。
zip -r sample_plugin.zip sample_plugin
tar.gzパッケージを生成するには、以下のコマンドを実行してください。
tar -zcvf sample_plugin.tar.gz sample_plugin
Add a Repo
Cloud Exchangeにプラグインをデプロイするには、まずリポジトリを追加してください。
- Cloud Exchangeにログインしてください。
- Settings > Plugin Repository .
へ移動してください。
- Configure New Repository .
をクリックしてください
- リポジトリ名、リポジトリURL、ユーザー名、および個人アクセストークンを入力してください。
- Saveをクリックしてください。

- Settings > Pluginsへ移動してください。
- リポジトリのドロップダウンメニューからリポジトリ名Select 、次のセクションに進んでください。

プラグインのzipファイルまたはtar.gzファイルをアップロードしてください。
- 前のセクションから続ける場合は、ステップ2に進んでください。そうでない場合は、 Plugin Repositories .
に進んでください。
- リポジトリのUpload Pluginアイコンをクリックしてください。

- Browse .
をクリックしてください
- 作成したzipファイルまたはtar.gzファイルSelect 。

- Uploadをクリックしてください。
Deliverables
Plugin Guide
- プラグインガイドは、リリースごとに必ず更新してください。
- プラグインガイドには、以下の内容が含まれている必要があります。
- リリースノート
- デスクリプション
- 前提条件
- プラグインスコープ
- サポートされているデータタイプ
- Mapping
- Pull Mapping for <Entity>
- 権限
- APIの詳細
- 使うAPI一覧
- パフォーマンスマトリックス
- ユーザーエージェント
- ワークフロー
- サードパーティ製プラグインプラットフォームの設定
- Netskope CE の設定
- サードパーティ製プラグインの設定
- ビジネスルール構成
- アクション設定
- Validation
- トラブルシューティング
- 制限事項
具体的な例については、公開されているリスクエクスチェンジプラグインガイドを参照してください。
デモビデオ
Risk Exchangeプラグインの開発が成功したら、デモビデオを作成し、プラグインのエンドツーエンドのワークフローを示してください。
Note:詳細は、 Microsoft Entra IDプラグインのガイドを参照してください。

