
# Fournisseur OpenTofu et Terraform

Le fournisseur `keenauth/keenauth` gère la configuration d'un environnement KeenAuth sous forme de code. Il appelle l'API de gestion, utilise le protocole de plugin 6 et fonctionne avec OpenTofu et Terraform. Il n'est pas encore publié dans un registre de fournisseurs.

## Authentification et cible

Le fournisseur gère l'environnement auquel appartient son identifiant. Pour gérer plusieurs environnements, configurez un alias de fournisseur par environnement. Il s'authentifie de l'une des deux manières suivantes, et d'une seule : avec une clé d'API de gestion, ou sans clé en tant qu'application `management` avec `private_key_jwt`. Renseigner les deux est une erreur.

| Paramètre | Variable d'environnement | Description |
|---|---|---|
| `api_key` | `KEENAUTH_API_KEY` | Clé d'API de gestion. Privilégiez la variable d'environnement. La clé n'est jamais écrite dans les fichiers d'état ou de plan. |
| `client_id` | `KEENAUTH_CLIENT_ID` | Identifiant (`app_…`) d'une application `management`, à la place de `api_key`. Nécessite `private_key` et `issuer`. |
| `private_key` | `KEENAUTH_PRIVATE_KEY` | Clé privée PEM PKCS#8 dont la clé publique est enregistrée sur l'application : EC P-256, EC P-384, Ed25519 ou RSA d'au moins 2048 bits. Privilégiez la variable d'environnement. Elle n'est jamais écrite dans l'état. |
| `private_key_algorithm` | | `PS256` (par défaut) ou `RS256`, uniquement pour une clé RSA. |
| `issuer` | `KEENAUTH_ISSUER` | L'hôte par défaut de l'environnement, `https://<environment>.<region>.keenauth.app`. Le fournisseur obtient son jeton à l'adresse `<issuer>/oauth2/token`. |
| `scopes` | | Autorisations à demander avec `client_id`. Si ce paramètre est omis, les scopes par défaut de l'octroi s'appliquent. |
| `region` | `KEENAUTH_REGION` | `eu` (par défaut) ou `us`. L'adresse de l'API est `https://api.eu.keenauth.com/v1` / `https://api.us.keenauth.com/v1`. |
| `base_url` | `KEENAUTH_BASE_URL` | Adresse explicite de l'API. Seule `https://<host>.keenauth.com/v1` est acceptée, ainsi que les adresses de bouclage pour les tests locaux. |

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

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

### Authentification sans clé avec `private_key_jwt`

1. Créez une application avec `app_type = "management"` et un enregistrement `keenauth_management_client` contenant les autorisations dont la configuration a besoin.
2. Enregistrez la clé publique d'une paire de clés sur l'application (`POST /v1/applications/{application_id}/credentials` avec `type: public_key`, la CLI ou le tableau de bord).
3. Donnez au fournisseur l'identifiant de l'application, la clé privée et l'émetteur :

```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
```

Pour chaque jeton de gestion, le fournisseur signe une assertion client (RFC 7523) valable 60 secondes : `iss` et `sub` valent l'identifiant client, `aud` vaut l'émetteur, `jti` est aléatoire et `kid` est l'empreinte RFC 7638 de la clé. Il échange l'assertion contre un jeton valable 10 minutes, via l'octroi `client_credentials`, et en obtient un nouveau une minute avant l'expiration de l'ancien. Le jeton ne peut jamais avoir plus d'autorisations que l'enregistrement `keenauth_management_client` de l'application. Les points de terminaison qui n'acceptent qu'une clé d'API, comme les clients de gestion, nécessitent un alias de fournisseur configuré avec `api_key`.

## Ressources

