서명 키 교체
POST /v1/signing-keys:rotate · 권한 signing-keys:write
자동 일정과 관계없이 지금 서명 키 교체를 실행합니다.
mode: immediate: 정기 교체 단계를 즉시 실행합니다. 미리 게시된next키가 서명을 시작하고, 기존active키는 7일 동안retired상태로 남으며, 새next키가 게시됩니다.next가 활성 키와 다른 알고리즘(알고리즘 변경)을 사용하고 7일 이내에 게시된 경우 호출은409 next_key_too_young와 함께 실패합니다.mode: emergency(키 유출 의심): 기존active키가 폐기되어 JWKS에서 즉시 제거됩니다.next가 활성화되고 새next가 생성됩니다.revoke_next: true는next도 폐기하고, 새로 생성되어 한 번도 게시되지 않은 키를 활성화합니다.revoke_sessions: true는 환경의 모든 세션과 리프레시 토큰 패밀리도 폐기하므로 사용자는 다시 로그인해야 합니다.reason가 필요합니다.
연합 키
use는 환경의 연합 키 중 하나를 지정할 수도 있습니다: saml_sp_signing와 saml_sp_encryption(SP 메타데이터에 게시되는 SAML 서비스 제공자 서명 및 암호화 키), 또는 oidc_rp_signing(엔터프라이즈 OIDC 연결의 private_key_jwt 키, 게시 위치 /sso/jwks.json). 이 키들은 항상 RSA-3072이며 1년에 한 번 자동으로 교체됩니다. 새 next 키는 인계 30일 전에 게시되고, 기존 키는 인계 후 30일 동안 게시 상태로 남습니다.
mode: immediate는 미리 게시된next키를 지금 활성화합니다. 기존 키는 30일 더 게시 상태로 남습니다(retired_kids에 표시됨). 게시된next키가 없으면 호출은409 conflict와 함께 실패하며,next키가 7일 이내에 게시되었다면409 next_key_too_young와 함께 실패합니다.mode: emergency는 활성 키를 메타데이터 또는 JWKS에서 즉시 제거하고 개인 키를 파기합니다(revoked_kids). 게시된next키가 활성화되며, 없거나revoke_next: true를 사용한 경우 새로 생성되어 한 번도 게시되지 않은 키가 활성화됩니다. URL에서 메타데이터 또는 JWKS를 불러오는 ID 공급자는 다음 갱신 때 변경 사항을 반영합니다. 메타데이터나 인증서를 직접 업로드한 공급자는 새 인증서를 업로드할 때까지 로그인을 거부합니다. 이 경우 영향을 받는 연결마다connection.sp_certificate_rotation_started웹훅 이벤트가 전송됩니다.
연합 키의 경우 응답의 next_kid은 null이고, removed_kids는 비어 있으며, revoke_sessions은 허용되지 않습니다. 환경에서 SAML이나 private_key_jwt를 한 번도 사용하지 않았다면 교체할 키가 없으므로 호출은 409 conflict와 함께 실패합니다.
연결 키
SAML 연결은 환경 키 대신 전용 SP 키를 가질 수 있습니다. 이 키를 교체하려면 connection_id(conn_…)를 use: saml_sp_signing 또는 saml_sp_encryption와 함께 추가합니다. 같은 모드, 권한 및 규칙이 적용되지만 해당 연결의 키 세트만 변경됩니다. 환경의 키와 다른 연결의 키는 그대로 유지되며, connection.sp_certificate_rotation_started 이벤트는 해당 연결에 대해서만 전송됩니다. 감사 기록의 대상은 환경이며, 연결은 metadata.connection_id에 기록됩니다. 알 수 없는 연결이나 다른 환경의 연결은 404 not_found와 함께 실패합니다. 환경의 키를 사용하는 연결은 409 connection_keys_not_dedicated와 함께 실패합니다(환경 키를 교체하려면 connection_id를 빼고 요청하십시오). connection_id가 없으면 환경의 키 세트가 교체됩니다.
긴급 모드에서는 signing-keys:write 외에 자격 증명에 명시적으로 부여된 signing-keys:emergency 권한이 필요합니다. 해당 권한이 있는 제한된 키 또는 M2M 클라이언트만 호출할 수 있습니다. 전체 액세스 비밀 키(idp_sk_…)는 긴급 모드에서 403 insufficient_permissions를 받습니다.
새 토큰 서명 키는 환경 정책의 알고리즘을 사용합니다(정책 조회). 토큰 서명 키 교체가 성공하면 signing_key.rotated 또는 signing_key.revoked 웹훅 이벤트가 전송되며, 모든 교체는 관리 감사 기록을 남깁니다. 이 엔드포인트는 "키 및 비밀 발급" 속도 제한 그룹에 속합니다. Idempotency-Key를 보내십시오. 네트워크 오류 후 재시도하면 두 번 교체하지 않고 첫 번째 결과를 반환합니다.
요청
JSON 본문(알 수 없는 필드는 400 unknown_field와 함께 거부됩니다):
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
Idempotency-Key |
헤더 | 아니요 | 권장합니다. A-Z a-z 0-9 _ -의 16-64자입니다. |
mode |
문자열 | 예 | immediate 또는 emergency. |
use |
문자열 | 아니요 | 교체할 키입니다. 기본값은 token_signing(액세스 및 ID 토큰 서명 키)입니다. 연합 키는 saml_sp_signing, saml_sp_encryption, oidc_rp_signing입니다(연합 키 참조). |
revoke_sessions |
불리언 | 아니요 | 긴급 및 token_signing 모드에서만 사용합니다. 모든 세션과 리프레시 토큰도 폐기합니다. 기본값은 false입니다. |
revoke_next |
불리언 | 아니요 | 긴급 모드에서만 사용합니다. 게시된 next 키도 폐기합니다. 기본값은 false입니다. |
reason |
문자열 | 긴급 모드: 예 | 긴급 모드에서만 사용합니다. 출력 가능한 ASCII 문자 1-512자이며, 예를 들어 사고 번호를 적습니다. 비밀이나 개인 정보는 입력하지 마십시오. |
connection_id |
문자열 | 아니요 | saml_sp_signing 및 saml_sp_encryption 모드에서만 사용합니다. 전용 SP 키를 가진 SAML 연결(conn_…)입니다. 환경 키 대신 이 연결의 키 세트가 교체됩니다(연결 키 참조). |
mode: immediate를 사용하여 revoke_sessions: true, revoke_next: true 또는 reason를 보내면 422와 함께 실패합니다(not_allowed). connection_id가 token_signing 또는 oidc_rp_signing와 함께 있으면 같은 방식으로 실패합니다.
응답
교체 결과를 담은 200 OK를 반환합니다. activated_kid는 이후 서명에 사용되는 키이고, next_kid는 새로 게시된 next 키입니다(연합 키의 경우 null). retired_kids은 서명을 멈추었지만 계속 게시되어 있는 키입니다(토큰 서명 키는 7일, 연합 키는 30일). revoked_kids은 긴급 교체로 JWKS에서 제거된 키입니다. removed_kids은 7일 기간이 끝나 같은 단계에서 JWKS를 떠난 폐기 키입니다.
{
"mode": "immediate",
"use": "token_signing",
"activated_kid": "ypeBEsobvcr6wjGzmiPcTaeG7_gUfE5yuYB3ha_uSLs",
"next_kid": "GKw-c0PwFokMUQ6T-TUmEWnZ4_VlQ2Qpgw-vCTT0-OQ",
"retired_kids": ["PiPoFgA5WUoziU9lZOGxNIu9egCI1CxKy3PurtWcAJ0"],
"revoked_kids": [],
"removed_kids": ["Ln0sA6lQeuJl7PW1NWiFpTOTogKdJBOUmXJloaJa78Y"],
"revoke_sessions": false
}
오류
| HTTP | 코드 | 발생 조건 |
|---|---|---|
| 400 | unknown_field |
본문에 알 수 없는 필드가 있습니다. |
| 400 | malformed_request |
본문이 올바른 JSON이 아니거나 Idempotency-Key 헤더가 잘못되었거나 중복되었습니다. |
| 403 | insufficient_permissions |
자격 증명에 signing-keys:write가 없거나, 명시적으로 부여된 signing-keys:emergency 없이 긴급 모드가 요청되었습니다. |
| 404 | not_found |
connection_id가 이 환경의 SAML 연결을 가리키지 않습니다. |
| 409 | connection_keys_not_dedicated |
connection_id가 환경의 SP 키를 사용하는 연결을 가리킵니다. |
| 409 | next_key_too_young |
알고리즘 변경이 대기 중이고 next 키가 7일 이내에 게시되었거나, (연합 키, immediate) next 키가 7일 이내에 게시되었습니다. |
| 409 | conflict |
환경에 게시된 next 키가 없거나, 연합 use의 활성 키가 없거나, 이전 연합 키가 아직 30일 중첩 기간 중입니다. |
| 415 | unsupported_media_type |
콘텐츠 타입이 application/json가 아닙니다. |
| 422 | validation_failed |
필드가 없거나 잘못되었습니다. 포인터가 해당 필드를 가리킵니다(예: /reason). |
| 422 | idempotency_key_reuse |
Idempotency-Key가 다른 본문과 함께 이미 사용되었습니다. |
| 501 | not_implemented |
이 배포에서는 아직 사용할 수 없는 작업입니다. |
| 401 | unauthenticated |
자격 증명이 없거나, 잘못되었거나, 폐기되었습니다. |
| 429 | rate_limited |
속도 제한을 초과했습니다. Retry-After 기간 이후에 다시 시도하십시오. |
| 503 | service_unavailable |
종속 서비스를 일시적으로 사용할 수 없습니다. Retry-After 기간 이후에 다시 시도하십시오. |
예시
정기 교체:
curl -X POST "https://api.eu.keenauth.com/v1/signing-keys:rotate" \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"mode":"immediate"}'
signing-keys:write와 signing-keys:emergency를 부여한 제한된 키로 긴급 교체:
curl -X POST "https://api.eu.keenauth.com/v1/signing-keys:rotate" \
-H "Authorization: Bearer $KEENAUTH_EMERGENCY_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"mode":"emergency","revoke_sessions":true,"reason":"INC-2041 key exposure"}'
게시된 next 키도 폐기하면서 SAML SP 서명 키를 긴급 교체:
curl -X POST "https://api.eu.keenauth.com/v1/signing-keys:rotate" \
-H "Authorization: Bearer $KEENAUTH_EMERGENCY_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"mode":"emergency","use":"saml_sp_signing","revoke_next":true,"reason":"INC-2042 SP key exposure"}'
한 연결의 전용 SAML SP 서명 키를 긴급 교체:
curl -X POST "https://api.eu.keenauth.com/v1/signing-keys:rotate" \
-H "Authorization: Bearer $KEENAUTH_EMERGENCY_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"mode":"emergency","use":"saml_sp_signing","connection_id":"conn_01h2xcejqtf2nbrexx3vqjhp41","reason":"INC-2043 connection key exposure"}'