
# OpenTofu と Terraform プロバイダ

`keenauth/keenauth` プロバイダは、1 つの KeenAuth 環境の設定をコードとして管理します。管理 API を呼び出し、プラグインプロトコル 6 を使用し、OpenTofu と Terraform で動作します。まだプロバイダレジストリには公開されていません。

## 認証と対象

プロバイダは、その認証情報が属する環境を管理します。複数の環境を管理する場合は、環境ごとにプロバイダのエイリアスを 1 つずつ設定してください。認証方法は次の 2 つのうち 1 つだけです。管理 API キーを使用する方法、または `private_key_jwt` を使用する `management` アプリケーションとしてキーレスで認証する方法です。両方を設定するとエラーになります。

| 設定 | 環境変数 | 説明 |
|---|---|---|
| `api_key` | `KEENAUTH_API_KEY` | 管理 API キーです。環境変数の使用を推奨します。キーがステートファイルやプランファイルに書き込まれることはありません。 |
| `client_id` | `KEENAUTH_CLIENT_ID` | `api_key` の代わりに使用する、`management` アプリケーションの ID（`app_…`）です。`private_key` と `issuer` が必要です。 |
| `private_key` | `KEENAUTH_PRIVATE_KEY` | アプリケーションに公開鍵が登録されている PEM PKCS#8 形式の秘密鍵です。EC P-256、EC P-384、Ed25519、または 2048 ビット以上の RSA を使用できます。環境変数の使用を推奨します。ステートに書き込まれることはありません。 |
| `private_key_algorithm` | | `PS256`（デフォルト）または `RS256` です。RSA 鍵の場合のみ指定します。 |
| `issuer` | `KEENAUTH_ISSUER` | 環境のデフォルトホスト、`https://<environment>.<region>.keenauth.app` です。プロバイダは `<issuer>/oauth2/token` からトークンを取得します。 |
| `scopes` | | `client_id` で要求する権限です。省略した場合は、付与のデフォルトスコープが適用されます。 |
| `region` | `KEENAUTH_REGION` | `eu`（デフォルト）または `us` です。API のアドレスは `https://api.eu.keenauth.com/v1` / `https://api.us.keenauth.com/v1` です。 |
| `base_url` | `KEENAUTH_BASE_URL` | API のアドレスを明示的に指定します。受け付けるのは `https://<host>.keenauth.com/v1` のみです。ローカルテスト用にループバックアドレスも指定できます。 |

```terraform
terraform {
  required_providers {
    keenauth = { source = "keenauth/keenauth" }
  }
}

provider "keenauth" {
  region = "eu"
}
```

### `private_key_jwt` によるキーレス認証

1. `app_type = "management"` のアプリケーションを作成し、構成に必要な権限を持つ `keenauth_management_client` レコードを作成します。
2. 鍵ペアの公開鍵をアプリケーションに登録します（`type: public_key` を指定して `POST /v1/applications/{application_id}/credentials` を呼び出す、CLI を使用する、またはダッシュボードを使用します）。
3. アプリケーション ID、秘密鍵、発行者をプロバイダに渡します。

```shell
export KEENAUTH_CLIENT_ID="app_..."
export KEENAUTH_PRIVATE_KEY="$(cat ops-automation.pk8.pem)"
export KEENAUTH_ISSUER="https://acme.eu.keenauth.app"
tofu plan
```

プロバイダは管理トークンのたびに、60 秒間有効なクライアントアサーション（RFC 7523）に署名します。`iss` と `sub` はクライアント ID、`aud` は発行者、`jti` はランダム値、`kid` は鍵の RFC 7638 サムプリントです。このアサーションを `client_credentials` グラントで交換し、有効期間 10 分のトークンを取得します。古いトークンの期限切れの 1 分前に新しいトークンを取得します。トークンが持つ権限が、アプリケーションの `keenauth_management_client` レコードの権限を超えることはありません。管理クライアントなど、API キーのみを受け付けるエンドポイントには、`api_key` で設定したプロバイダのエイリアスが必要です。

## リソース