| Nom | Type | Ce qu'elle gère |
|---|---|---|
| `keenauth_application` | resource | Une application (client OAuth 2.0 / OpenID Connect). |
| `keenauth_connection` | resource | Une connexion de connexion : base de données, sans mot de passe, clé d'accès, réseau social ou entreprise. |
| [`keenauth_connection_oidc_config`](/docs/terraform/connection-oidc-config) | resource | La configuration de la partie utilisatrice d'une connexion OIDC d'entreprise, avec un secret client en écriture seule (OpenTofu ou Terraform 1.11+). Importez-la avec l'identifiant de la connexion. La destruction la retire seulement de l'état. |
| [`keenauth_environment_settings`](/docs/terraform/environment-settings) | resource | Paramètres de l'environnement : langues, sessions, inscription, notifications, récupération, authentification multifacteur, premiers facteurs. Une par environnement. |
| [`keenauth_attack_protection`](/docs/terraform/attack-protection) | resource | Protection contre les attaques : force brute, limitation par adresse IP, bourrage d'identifiants, bots, mots de passe compromis, inscription, fraude par SMS, politique de risque. Une par environnement. |
| [`keenauth_branding`](/docs/terraform/branding) | resource | Le thème de l'environnement du brouillon de personnalisation. Un par environnement. |
| [`keenauth_custom_domain`](/docs/terraform/custom-domain) | resource | Un domaine de connexion personnalisé. |
| [`keenauth_api_key`](/docs/terraform/api-key) | resource | Une clé d'API de gestion : import uniquement ; la destruction la révoque. |
| `keenauth_organization` | resource | Une organisation B2B : nom, slug, identifiant externe, métadonnées, couleur de marque et limite de membres. La destruction la supprime immédiatement ; les actions de statut (désactiver, activer, annuler la suppression) restent dans la CLI et le tableau de bord. |
| `keenauth_organization_role` | resource | Un rôle propre à une organisation et son ensemble d'autorisations (offre Business). Importez-le avec `<org_id>/<key>`. |
| [`keenauth_permission`](/docs/terraform/permission) | resource | Une autorisation (scope OAuth) d'une API avec les textes de son écran de consentement. Importez-la avec `<api_id>/<value>`. |
| [`keenauth_role`](/docs/terraform/role) | resource | Un rôle de l'environnement et son ensemble complet d'autorisations. L'attribution aux utilisateurs et aux membres ne constitue pas une ressource. |
| [`keenauth_organization_domain`](/docs/terraform/organization-domain) | resource | Un domaine d'une organisation pour la capture de domaine et le routage SSO. La vérification reste une action. |
| [`keenauth_session_policy`](/docs/terraform/organization-policies) | resource | Les durées de session d'une organisation ; plus strictes que celles de l'environnement uniquement (offre Enterprise). |
| [`keenauth_mfa_policy`](/docs/terraform/organization-policies) | resource | Les règles d'authentification multifacteur d'une organisation ; plus strictes que celles de l'environnement uniquement. |
| [`keenauth_email_template`](/docs/terraform/email-template) | resource | Le contenu publié d'un modèle d'e-mail (famille et locale) ; offre Startup. Importez-le avec `<family>/<locale>`. La destruction le retire seulement de l'état. |
| [`keenauth_management_client`](/docs/terraform/management-client) | resource | Les autorisations de l'API de gestion et la liste d'adresses IP autorisées d'une application `management`. Importez-la avec l'identifiant de l'application. |
| [`keenauth_directory`](/docs/terraform/directory) | resource | Un annuaire SCIM d'une organisation et ses paramètres de provisionnement ; `name` et les paramètres se modifient sur place, `organization_id`, `scim_host` et `type` le remplacent. Importez-le avec l'identifiant de l'annuaire. |
| [`keenauth_directory_role_mapping`](/docs/terraform/directory-role-mapping) | resource | Associe un groupe d'annuaire SCIM à un rôle ; toute modification le remplace. Importez-le avec `<directory_id>/<mapping_id>`. |
| [`keenauth_directory_token`](/docs/terraform/directory-token) | resource | Un jeton SCIM d'un annuaire, conservé dans l'état uniquement chiffré avec votre clé publique RSA ; toute modification crée un nouveau jeton, la destruction le révoque. Non importable. |
| [`keenauth_webhook_endpoint`](/docs/terraform/webhook-endpoint) | resource | Un point de terminaison webhook ; chaque argument se modifie sur place. Le secret de signature est conservé dans l'état uniquement chiffré avec votre clé publique RSA ; la modification de la clé ou de `rotation_trigger` le renouvelle. Importez-le avec l'identifiant ou la clé du point de terminaison. |
| `keenauth_application` | data source | Lit une application par `id` ou `key`. |
| `keenauth_connection` | data source | Lit une connexion par `id` ou `key`. |
| `keenauth_organization` | data source | Lit une organisation par `id` ou `slug`. |
| [`keenauth_role`](/docs/terraform/role) | data source | Lit un rôle de l'environnement par `id` ou `key`. |
| `keenauth_environment` | data source | Lit l'environnement de la clé d'API : identifiant, type, région, cellule, état et offre. |

