구성 계획 적용
POST /v1/config-plans/{plan_id}:apply · 권한 config:write, 계획의 읽기 권한과 변경되는 각 종류의 쓰기 권한
저장된 계획을 환경에 적용합니다. 모든 변경은 하나의 트랜잭션으로 기록됩니다. 하나라도 실패하면 아무것도 저장되지 않습니다. 계획은 한 번만 적용할 수 있습니다.
요청
| 매개변수 | 설명 |
|---|---|
plan_id |
계획 ID, cfgp_…. |
요청 본문은 선택 사항입니다.
| 필드 | 설명 |
|---|---|
resolved_secrets |
requires_secret: true이 있는 모든 변경에 대한 secret_ref 이름 → 값 객체입니다(예: KEENAUTH_CONNECTION_GITHUB_CLIENT_SECRET). 값은 최대 8 KiB입니다. 계획에서 저장되거나 기록되거나 반환되지 않습니다. |
confirm_deletions |
확인하는 <kind>/<key> 삭제 목록입니다(예: connection/legacy). 계획의 deletion_requires_confirmation 경고에 이 확인이 필요한 삭제가 나열됩니다. |
sp_host |
환경의 서비스 제공자 호스트입니다(예: login.example.com). 계획이 엔터프라이즈 연결의 OIDC 자료를 생성할 때만 필요합니다(콜백 https://<sp_host>/sso/<connection id>/callback이 이 값으로 고정됩니다). 필요하지 않은 요청에서는 보내지 않아야 합니다. |
- 쓰기 권한은
environment-settings:write,identity-settings:write,attack-protection:write,branding:write(branding및application_branding의 경우),connections:write,apis:write,roles:write및applications:write이며,no_op이외의 변경이 있는 종류에만 필요합니다. - 쓰기 전에 대상을 다시 읽습니다. 계획이 만들어진 후 계획된 리소스의 버전이나 계획 종류의 내용이 변경되었다면 아무것도 기록되지 않고, 계획은
conflicted상태가 되며 요청은409 config_conflict로 실패합니다. 새 계획을 만드십시오.prune를 사용하면 계획된 리소스를 참조하는 종류도 비교되며, 리소스 간 참조가 다시 확인됩니다. 깨진 참조 역시 계획을conflicted상태로 만듭니다. - 연결 또는 지난 30일 이내에 토큰을 받은 애플리케이션을 삭제하는 경우
confirm_deletions에 반복해서 입력해야 합니다. 그렇지 않으면 요청은409 deletion_not_confirmed로 실패하고 계획은planned상태로 남습니다. - 엔터프라이즈 연결의 OIDC 자료(
spec.oidc)와 클라이언트 비밀은 연결 레코드 다음에 페더레이션 서비스에 기록됩니다. 두 번째 기록이 거부되면 계획은planned상태로 남고, 연결 레코드는 이미 존재할 수 있으며, 새 계획은 누락된 자료만 기록합니다.null의spec.oidc은 자료를 변경하지 않습니다. 소셜 연결의 클라이언트 비밀은 아직 기록할 수 없습니다. 그러한requires_secret변경이 있는 계획은 비밀을 확인한 후501 not_implemented를 반환합니다. 아무것도 기록되지 않습니다. Idempotency-Key를 지원합니다. 가능하면 본문에 비밀을 포함하지 않고 보내십시오. 키의 레코드에는 본문의 해시가 저장됩니다.
응답
200 OK와 Cache-Control: no-store를 함께 반환합니다: 구성 계획 조회 형식의 계획이며 status: applied 및 applied_at가 포함됩니다.
변경 전 영향을 받은 리소스의 구성은 리비전으로 보관됩니다(환경당 최신 50개, 최대 90일). 적용 시 생성, 수정, 삭제, 변경되지 않은 리소스 수를 담은 config.applied 항목 하나를 환경의 관리 로그에 기록합니다. 변경된 각 리소스도 자체 항목을 기록합니다.
오류
| HTTP | 코드 | 발생 시점 |
|---|---|---|
| 400 | malformed_request, unknown_field |
본문이 JSON이 아니거나 resolved_secrets, confirm_deletions, sp_host 이외의 필드가 있는 경우입니다. |
| 401 | unauthenticated |
자격 증명이 없거나 잘못되었거나 취소된 경우입니다. |
| 403 | insufficient_permissions |
자격 증명에 필요한 권한이 없습니다. required_permissions에 모든 권한이 나열됩니다. |
| 404 | not_found |
계획이 없거나 다른 환경에 속하거나 삭제되었습니다. |
| 409 | config_conflict |
계획이 만들어진 후 대상이 변경되었습니다. 계획은 이제 conflicted 상태입니다. |
| 409 | config_plan_not_applicable |
계획이 이미 적용되었거나 conflicted 상태이거나, 다른 요청이 지금 적용 중입니다(plan_status: applying). plan_status에서 상태를 확인할 수 있습니다. |
| 409 | deletion_not_confirmed |
보호된 삭제가 confirm_deletions에 없습니다. unconfirmed_deletions에 나열됩니다. |
| 409 | conflict |
다른 리소스가 변경의 고유 값을 이미 사용하고 있습니다(errors[].pointer은 /changes/<i>/spec/<field>, 코드 duplicate); 계획은 planned 상태로 남습니다. |
| 409 | connection_in_use |
삭제할 연결이 아직 사용 중입니다. 계획은 planned 상태로 남습니다. |
| 409 | connection_test_required |
변경이 enterprise 연결 active을 생성하거나, 테스트 로그인에 성공하지 않은 연결을 활성화합니다(errors[].pointer은 /changes/<i>/spec, 코드 test_required); 계획은 planned 상태로 남습니다. |
| 410 | config_plan_expired |
계획의 유효 시간이 지났습니다. 새 계획을 만드십시오. |
| 413 | config_document_too_large |
변경 사항이나 이에 대해 보관된 리비전(최대 10 MiB)이 한 요청으로 적용하기에 너무 큽니다. 종류를 줄여 계획하십시오. |
| 422 | validation_failed |
아래를 참조하십시오. |
| 422 | policy_conflict |
변경이 환경 정책과 충돌합니다. 계획은 planned 상태로 남습니다. |
| 429 | rate_limited |
config_plan 속도 제한(계획 생성과 공유)을 초과했거나, 이 환경에 대해 한 번에 계산 또는 적용 중인 계획이 너무 많습니다. 계획은 planned 상태로 남으며, Retry-After 기간 후에 다시 시도하십시오. |
| 501 | not_implemented |
계획에 아직 기록할 수 없는 소셜 연결의 클라이언트 비밀이 필요합니다. |
| 503 | service_unavailable |
종속 서비스(디렉터리 또는 엔터프라이즈 OIDC 자료의 경우 페더레이션 서비스)를 일시적으로 사용할 수 없거나 계획 용량이 일시적으로 찼습니다. 아무것도 기록되지 않았거나, 페더레이션 서비스의 경우 연결 레코드만 기록되었습니다. Retry-After 기간 후에 다시 시도하십시오. |
errors[].pointer |
errors[].code |
의미 |
|---|---|---|
/resolved_secrets/<NAME> |
secret_missing |
계획에 이 비밀이 필요합니다. |
/resolved_secrets/<NAME> |
secret_unused |
계획에 이 비밀이 필요하지 않습니다. |
/resolved_secrets/<NAME> |
secret_invalid |
값이 비어 있거나, 8 KiB보다 길거나, 텍스트가 아닙니다. |
/resolved_secrets/<NAME> |
invalid |
이름이 KEENAUTH_… 형식이 아닙니다(A-Z, 0-9, _). |
/sp_host |
sp_host_required, sp_host_unused, invalid |
계획이 OIDC 자료를 생성하는데 호스트가 주어지지 않았거나, 호스트가 필요하지 않거나, 호스트가 소문자 DNS 이름이 아닙니다. |
/changes/<i>/spec/oidc/... |
연결 OIDC API와 동일 | 페더레이션 서비스가 계획의 changes에서 이 위치의 자료를 거부했습니다. |
/confirm_deletions/<i> |
duplicate, not_a_deletion |
항목이 반복되었거나 계획에서 삭제가 아닙니다. |
/confirm_deletions/<i> |
invalid |
항목이 <kind>/<key> 형식이 아닙니다. |
/resolved_secrets, /confirm_deletions |
too_many |
5,000개를 초과하는 항목입니다. |
/changes/<i>/spec/... |
리소스 고유 API와 동일 | 환경이 계획의 changes에서 이 위치의 변경을 거부했습니다. |
예제
curl -X POST "https://api.eu.keenauth.com/v1/config-plans/cfgp_01m4qpqtywfs7930tb6kqn5rc5:apply" \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"confirm_deletions": ["connection/legacy"]}'
keenauth config apply cfgp_01m4qpqtywfs7930tb6kqn5rc5 --confirm-deletion connection/legacy
keenauth config apply --secrets-from-env는 계획에 필요한 각 비밀을 같은 이름의 환경 변수에서 읽으며, 이를 출력하지 않습니다.