Planificar un cambio de configuración

POST /v1/config-plans · permiso config:read y el permiso de lectura de cada tipo del documento

Compara un documento de configuración con la configuración actual del entorno y guarda el resultado como un plan. No se cambia nada: un plan solo muestra lo que haría aplicar el documento. Úsalo para revisar una promoción de development a staging o production antes de aplicarla.

Solicitud

Campo Descripción
document Obligatorio. Un documento de configuración con el formato de GET /v1/config-export. Debe cumplir el JSON Schema https://docs.keenauth.com/config/schema/v1.json.
prune Opcional, false por defecto. Si es true, se planifica eliminar los recursos de los tipos del documento que faltan en el documento.

Respuesta

201 Created con Location: /v1/config-plans/{plan_id} y Cache-Control: no-store.

Campo Descripción
id ID del plan, cfgp_….
status planned; expired después de expires_at.
expires_at El plan es válido durante 1 hora. Se elimina 7 días después de caducar.
summary Número de acciones create, update, delete y no_op.
changes Una entrada por recurso, en orden de tipo y luego por key.
warnings secret_required: la conexión necesita un client secret que el destino aún no tiene.

Cada cambio tiene kind, key, action (create, update, delete o no_op), object_version (la versión del recurso de destino al planificar; null en create), requires_secret, fields y, en create y update, el spec deseado. Cada entrada de fields es una diferencia de campo: pointer (RFC 6901, por ejemplo /spec/name), op (add, remove o replace, como en RFC 6902), before y after. Las listas se comparan como valores completos.

Un documento exportado enviado sin cambios planifica no_op para cada recurso, sea cual sea el orden de los recursos y de las listas de tipo conjunto.

{
  "id": "cfgp_01m4qpqtywfs7930tb6kqn5rc5",
  "status": "planned",
  "prune": false,
  "kinds": ["connection"],
  "expires_at": "2026-10-12T11:00:00Z",
  "summary": {"create": 1, "update": 1, "delete": 0, "no_op": 1},
  "changes": [
    {"kind": "connection", "key": "db", "action": "no_op", "object_version": 5, "requires_secret": false, "fields": []},
    {"kind": "connection", "key": "github", "action": "create", "object_version": null, "requires_secret": true, "fields": [], "spec": {"type": "social", "strategy": "github", "name": "GitHub", "display_name": null, "status": "active", "settings": {}, "client_secret": {"secret_ref": {"source": "env", "name": "KEENAUTH_CONNECTION_GITHUB_CLIENT_SECRET"}}}},
    {"kind": "connection", "key": "google", "action": "update", "object_version": 4, "requires_secret": false, "fields": [{"pointer": "/spec/name", "op": "replace", "before": "Google", "after": "Google Workspace"}], "spec": {"type": "social", "strategy": "google", "name": "Google Workspace", "display_name": null, "status": "active", "settings": {}, "client_secret": {"secret_ref": {"source": "env", "name": "KEENAUTH_CONNECTION_GOOGLE_CLIENT_SECRET"}}}}
  ],
  "warnings": [{"code": "secret_required", "kind": "connection", "key": "github", "pointer": "/spec/client_secret"}]
}

Cada plan escribe una entrada config_plan.created en el registro de gestión del entorno.

Límites

Errores

HTTP code Cuándo
400 malformed_request, unknown_field El cuerpo no es JSON o tiene un campo distinto de document y prune.
401 unauthenticated Las credenciales faltan, no son válidas o se revocaron.
403 insufficient_permissions A las credenciales les falta un permiso necesario; required_permissions los enumera todos.
413 config_document_too_large, payload_too_large El documento supera los 5000 recursos o 10 MiB; planifica menos tipos.
422 validation_failed Consulta abajo; errors[].pointer apunta dentro de la solicitud (/document/...).
429 rate_limited Se alcanzó el límite de frecuencia de planes o la cuota de planes del entorno, o el entorno está calculando demasiados planes; vuelve a intentarlo tras el periodo Retry-After (en la cuota, cuando el plan más antiguo caduque o se elimine).
503 service_unavailable El cálculo de planes está al límite de capacidad o una dependencia no está disponible temporalmente; vuelve a intentarlo tras el periodo Retry-After.
errors[].code Significado
required Falta document.
invalid El documento no cumple el esquema en este puntero.
duplicate Dos recursos tienen el mismo kind y key.
kind_not_listed El tipo del recurso no está en kinds.
secret_value Se encontró un valor secreto; usa un marcador secret_ref.
unresolved_reference La key referenciada no existiría después del cambio.
key_in_use La key pertenece a una aplicación que no se gestiona con configuración (propiedad de una organización o autorregistrada) o a la API del sistema.
still_referenced /prune: un recurso que se mantiene hace referencia a un recurso que el plan eliminaría.
too_large Un recurso, una advertencia o un campo de nivel superior tiene más de 200.000 valores JSON.
too_long Los settings de una conexión superan 32 KiB, o los jwks de una aplicación o el consent_text_i18n de un permiso superan 16 KiB.
too_deep Los settings de una conexión tienen más de 8 niveles de anidamiento.
reserved El identifier de la API está en el espacio de nombres urn:idp: de la plataforma.

Ejemplo

curl -X POST "https://api.eu.keenauth.com/v1/config-plans" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"document\": $(cat keenauth.json), \"prune\": false}"

keenauth config plan -f keenauth.yaml