
# keenauth_directory_token

El recurso `keenauth_directory_token` crea un token portador SCIM de un directorio para el proveedor de identidad que aprovisiona en él usuarios y grupos. El proveedor guarda el token en el estado solo cifrado con una clave pública RSA que usted le indica.

```terraform
resource "keenauth_directory_token" "okta" {
  directory_id    = keenauth_directory.acme_okta.id
  label           = "Okta"
  expires_in_days = 180
  public_key      = file("${path.module}/scim-token-key.pub.pem")

  lifecycle {
    create_before_destroy = true
  }
}

output "okta_scim_token_encrypted" {
  value = keenauth_directory_token.okta.encrypted_token
}
```

## El token nunca se guarda en texto plano

La API devuelve un token SCIM una sola vez, en la respuesta que lo crea, y después ningún endpoint puede leerlo. El proveedor cifra el token con su clave pública (RSA-OAEP con SHA-256, MGF1 con SHA-256 y una etiqueta vacía) y escribe en `encrypted_token` solo el texto cifrado en base64. El token en texto plano nunca llega al estado, a un archivo de plan, a una salida ni a un registro. Solo quien tiene la clave privada puede descifrarlo; por eso, un archivo de estado filtrado no filtra el token.

Cree el par de claves una vez, fuera de OpenTofu, y mantenga la clave privada fuera de su configuración:

```shell
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out scim-token-key.pem
openssl pkey -in scim-token-key.pem -pubout -out scim-token-key.pub.pem
```

Después de `tofu apply`, descifre el token y entréguelo al proveedor de identidad:

```shell
tofu output -raw okta_scim_token_encrypted | base64 -d | \
  openssl pkeyutl -decrypt -inkey scim-token-key.pem \
    -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256
```

`public_key` debe ser una clave pública RSA codificada en PEM (`PUBLIC KEY` o `RSA PUBLIC KEY`) de al menos 2048 bits. Una clave privada o una clave más pequeña se rechaza en la fase de plan. Si el proveedor no puede entregar un token, lo revoca de inmediato y el apply falla, así que no existe ningún token válido que nadie posea.

## Solo crear y revocar

Un token no se puede modificar. Cada argumento (`directory_id`, `label`, `expires_in_days`, `public_key`) crea un token nuevo cuando lo cambia, y el token anterior se revoca. Destruir el recurso revoca el token.

Un token revocado fuera del proveedor, o caducado, se elimina del estado en la siguiente actualización, y el siguiente apply crea uno nuevo. Eliminar el directorio elimina sus tokens.

## Rotación

Un directorio tiene como máximo 2 tokens válidos; un tercero se rechaza con `409`. Eso basta para rotar sin tiempo de inactividad: con `create_before_destroy = true`, el token nuevo se crea antes de revocar el anterior. Entregue el token nuevo al proveedor de identidad en la misma ventana de cambio.

## Argumentos

- `label` tiene de 1 a 100 caracteres, sin caracteres de control ni espacios al principio o al final. El valor por defecto de la API es `Token`.
- `expires_in_days` va de 30 a 730. El valor por defecto de la API es 365.
- `encrypted_token`, `created_at`, `expires_at` e `id` son de solo lectura.

## Importación

El recurso no se puede importar: el valor de un token existente no se puede volver a leer, así que un token importado no podría entregarse. Revoque un token antiguo con `keenauth directories tokens delete <directory_id> <token_id>` y deje que el proveedor cree uno nuevo.