```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]
}
```

## Import

Les applications et les connexions peuvent être importées par leur `key` ou leur identifiant, un domaine personnalisé par son nom d'hôte ou son identifiant, et une clé d'API par son identifiant :

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

Les paramètres de l'environnement, la protection contre les attaques et le brouillon de personnalisation existent une seule fois par environnement ; importez-les avec les identifiants fixes `environment-settings`, `attack-protection` et `branding`. La destruction de l'un d'eux le retire seulement de l'état.

## Modifications sûres

- Une création envoie un `Idempotency-Key`, de sorte qu'une création relancée ne crée jamais un second objet.
- Une mise à jour ou une suppression envoie un `If-Match` avec le dernier ETag lu. Si quelqu'un a modifié l'objet après la création du plan, l'API répond `412` et rien ne change. Relancez `plan`.
- Une modification effectuée dans le tableau de bord apparaît dans le `plan` suivant comme une dérive, et `apply` la rétablit. Un objet supprimé en dehors du fournisseur est retiré de l'état puis recréé.
- Une mise à jour n'envoie que les champs modifiés, sous forme de correctif de fusion JSON (RFC 7396).

## Secrets

Aucune ressource ne stocke un secret en clair dans l'état. Les secrets que vous confiez à KeenAuth sont des arguments en écriture seule (`*_wo`) : le fournisseur les envoie mais ne les écrit jamais dans les fichiers d'état ou de plan, et ne les renvoie que lorsque leur `*_wo_version` change. Ils nécessitent OpenTofu ou Terraform 1.11 ou une version ultérieure. Aujourd'hui, il s'agit du secret client d'une connexion OIDC d'entreprise (`keenauth_connection_oidc_config`). Les secrets clients et les clés de signature des applications ne sont pas gérés par cette version du fournisseur ; créez-les et renouvelez-les dans le tableau de bord ou avec la CLI. Les secrets générés par KeenAuth ne peuvent pas être en écriture seule, car un argument en écriture seule ne transporte une valeur que de la configuration vers le fournisseur. Le fournisseur ne crée jamais de clé d'API, car la clé brute finirait dans l'état : créez une clé avec la CLI, stockez-la dans votre gestionnaire de secrets et importez-la dans `keenauth_api_key` par son identifiant. Le jeton SCIM d'un annuaire n'est affiché qu'une fois par l'API ; le fournisseur révoque donc le jeton renvoyé par la création d'un annuaire et ne le conserve jamais. `keenauth_directory_token` crée le jeton pour votre fournisseur d'identité et le conserve dans l'état uniquement chiffré avec votre clé publique RSA. `keenauth_webhook_endpoint` conserve le secret de signature des webhooks de la même manière, uniquement chiffré avec sa `public_key`, et le supprime lorsqu'aucune clé n'est fournie. Les `settings` d'une connexion ne doivent contenir aucun secret ; l'API rejette les paramètres qui ressemblent à des secrets.

## Limites de cette version

- Les applications, les connexions et leur configuration OIDC, les paramètres de l'environnement, la protection contre les attaques, le thème de l'environnement du brouillon de personnalisation, les domaines personnalisés, les clés d'API (import uniquement), les organisations, les rôles et autorisations, les domaines d'organisation, les politiques de session et d'authentification multifacteur des organisations, les modèles d'e-mail, les clients de gestion, les annuaires SCIM, leurs correspondances groupe-rôle, les jetons SCIM (chiffrés avec votre clé publique) et les points de terminaison webhook sont gérés. Les hooks, les flux de journaux et les modèles de SMS arriveront dans des versions ultérieures.
- Le fournisseur ne publie pas la personnalisation ; publiez le brouillon dans le tableau de bord ou avec `keenauth branding publish`.
- Les champs facultatifs dotés d'une valeur par défaut côté serveur (par exemple `grant_types`) conservent leur dernière valeur lorsque vous les retirez de la configuration.
- Les descriptions du schéma et les messages d'erreur sont en anglais.