| 名前 | 種類 | 管理する対象 |
|---|---|---|
| `keenauth_application` | resource | アプリケーション（OAuth 2.0 / OpenID Connect クライアント）です。 |
| `keenauth_connection` | resource | ログイン接続です。データベース、パスワードレス、パスキー、ソーシャル、エンタープライズのいずれかです。 |
| [`keenauth_connection_oidc_config`](/docs/terraform/connection-oidc-config) | resource | エンタープライズ OIDC 接続のリライングパーティ設定です。クライアントシークレットは書き込み専用です（OpenTofu または Terraform 1.11 以降）。接続 ID でインポートします。destroy はステートから削除するだけです。 |
| [`keenauth_environment_settings`](/docs/terraform/environment-settings) | resource | 環境設定です。言語、セッション、サインアップ、通知、リカバリー、多要素認証、最初の認証要素などを含みます。環境ごとに 1 つです。 |
| [`keenauth_attack_protection`](/docs/terraform/attack-protection) | resource | 攻撃対策です。ブルートフォース、IP スロットリング、認証情報の使い回し、ボット、漏えいしたパスワード、サインアップ、SMS 不正、リスクポリシーを含みます。環境ごとに 1 つです。 |
| [`keenauth_branding`](/docs/terraform/branding) | resource | ブランディングの下書きに含まれる環境のテーマです。環境ごとに 1 つです。 |
| [`keenauth_custom_domain`](/docs/terraform/custom-domain) | resource | カスタムログインドメインです。 |
| [`keenauth_api_key`](/docs/terraform/api-key) | resource | 管理 API キーです。インポートのみに対応し、destroy では取り消されます。 |
| `keenauth_organization` | resource | B2B 組織です。名前、スラッグ、外部 ID、メタデータ、ブランドカラー、メンバー数の上限を管理します。destroy では即座に削除されます。ステータス操作（無効化、有効化、削除の取り消し）は CLI とダッシュボードで行います。 |
| `keenauth_organization_role` | resource | 組織固有のロールと、その権限セットです（Business プラン）。`<org_id>/<key>` でインポートします。 |
| [`keenauth_permission`](/docs/terraform/permission) | resource | API の権限（OAuth スコープ）と、同意画面のテキストです。`<api_id>/<value>` でインポートします。 |
| [`keenauth_role`](/docs/terraform/role) | resource | 環境のロールと、その完全な権限セットです。ユーザーやメンバーシップの割り当てはリソースではありません。 |
| [`keenauth_organization_domain`](/docs/terraform/organization-domain) | resource | ドメインキャプチャと SSO ルーティングのための組織のドメインです。検証はアクションとして扱われます。 |
| [`keenauth_session_policy`](/docs/terraform/organization-policies) | resource | 組織のセッション有効期間です。環境の設定より厳しい値のみ設定できます（Enterprise プラン）。 |
| [`keenauth_mfa_policy`](/docs/terraform/organization-policies) | resource | 組織の多要素認証ルールです。環境の設定より厳しい値のみ設定できます。 |
| [`keenauth_email_template`](/docs/terraform/email-template) | resource | 1 つのメールテンプレート（ファミリーとロケール）の公開済みの内容です（Startup プラン）。`<family>/<locale>` でインポートします。destroy はステートから削除するだけです。 |
| [`keenauth_management_client`](/docs/terraform/management-client) | resource | `management` アプリケーションの管理 API 権限と IP 許可リストです。アプリケーション ID でインポートします。 |
| [`keenauth_directory`](/docs/terraform/directory) | resource | 組織の SCIM ディレクトリと、そのプロビジョニング設定です。`name` と設定はその場で変更されます。`organization_id`、`scim_host`、`type` を変更すると再作成されます。ディレクトリ ID でインポートします。 |
| [`keenauth_directory_role_mapping`](/docs/terraform/directory-role-mapping) | resource | SCIM ディレクトリのグループをロールに対応付けます。変更があると再作成されます。`<directory_id>/<mapping_id>` でインポートします。 |
| [`keenauth_directory_token`](/docs/terraform/directory-token) | resource | ディレクトリの SCIM トークンです。ステートには RSA 公開鍵で暗号化された状態でのみ保持されます。変更があると新しいトークンが作成され、destroy では取り消されます。インポートはできません。 |
| [`keenauth_webhook_endpoint`](/docs/terraform/webhook-endpoint) | resource | Webhook エンドポイントです。すべての引数はその場で変更されます。署名シークレットは RSA 公開鍵で暗号化された状態でのみステートに保持されます。鍵または `rotation_trigger` を変更すると、シークレットがローテーションされます。エンドポイント ID またはキーでインポートします。 |
| `keenauth_application` | data source | `id` または `key` で 1 つのアプリケーションを読み取ります。 |
| `keenauth_connection` | data source | `id` または `key` で 1 つの接続を読み取ります。 |
| `keenauth_organization` | data source | `id` または `slug` で 1 つの組織を読み取ります。 |
| [`keenauth_role`](/docs/terraform/role) | data source | `id` または `key` で 1 つの環境のロールを読み取ります。 |
| `keenauth_environment` | data source | API キーの環境を読み取ります。ID、種類、リージョン、セル、状態、プランを含みます。 |

