구성 변경 계획

POST /v1/config-plans · 권한 config:read와 문서에 있는 각 종류의 읽기 권한

구성 문서를 환경의 현재 구성과 비교하고 결과를 계획으로 저장합니다. 아무것도 변경되지 않습니다. 계획은 문서를 적용하면 무엇이 바뀌는지만 보여 줍니다. development에서 staging 또는 production으로 승격하기 전에 검토할 때 사용하세요.

요청

필드 설명
document 필수. GET /v1/config-export 형식의 구성 문서입니다. JSON Schema https://docs.keenauth.com/config/schema/v1.json과 일치해야 합니다.
prune 선택, 기본값 false. true이면 문서에 없는 문서 종류의 리소스 삭제가 계획됩니다.

응답

201 Created, Location: /v1/config-plans/{plan_id}와 Cache-Control: no-store 포함.

필드 설명
id 계획 ID, cfgp_….
status planned, expires_at 이후에는 expired.
expires_at 계획은 1시간 동안 유효하며 만료 7일 후 삭제됩니다.
summary create, update, delete, no_op 작업 수.
changes 리소스마다 하나의 항목, 종류 순서 다음 key 순서.
warnings secret_required: 대상에 아직 없는 클라이언트 시크릿이 연결에 필요합니다.

각 변경에는 kind, key, action(create, update, delete 또는 no_op), object_version(계획 시점 대상 리소스의 버전, create에서는 null), requires_secret, fields, 그리고 create와 update에서는 원하는 spec이 있습니다. fields의 각 항목은 필드 차이입니다. pointer(RFC 6901, 예: /spec/name), op(RFC 6902와 같은 add, remove 또는 replace), before, after. 목록은 전체 값으로 비교합니다.

내보낸 문서를 변경하지 않고 보내면 리소스와 집합형 목록의 순서와 관계없이 모든 리소스가 no_op으로 계획됩니다.

{
  "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"}]
}

모든 계획은 환경의 관리 로그에 config_plan.created 항목을 기록합니다.

제한

오류

HTTP code 발생 조건
400 malformed_request, unknown_field 본문이 JSON이 아니거나 document, prune 이외의 필드가 있습니다.
401 unauthenticated 자격 증명이 없거나 유효하지 않거나 취소되었습니다.
403 insufficient_permissions 필요한 권한이 없습니다. required_permissions에 모두 나열됩니다.
413 config_document_too_large, payload_too_large 문서가 리소스 5,000개 또는 10 MiB를 넘습니다. 더 적은 종류를 계획하세요.
422 validation_failed 아래를 참조하세요. errors[].pointer는 요청 안(/document/...)을 가리킵니다.
429 rate_limited 플랜 속도 제한 또는 환경의 플랜 할당량에 도달했거나 환경이 너무 많은 플랜을 계산하고 있습니다. Retry-After 시간 후 다시 시도하세요(할당량의 경우 가장 오래된 플랜이 만료되거나 삭제될 때).
503 service_unavailable 플랜 계산 용량이 가득 찼거나 종속 서비스를 일시적으로 사용할 수 없습니다. Retry-After 시간 후 다시 시도하세요.
errors[].code 의미
required document가 없습니다.
invalid 이 포인터에서 문서가 스키마와 일치하지 않습니다.
duplicate 두 리소스의 kind와 key가 같습니다.
kind_not_listed 리소스의 종류가 kinds에 없습니다.
secret_value 비밀 값이 발견되었습니다. secret_ref 자리 표시자를 사용하세요.
unresolved_reference 참조하는 key가 변경 후에는 존재하지 않습니다.
key_in_use key가 구성으로 관리되지 않는 애플리케이션(조직 소유 또는 자체 등록) 또는 시스템 API에 속합니다.
still_referenced /prune: 남는 리소스가 계획이 삭제할 리소스를 참조합니다.
too_large 리소스, 경고 또는 최상위 필드에 JSON 값이 200,000개를 초과합니다.
too_long 연결의 settings가 32 KiB를 초과하거나, 애플리케이션의 jwks 또는 권한의 consent_text_i18n이 16 KiB를 초과합니다.
too_deep 연결의 settings가 8단계보다 깊게 중첩되어 있습니다.
reserved API identifier가 플랫폼의 urn:idp: 네임스페이스에 있습니다.

예제

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