# Snowflake

{% hint style="info" %}
このコネクタは現在、リクエストに応じて提供しています。ワークスペースで有効にするには、[サポートにお問い合わせください](https://www.aikido.dev/contact)。
{% endhint %}

Aikido の issue を Snowflake に送信すると、セキュリティの検出結果をデータウェアハウス内の他のデータと合わせてクエリできるようになります。

Aikido の検出結果に対して独自の分析を行いたい場合、他のビジネスデータと結合したい場合、または既存の Snowflake ベースのダッシュボードやアラートに取り込みたい場合に便利です。

### 要件

接続する前に、Snowflake で以下を用意してください。

* **Account identifier、Database、Warehouse、Schema、Role、User** - テーブル、ステージ、ファイルフォーマットを作成する権限を持つ専用のサービスアカウント用です。
* **テーブル名** - 書き込み先のテーブルです。まだ存在しない場合は、Aikido が初回のデータ書き込み時に自動的に作成します。
* **ステージ名** - テーブルの初回作成時にのみ使用されます。
* **認証** - サービスアカウントの RSA **Private Key**（推奨）または **Password** のいずれかです。

### Snowflake の接続

{% stepper %}
{% step %}
#### Snowflake サービスアカウントを設定する

個人のログインではなく、専用のサービスアカウントの使用を推奨します。作成するユーザーの種類は、認証方式によって異なります。

**キーペア認証（推奨）**

[Snowflake のキーペア認証ガイド](https://docs.snowflake.com/en/user-guide/key-pair-auth)に従って RSA キーペアを生成し、公開鍵を使用してサービスユーザーを作成します。

```sql
CREATE USER aikido_service_account
    COMMENT = 'Service account for Aikido Snowflake integration'
    TYPE = 'service'
    RSA_PUBLIC_KEY = 'Your RSA Public Key';
```

秘密鍵（raw PEM または base64）は安全な場所に保管してください。後のステップで Aikido に貼り付けます。

**パスワード認証**

{% hint style="warning" %}
Snowflake のサービスユーザー（`TYPE = 'service'`）はパスワードによるログインをサポートしていません。パスワードで認証したい場合は、サービスユーザーではなく通常のユーザーを作成してください。
{% endhint %}

```sql
CREATE USER aikido_service_account
    COMMENT = 'Service account for Aikido Snowflake integration'
    PASSWORD = 'a strong, generated password'
    MUST_CHANGE_PASSWORD = FALSE;
```

可能な場合は、パスワード認証よりもキーペア認証を推奨します。

**ロールを作成して権限を付与する**

```sql
CREATE ROLE aikido_service_account_role;

GRANT ROLE aikido_service_account_role TO USER aikido_service_account;

GRANT USAGE ON WAREHOUSE {your_warehouse} TO ROLE aikido_service_account_role;
GRANT USAGE ON DATABASE {your_database} TO ROLE aikido_service_account_role;
GRANT USAGE ON SCHEMA {your_database}.{your_schema} TO ROLE aikido_service_account_role;
GRANT CREATE TABLE ON SCHEMA {your_database}.{your_schema} TO ROLE aikido_service_account_role;
GRANT CREATE STAGE ON SCHEMA {your_database}.{your_schema} TO ROLE aikido_service_account_role;
GRANT CREATE FILE FORMAT ON SCHEMA {your_database}.{your_schema} TO ROLE aikido_service_account_role;
```

これにより、コネクタが実際に必要とする権限、つまりウェアハウスへのクエリと、初回書き込み時のテーブル、ステージ、ファイルフォーマットの作成がカバーされます。`MONITOR` の付与や `USAGE ON FUTURE SCHEMAS` は不要です。これらは単一テーブルのコネクタが必要とする以上の広範なアクセスを与えます。このロールにウェアハウスやデータベースのアクティビティの可視性、または後から作成されるスキーマへのアクセスを別途持たせたい場合にのみ追加してください。

Aikido にテーブルを作成させるのではなく、自分で作成したテーブルを Aikido に指定する場合は、その特定のテーブルへの書き込み権限も付与してください。

```sql
GRANT INSERT ON TABLE {your_database}.{your_schema}.{your_table} TO ROLE aikido_service_account_role;
```
{% endstep %}

{% step %}
#### SIEM を接続する

Aikido アプリで **Settings > Integrations** に移動し、新しい SIEM 連携を追加します。**Connect a SIEM** ダイアログで **Snowflake** を選択し、以下を入力します。

**Settings**

* **Database** - 接続先の Snowflake データベースです。
* **Warehouse** - クエリの実行とデータのロードに使用する仮想ウェアハウスです。
* **Schema** - 書き込み先のテーブルが存在するデータベース内のスキーマです。
* **User** - サービスアカウントのユーザー名です。
* **Account** - Snowflake の account identifier です。Snowflake の現在の標準フォーマットは `organization_name-account_name` です（Snowflake で `SELECT CURRENT_ORGANIZATION_NAME(), CURRENT_ACCOUNT_NAME();` を実行すると両方を確認できます）。アカウントによっては、古い account locator 形式も使用できる場合があります。どちらが該当するかわからない場合は、[Snowflake の account identifier ガイド](https://docs.snowflake.com/en/user-guide/admin-account-identifier)を参照してください。
* **Table** - データの書き込み先テーブルです。存在しない場合は、Aikido が自動的に作成します。
* **Case Insensitivity** - オンにすると、テーブル作成時にカラム名が大文字に変換されます（Snowflake のデフォルトの動作）。オフにすると、元の大文字・小文字が保持されます。データのロード自体は、常に大文字・小文字を区別せずにカラムを照合します。
* **Stage** - データのロードに使用する Snowflake ステージです。テーブルの初回作成時にのみ関係します。
* **Role** - サービスアカウントが使用するロールです。
* **Authentication Type** - **private key**（推奨）または **password** を選択します。

**Options**

* **Batch Config** - 書き込み前のデータのバッチ処理方法を制御します。
  * **Batch Data Size** - レコード数や経過時間に関係なく、バッチが送信されるまでの最大合計サイズ（バイト）です。
  * **Batch Record Count** - バッチが自動的に送信されるまでに蓄積するレコードの最大数です。
  * **Maximum Flush Interval** - サイズや件数に関係なく、送信前にレコードを保持する最大時間（秒）です。

**Authentication**

選択した **Authentication Type** に対応するフィールドを入力します。

* **Private Key** - サービスアカウントの RSA 秘密鍵です。raw PEM または base64 形式で入力します。
* **Password** - サービスアカウントのパスワードです。パスワード認証を使用する場合のみ入力します（秘密鍵よりも安全性が低くなります）。

**Test connection** をクリックして Aikido が Snowflake に到達できることを確認し、**Save changes** をクリックします。
{% endstep %}

{% step %}
#### 同期する issue を設定する

Snowflake 連携ページの **Issue input settings** で、同期する Aikido の issue を設定します。

* **Issue status** - 例えば、オープンな issue のみを同期するか、解決済みや無視された issue も含めるかを設定します。
* **Minimum severity** - 同期する最低の重大度レベルです。
* **Issue type** - 特定の issue タイプに限定するか、すべてを同期します。
* **Language** - 特定の言語に限定するか、すべてを同期します。
* **Sync frequency** - Aikido が条件に一致する issue を Snowflake にプッシュする頻度です（例: 1 時間ごと）。

**Save Settings** をクリックします。
{% endstep %}
{% endstepper %}

### データのロード方法

まだ存在しないテーブルに初めてデータを書き込む際、Aikido はデータをステージングして `COPY INTO` を使用し、Snowflake がスキーマを推論してテーブルを自動的に作成できるようにします。テーブルが作成された後の書き込みは、直接の `INSERT` ステートメントに切り替わります。これは継続的な小規模バッチに対してよりコスト効率が高い方法です。

### イベントが届いていることの確認

Snowflake で書き込み先のテーブルを直接クエリします。設定した同期頻度の時間が経過するまで待つか、Aikido でテスト用の issue を発生させて、新しい行が表示されることを確認してください。

### トラブルシューティング

* **接続エラーまたはタイムアウトエラー** - account identifier のフォーマットを再確認し、ウェアハウスがすばやく起動することを確認してください（接続は 30 秒でタイムアウトします）。
* **認証エラー** - キーペア認証の場合は、秘密鍵がサービスアカウントに登録された公開鍵と一致していることを確認し、PEM と base64 の両方の形式を試してください。パスワード認証の場合は、認証情報が正しく、パスワード認証が有効になっていることを確認してください。
* **データが欠落している** - データベース、スキーマ、テーブル、ステージの名前がすべて正しいことを確認してください。
* **挿入時のスキーマの不一致** - テーブルが作成された後は、受信データがそのスキーマと一致している必要があります。データの形式が時間とともに変化すると、挿入が失敗し始める可能性があります。
* **テーブルが作成されない** - テーブルの作成にはステージへのアクセスが必要です。ロールにスキーマに対する `CREATE STAGE` および `CREATE FILE FORMAT` 権限があることを確認してください。

### 制限事項

* JSON データのみがサポートされています。
* Aikido がテーブルを作成する場合、明示的なスキーマ定義はサポートされていません。スキーマはデータから推論されます。独自のスキーマでテーブルを事前に作成し、そのテーブルを Aikido に指定することもできます。その場合は、サービスロールにそのテーブルに対する `INSERT` 権限があることを確認してください（上記の権限付与を参照）。
* 直接の挿入では、既存のテーブルスキーマが受信データと一致している必要があります。データに一貫性がないと、挿入が失敗する可能性があります。

### 連携の管理

Aikido の **Settings > Integrations > Snowflake** から、以下の操作ができます。

* **Manage Integration** - 接続情報、バッチ処理、または認証を更新します。
* **Remove Integration** - Snowflake の接続を解除します。これにより今後のすべての同期が停止しますが、Snowflake にすでに書き込まれた行は削除されません。
