HTTP Ingest API の開始方法🔗
このドキュメントでは、HTTP Ingest エンドポイントのリクエストおよびレスポンスのセマンティクスを定義し、それに対して信頼性の高い送信者を構築するためのガイダンスを提供します。UI 主導の設定については、HTTP Ingest の設定セットアップガイドを参照してください。
はじめに🔗
Secureworks® Taegis™ XDR HTTP Ingest API は、セキュリティ関連のログを Taegis にほぼリアルタイムで配信するためのプッシュ型 HTTPS インターフェースです。各インテグレーションには固有の URL とインテグレーションキーが割り当てられます。お客様自身のシステム、または URL とキーが設定されたサードパーティシステムが、取り込み データのリクエストを開始します。XDR は、このインテグレーションを通じてお客様のシステムへの接続やデータのプルを行いません。
HTTP Ingest は転送メカニズムです。一部の最適化されたインテグレーションは、サポートされているサードパーティソースからデータを配信するために内部的に HTTP Ingest を使用しており、その場合、プラットフォームはソース固有の正規化および検知を配信データに適用します。HTTP Ingest を直接使用して、既存の最適化されたインテグレーションに含まれていないデータソースからデータを配信する場合、それはカスタムインテグレーションとして機能します。Taegis への転送は、正しく構成されたリクエストを送信する送信者に対して保証されますが、下流の結果(型付きスキーマへの正規化、検索の関連性、ソース固有の検知など)は、ソースが認識されているかどうかに依存します。詳細は下流処理を参照してください。
対象読者🔗
このリファレンスは、HTTPS 経由で XDR にテレメトリーを配信するシステムを構築または運用するエンジニア(社内開発のフォワーダー、Webhook ブリッジ、HTTPS POST リクエストを発行できるサードパーティ製品とのインテグレーションなど)を対象としています。
ユースケース🔗
HTTP Ingest API のユースケース例:
- HTTPS POST リクエストを発行できるアプリケーションやサービスからのセキュリティテレメトリーのストリーミング
- 上流 API やローカルソースから読み取ったログを、オンホストエージェント、スクリプト、または定期ジョブから転送
- アウトバウンド HTTP Webhook をサポートするサードパーティ SaaS データソースのブリッジ
慣例🔗
このドキュメントにおける MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、SHOULD NOT、RECOMMENDED、MAY、OPTIONAL などのキーワードは、BCP 14 (RFC 2119, RFC 8174)1 で定義されている通り、すべて大文字で記載されている場合にのみ、その意味で解釈されます。
用語🔗
このドキュメント全体で使用されるプラットフォーム共通の用語(テナント、イベント、データソース、取り込み、正規化、スキーマ、カスタムインテグレーション、最適化されたインテグレーション など)は、Secureworks® Taegis™ 用語集で定義されており、ここでもその定義に従って使用されています。
HTTP Ingest API 固有の用語は以下の通りです:
- インテグレーション: XDR UI でプロビジョニングされ、正確に 1 つのテナントにスコープされ、固有の URL とインテグレーションキーを持つ構成済み HTTP Ingest インスタンス。一般的なプラットフォーム用語としては インテグレーション で定義されています。
- インテグレーションキー: インテグレーション作成時に発行される不透明なベアラ認証情報で、インテグレーションの URL へのリクエスト認証に使用されます。
- ログレコード: HTTP Ingest リクエストボディ内の個々の入力単位。例えば、
text/plainの改行区切り 1 行や、JSON Lines ボディ内の 1 つの JSON オブジェクトなど。正常に処理されると、ログレコードはプラットフォーム上で 1 つ以上のイベントになります。
バージョン管理🔗
URL パスコンポーネント /v1/ は、HTTP Ingest API の現在のメジャーバージョンを示します。新しいオプションリクエストヘッダー、追加のサポートコンテンツタイプ、一時的な条件に対する追加のサポートレスポンスコード、追加のサポートデータソースは、事前通知なしに v1 に導入される場合があります。送信者は、認識されないオプションレスポンスヘッダーを無視し、RFC 91102 で定義されたより広いクラスセマンティクスに従って認識されないレスポンスコードを処理するように実装する SHOULD があります(例:認識されない 5xx ステータスはリトライ可能として扱う SHOULD があります)。
既存の動作を変更または削除する変更(リクエストヘッダーの名称変更や削除、受け入れ可能なコンテンツタイプの縮小、既存レスポンスコードの意味変更など)は、新しいバージョンパス(例:/v2/ など)で導入され、既存の送信者は v1 で引き続き動作します。
エンドポイント🔗
HTTP Ingest エンドポイント URL は、インテグレーション作成時に XDR UI でオペレーターに提示されます。URL のホスト部分はお客様のリージョンに固有です。パスはインテグレーションを一意に識別します:
オペレーターは、手動で構築するのではなく、XDR UI から正確な URL を取得する SHOULD があります。
すべてのリクエストは HTTPS 経由で行う MUST があります。トランスポート層は TLS (RFC 8446)3 です。プレーンテキスト HTTP は受け付けられません。
認証🔗
HTTP Ingest API は、Authorization HTTP ヘッダー(RFC 9110, Section 11)2 で提示されるベアラトークンを使用してリクエストを認証します。インテグレーションキーがベアラトークンとして機能します。
クライアントは、RFC 67504 で定義された Bearer スキームを使用する SHOULD があります:
Splunk HTTP Event Collector (HEC) と相互運用するよう設計されたクライアントは、代わりに Splunk スキームで認証情報を提示する MAY があります:
クライアントは、他の認証スキームに依存しては MUST NOT いけません。
インテグレーションキーのライフサイクル🔗
- インテグレーションキーはインテグレーション作成時に一度だけ生成され、XDR UI で一度だけ表示されます。オペレーターはその時点でキーを取得・保存する MUST があります。作成ダイアログを閉じた後は、プラットフォームはキーを再表示・復元しません。
- インテグレーションキーは自動的には失効しません。
- プラットフォームは現在、既存インテグレーションのキーのインプレースローテーションをサポートしていません。ローテーションするには、新しい HTTP Ingest インテグレーションを作成し、送信者を新しい URL とキーに移行し、新しいインテグレーションで取り込みを確認した後、以前のインテグレーションを削除する SHOULD があります。
- インテグレーションは、XDR UI からいつでも削除できます。削除されたインテグレーションのキーを提示するリクエストは、
401 Unauthorizedまたは403 Forbiddenで拒否されます。
認証情報の取り扱い🔗
- インテグレーションキーは完全なベアラ認証情報であり、長期間有効なシークレットと同様の運用上の注意をもって扱う MUST があります(例:シークレットマネージャやプラットフォームキーストアでの保管、ログからのマスキング、配布の制限など)。
- 論理的なデータソースごとに 1 つのインテグレーションを用意してください。 1 つのインテグレーションの URL とキーは複数の送信者間で共有 MAY できますが、スループット、エラー率、正常性ステータスは XDR UI でインテグレーションごとに報告されます。複数のデータソースを 1 つのインテグレーションでまとめると、これらのシグナルが集約され、個々のソースの問題の検出・特定・修復が著しく困難になります。ソースごとのインテグレーションにより、認証情報の独立したローテーションや失効も可能になります。
リクエスト形式🔗
コンテンツタイプ🔗
サポートされているリクエスト Content-Type 値は以下の通りです:
text/plain: 改行区切りのログレコード。1 行ごとに 1 レコード。application/json: リクエストボディごとに 1 つの JSON オブジェクト、または改行区切りで 1 行ごとに 1 つの JSON オブジェクト(JSON Lines / NDJSON)。JSON コンテンツは RFC 82595 に準拠している MUST があります。
リクエストボディは両コンテンツタイプとも UTF-8 エンコードである MUST があります。application/json については RFC 8259, Section 8.15 でもこの要件が課されています。
コンテンツエンコーディング🔗
リクエストボディは非圧縮または gzip (RFC 1952)6 で圧縮して送信 MAY できます。圧縮リクエストは Content-Encoding リクエストヘッダーでエンコーディングを宣言する MUST があります:
他のコンテンツエンコーディングはサポートされていません。
レコードのフレーミング🔗
- プレーンテキスト: ログレコードはラインフィード文字(
\n)で区切られます。ラインフィードで終わらないレコードは、次のレコードと結合される MAY があります。 - JSON: クライアントは、リクエストボディごとに 1 つの JSON オブジェクト、または 1 行ごとに 1 つの JSON オブジェクト(JSON Lines / NDJSON; https://jsonlines.org/7 参照)を送信する SHOULD があります。複数行にまたがる整形済み JSON は、行区切り送信には推奨されません。途中の改行がレコード境界として扱われるためです。
サイズ制限🔗
| 制限 | 値 | 動作 |
|---|---|---|
| 推奨リクエストボディサイズ | 約 100 KB | エンドツーエンドの取り込みレイテンシ最小化に最適化。 |
| 最大リクエストボディサイズ | 100 MB | ハード上限。これを超えるリクエストは 413 Payload Too Large で拒否。 |
| 推奨最大個別ログレコードサイズ | 約 500 KB | これより大きい個別レコードは、下流処理で分割または切り捨てられる MAY があります。 |
クライアントは、1 つの大きすぎるレコードや非常に小さいリクエストの大量発行ではなく、多数の小さなログレコードを適切なサイズのリクエストにバッチ化する SHOULD があります。
API はリクエストごとのログレコード数に個別の上限を設けていません。上記のバイトサイズ制限のみが拘束条件です。サイズ制限内であれば、含まれるログレコード数に関係なくリクエストは受け付けられます。
送信レート🔗
プラットフォームはすべてのテナントの安定性を確保するためにレート制御を適用します。クライアントは、送信者を安定した均等分布のトラフィックに調整し、数分間のデータを数秒に圧縮するようなバーストを避ける SHOULD があります。レート制限されたリクエストは 429 Too Many Requests(RFC 9110, Section 15.5.29)2 で通知されます。
レスポンスのセマンティクス🔗
ステータスコード🔗
ステータスコードは RFC 91102 に従います。この API のコードごとのセマンティクスは以下の通りです:
| ステータス | 意味 | 推奨クライアントアクション |
|---|---|---|
200 OK |
リクエストボディが非同期処理のために受理されました。 | 継続。 |
400 Bad Request |
リクエストが不正、空、または解析不能でした。 | 変更なしでリトライ MUST NOT。ペイロード、ヘッダー、エンコーディングを確認。 |
401 Unauthorized |
Authorization ヘッダーが欠落または認証情報が認識されませんでした。 |
リトライ MUST NOT。インテグレーションキーと URL の組み合わせを確認。 |
403 Forbidden |
認証情報は認識されたが、もはや認可されていません(例:インテグレーションが削除された)。 | リトライ MUST NOT。必要に応じて代替インテグレーションを生成。 |
408 Request Timeout |
リクエストがタイムアウトしました。 | バックオフ付きでリトライ MAY。 |
413 Payload Too Large |
リクエストボディが最大受理サイズを超えました。 | リトライ MUST NOT。ペイロードを小さいリクエストに分割。 |
429 Too Many Requests |
プラットフォームの保護によりレート制限されました。 | バックオフと同時実行数またはバッチサイズの削減でリトライ SHOULD。 |
500, 502, 503, 504 |
一時的なサービス側エラーが発生しました。 | バックオフ付きでリトライ SHOULD。 |
200 OK レスポンスは、リクエストボディが取り込みのために受理されたことのみを確認します。パース、正規化、検索インデックス化、検知生成は非同期で行われ、HTTP レスポンスには反映されません。
リトライ戦略🔗
クライアントは、リトライ可能なレスポンス(408、429、5xx)に対して、指数バックオフ+ジッター付きリトライポリシーを実装する SHOULD があります(例:初期間隔 1 秒、最大数分まで)。
HTTP Ingest API は少なくとも 1 回の配信セマンティクスを提供します:
- API は現在、クライアント指定の冪等性キーをサポートしておらず、リトライされたリクエスト間でログレコードの重複排除を行いません。
- 複数回配信されたログレコードは、ソース固有のパーサーが独自に重複排除しない限り、下流の検索や検知結果に複数回現れます。
クライアントは、未配信バッチをローカルに保持し、長期障害時のデータ損失を防ぐ SHOULD があります。
テナントのスコーピング🔗
各インテグレーションは、提示されたインテグレーションキーを所有する 1 つのテナントに紐付けられます。複数のテナントにデータを配信するには、オペレーターはテナントごとに 1 つの HTTP Ingest インテグレーションをプロビジョニングし、送信者から対応する URL とキーにルーティングする MUST があります。
下流処理🔗
200 OK の成功は、Taegis への転送を確認します。下流処理の深さは、送信されたデータソースが最適化されたインテグレーションでサポートされているかどうかによって異なります。HTTP Ingest は、XDR が管理する最適化されたインテグレーションの転送手段としても、お客様が直接構成したスタンドアロンのカスタムインテグレーションとしても機能します。
- 最適化されたインテグレーションでサポートされているデータソースは、ソース固有の正規化で処理され、1 つ以上の型付きスキーマにマッピングされたイベントを生成します。これらのイベントは、ソース固有の検知に即時対応可能です。
- 最適化されたインテグレーションでサポートされていないデータソースは、Genericスキーマで保存されます。Genericスキーマで保存されたログレコードは検索可能で、テナントの設定された保持期間保存されますが、ソース固有のスキーマにはマッピングされず、追加設定なしではソース固有の検知の対象になりません。
- 送信されたデータソースが最適化されたインテグレーションでサポートされている場合でも、個々のログレコードがパースできない場合は Genericスキーマで保存されます。
現在の最適化されたインテグレーションのカタログは、Capabilities at a Glanceリファレンスで管理されています。最適化されたインテグレーションで現在サポートされていないデータソースの処理を拡張するには、オペレーターはテナント向けにカスタムパーサーやカスタム検出ルールを作成 MAY できます。
セキュリティ上の考慮事項🔗
- トランスポート: すべてのリクエストは HTTPS (RFC 8446)3 で行う MUST があります。プレーンテキスト HTTP は受け付けられません。
- 認証情報の漏洩: インテグレーションキーは長期間有効なベアラ認証情報です。信頼できない相手に配布されるクライアントサイドコードへの埋め込み、プレーンテキストでのログ出力、非安全なチャネルでの送信は MUST NOT です。
- ソースごとの分離: 1 つのインテグレーションキーを多数の独立した送信者で共有すると、侵害時の影響範囲が拡大します。独立した特定、ローテーション、失効が重要な場合は、論理ソースごとに個別のインテグレーションを用意する SHOULD があります。
- ローテーションの衛生管理: インプレースキーのローテーションがサポートされていないため、オペレーターは新規作成/移行/旧削除のワークフローを定期的な運用手順として扱い、定期的なサイクルや疑わしい侵害時に積極的にキーをローテーションする SHOULD があります。
- 失効: XDR UI でインテグレーションを削除することが、即時キー失効のサポートされた手段です。削除されたインテグレーションのキーを提示する後続リクエストは、認証レイヤーで拒否されます。
代替プッシュ型転送手段🔗
HTTP Ingest は、XDR にお客様の環境へのアクセス権を与えることなくデータを配信するための複数のプッシュ型転送手段の 1 つです。全リストはカスタム転送方法を参照してください。例:
- syslog 転送用の XDR Collector
- バッチファイル送信用の File Upload API
- Secureworks 管理バケットへの配信用 S3 Ingest — Secureworks-Managed
- Azure ネイティブソース用の Azure Event Hubs および Azure Storage Accounts
例🔗
以下の例は、ローカルファイルの内容を構成済み HTTP Ingest インテグレーションに送信します。実行前に HTTP_INGEST_URL および HTTP_INGEST_KEY 環境変数を設定してください:
export HTTP_INGEST_URL="https://<regional-ingest-host>/http-endpoint/v1/<integration-id>"
export HTTP_INGEST_KEY="your_integration_key"
cURL🔗
単一のリテラルレコードでインテグレーションへの接続性を確認:
curl --request POST "$HTTP_INGEST_URL" \
--header "Authorization: Bearer $HTTP_INGEST_KEY" \
--header "Content-Type: text/plain" \
--data "hello world"
成功すると 200 OK が返ります。送信したレコードは、まもなく XDR UI で検索可能になります。
プレーンテキストのログファイルを送信:
curl --request POST "$HTTP_INGEST_URL" \
--header "Authorization: Bearer $HTTP_INGEST_KEY" \
--header "Content-Type: text/plain" \
--data-binary @logs.txt
gzip で圧縮した JSON ペイロードを送信:
gzip --to-stdout payload.json | \
curl --request POST "$HTTP_INGEST_URL" \
--header "Authorization: Bearer $HTTP_INGEST_KEY" \
--header "Content-Type: application/json" \
--header "Content-Encoding: gzip" \
--data-binary @-
Python🔗
この例は、レスポンスのセマンティクスで説明した推奨レスポンスコード処理および指数バックオフ+ジッター付きリトライ戦略を示しています:
#!/usr/bin/env python3
"""Send a local file to HTTP Ingest with retry handling."""
import os
import random
import sys
import time
import requests
API_URL = os.environ["HTTP_INGEST_URL"]
API_KEY = os.environ["HTTP_INGEST_KEY"]
# Status codes the HTTP Ingest API contract considers retryable.
RETRYABLE_STATUS = {408, 429, 500, 502, 503, 504}
def post(body: bytes, content_type: str, max_attempts: int = 5) -> None:
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": content_type,
}
backoff_cap = 60.0 # seconds
backoff = 1.0
for attempt in range(1, max_attempts + 1):
response = requests.post(API_URL, data=body, headers=headers, timeout=30)
status = response.status_code
if status == 200:
return
# Non-retryable per the documented contract: stop immediately.
if status == 400:
sys.exit("400 Bad Request — inspect payload, headers, and encoding.")
if status == 401:
sys.exit("401 Unauthorized — verify the integration key and URL.")
if status == 403:
sys.exit("403 Forbidden — Integration may have been deleted; provision a new one.")
if status == 413:
sys.exit("413 Payload Too Large — split the body into smaller batches.")
# Retryable: sleep with full-jitter backoff, then try again.
if status in RETRYABLE_STATUS and attempt < max_attempts:
sleep_for = random.uniform(0, min(backoff, backoff_cap))
time.sleep(sleep_for)
backoff *= 2
continue
sys.exit(f"Unexpected status {status}: {response.text}")
sys.exit(f"Failed after {max_attempts} attempts.")
if __name__ == "__main__":
if len(sys.argv) != 2:
sys.exit(f"usage: {sys.argv[0]} <filename>")
with open(sys.argv[1], "rb") as fd:
post(fd.read(), content_type="text/plain")
JSON Lines (NDJSON) を送信する場合は、content_type="application/json" を設定し、ファイルが改行区切りで 1 行ごとに 1 つの JSON オブジェクトを含むことを確認してください。
関連ドキュメント🔗
- HTTP Ingest の設定: UI 主導のセットアップガイド
- HTTP Ingest 転送方法の概要: ハイレベルな説明とリファレンスアーキテクチャ
- カスタム転送方法: XDR でサポートされるすべてのカスタム転送の概要
- カスタムパーサー: 追加データソースへの正規化拡張
- カスタム検出ルール: 取り込んだデータに対する検知の作成
参考文献🔗
-
BCP 14 — Best Current Practice 14: RFC 2119, RFC 8174. https://www.rfc-editor.org/info/bcp14/。RFC 2119 — Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. https://www.rfc-editor.org/info/rfc2119。RFC 8174 — Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, May 2017. https://www.rfc-editor.org/info/rfc8174。 ↩
-
RFC 9110 — Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, June 2022. https://www.rfc-editor.org/info/rfc9110 ↩↩↩↩
-
RFC 8446 — Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, August 2018. https://www.rfc-editor.org/info/rfc8446 ↩↩
-
RFC 6750 — Jones, M. and D. Hardt, "The OAuth 2.0 Authorization Framework: Bearer Token Usage", RFC 6750, October 2012. https://www.rfc-editor.org/info/rfc6750 ↩
-
RFC 8259 — Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, December 2017. https://www.rfc-editor.org/info/rfc8259 ↩↩
-
RFC 1952 — Deutsch, P., "GZIP file format specification version 4.3", RFC 1952, May 1996. https://www.rfc-editor.org/info/rfc1952 ↩
-
JSON Lines. https://jsonlines.org/ ↩