```terraform
resource "keenauth_connection" "google" {
  key      = "google"
  type     = "social"
  strategy = "google"
  name     = "google"
  status   = "active"
  settings = jsonencode({ scopes = ["openid", "email", "profile"] })
}

resource "keenauth_application" "storefront" {
  key            = "storefront"
  name           = "Storefront"
  app_type       = "web"
  party          = "first_party"
  redirect_uris  = ["https://shop.example.com/callback"]
  connection_ids = [keenauth_connection.google.id]
}
```

## インポート

アプリケーションと接続は `key` または ID でインポートできます。カスタムドメインはホスト名または ID で、API キーは ID でインポートできます。

```shell
tofu import keenauth_application.storefront storefront
tofu import keenauth_connection.google conn_01j9zq3v8c5m2x7k4t6r1n0b3d
tofu import keenauth_custom_domain.login login.example.com
```

環境設定、攻撃対策、ブランディングの下書きは環境ごとに 1 つだけ存在します。固定 ID の `environment-settings`、`attack-protection`、`branding` を使用してインポートしてください。これらのいずれかを destroy すると、ステートから削除されるだけです。

## 安全な変更

- 作成時には `Idempotency-Key` が送信されるため、作成を再試行しても同じオブジェクトが 2 つ作成されることはありません。
- 更新や削除の際には、最後に読み取った ETag を使用して `If-Match` が送信されます。プランを作成した後にオブジェクトが変更されていた場合、API は `412` を返し、何も変更されません。`plan` を再実行してください。
- ダッシュボードで行われた変更は、次の `plan` でドリフトとして表示されます。`apply` を実行すると元に戻ります。プロバイダの外部で削除されたオブジェクトは、ステートから除去され、再作成されます。
- 更新時には、変更されたフィールドのみが JSON マージパッチ（RFC 7396）として送信されます。

## シークレット

どのリソースも、シークレットを平文でステートに保存しません。KeenAuth に渡すシークレットは書き込み専用の引数（`*_wo`）です。プロバイダはこれらを送信しますが、ステートやプランファイルには書き込みません。送信し直すのは `*_wo_version` が変更された場合のみです。これらには OpenTofu または Terraform 1.11 以降が必要です。現在はエンタープライズ OIDC 接続のクライアントシークレット（`keenauth_connection_oidc_config`）が該当します。アプリケーションのクライアントシークレットと署名鍵は、このバージョンのプロバイダでは管理されません。ダッシュボードまたは CLI で作成とローテーションを行ってください。KeenAuth が生成するシークレットは書き込み専用にできません。書き込み専用の引数は、構成からプロバイダへ値を渡すだけだからです。プロバイダは API キーを作成しません。生のキーがステートに残ってしまうためです。CLI でキーを作成し、シークレットマネージャーに保存して、ID を指定して `keenauth_api_key` にインポートしてください。ディレクトリの SCIM トークンは API によって一度だけ表示されます。そのため、プロバイダはディレクトリ作成時に返されたトークンを取り消し、保持しません。`keenauth_directory_token` は、ID プロバイダ用のトークンを作成し、RSA 公開鍵で暗号化した状態でのみステートに保持します。`keenauth_webhook_endpoint` も同じ方法で Webhook の署名シークレットを扱います。その暗号化には `public_key` を使用し、鍵が指定されていない場合は破棄します。接続の `settings` にシークレットを含めることはできません。API はシークレットのような設定を拒否します。

## このバージョンの制限

- 管理対象は、アプリケーション、接続とその OIDC 設定、環境設定、攻撃対策、ブランディングの下書きの環境テーマ、カスタムドメイン、API キー（インポートのみ）、組織、ロールと権限、組織ドメイン、組織のセッションと多要素認証のポリシー、メールテンプレート、管理クライアント、SCIM ディレクトリ、グループとロールの対応付け、SCIM トークン（公開鍵で暗号化）、Webhook エンドポイントです。フック、ログストリーム、SMS テンプレートは以降のバージョンで対応予定です。
- プロバイダはブランディングを公開しません。ダッシュボードまたは `keenauth branding publish` を使用して下書きを公開してください。
- サーバーにデフォルト値があるオプションのフィールド（例: `grant_types`）は、構成から削除しても最後の値を保持します。
- スキーマの説明とエラーメッセージは英語です。
