
# 연결의 리비전 목록 조회

`GET /v1/connections/{connection_id}/revisions` · 권한 `connections:read`

엔터프라이즈(SAML 또는 OIDC) 연결의 리비전을 최신순으로 나열합니다. 대기 중인 초안(최대 1개)과 최근 90일 이내에 게시되었거나 폐기된 리비전이 포함됩니다.

**활성** 연결에서 보안상 중요한 변경은 바로 적용되지 않습니다. 대신 **초안 리비전**이 되며, 초안을 테스트하고 게시하기 전까지 실시간 구성은 그대로 유지됩니다.

- ID 공급자의 엔티티 ID 또는 SSO URL을 변경하거나 서명 고정을 제거하는 SAML 메타데이터 가져오기([메타데이터 가져오기](import-metadata.md));
- OIDC `issuer` 또는 `client_id` 변경([OIDC 구성 설정](../connection-oidc/put.md));
- 연결 상태와 관계없이 모든 SP 호스트 마이그레이션([SP 호스트 마이그레이션](migrate-sp-host.md)).

초안은 [연결 테스트](test.md)에서 `revision_id`로 테스트한 후 [게시](publish-revision.md)하십시오. 새 초안을 만들면 이전 초안은 폐기됩니다(`discard_reason: superseded`).

리비전에는 새로운 비밀이 아닌 값만 표시됩니다(`changes`). 새 OIDC 클라이언트 비밀은 `client_secret_change`(`keep`, `replace` 또는 `clear`)로만 나타나며, 비밀 값과 마지막 몇 글자는 반환되지 않습니다. 리비전을 만들거나 승인한 사용자는 여기가 아니라 관리 감사 로그(`connection.revision_created`, `connection.revision_published`)에 기록됩니다.

## 요청

| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
| `connection_id` | path | 예 | 엔터프라이즈 연결 ID(`conn_…`). |
| `limit` | query | 아니요 | 페이지 크기, 1–100(기본값 20). |
| `after` | query | 아니요 | `list_metadata.after`의 커서. 커서는 이를 생성한 연결에서만 사용할 수 있습니다. |

목록은 앞으로만 페이지 이동할 수 있습니다. `before`와 `order`는 지원되지 않습니다(`422`).

## 응답

`200 OK`:

```json
{
  "data": [
    {
      "id": "connrev_01j9xr8c2d4e6f8g0h2j4k6m8n",
      "connection_id": "conn_01j9xp6q0r1s5t7v9w1x3y5z7b",
      "protocol": "saml",
      "kind": "sp_host",
      "status": "draft",
      "discard_reason": null,
      "created_at": "2026-10-28T10:00:00Z",
      "decided_at": null,
      "purge_after": null,
      "superseded_revision_id": null,
      "changes": {
        "sp_host": "login.example.com",
        "idp_entity_id": null,
        "idp_sso_url": null,
        "idp_slo_url": null,
        "certificate_fingerprints": [],
        "mfa_authn_context_values": null,
        "issuer": null,
        "client_id": null,
        "client_auth_method": null,
        "provider_profile": null,
        "client_secret_change": null
      },
      "latest_test": {
        "test_id": "conntest_01j9xr4a6b8c0d2e4f6g8h0j2k",
        "status": "passed",
        "failure_reason": null,
        "started_at": "2026-10-28T10:05:00Z",
        "completed_at": "2026-10-28T10:06:00Z"
      }
    }
  ],
  "list_metadata": { "before": null, "after": null }
}
```

| 필드 | 설명 |
|---|---|
| `kind` | `configuration`(ID 공급자 또는 OIDC 클라이언트 변경) 또는 `sp_host`(SP 호스트 마이그레이션). |
| `status` | `draft`(테스트 및 게시 대기 중), `published` 또는 `discarded`. |
| `decided_at` / `purge_after` | 리비전이 게시되거나 폐기된 시점과 삭제되는 시점(90일 후). 초안의 경우 `null`. |
| `changes` | 새 값입니다. 리비전이 변경하지 않는 필드는 `null`입니다. |
| `latest_test` | 지난 24시간 동안 이 리비전에 대해 수행된 최신 테스트 로그인, 없으면 `null`. 게시하려면 `passed` 상태여야 합니다. |

## 오류

| HTTP | code | 발생 조건 |
|---|---|---|
| 400 | `invalid_cursor` | 커서 형식이 잘못되었거나 다른 연결 또는 쿼리에 속합니다. |
| 401 | `unauthenticated` | 자격 증명이 없거나 잘못되었거나 취소되었습니다. |
| 403 | `insufficient_permissions` | 자격 증명에 `connections:read` 권한이 없습니다. |
| 404 | `not_found` | 이 환경에 연결이 없거나 엔터프라이즈 연결이 아닙니다. |
| 422 | `validation_failed` | 쿼리 매개변수가 잘못되었습니다(예: `limit`이 100을 초과하거나 `before` 사용). |
| 429 | `rate_limited` | 요청 한도를 초과했습니다. `Retry-After` 기간 이후에 다시 시도하십시오. |
| 503 | `service_unavailable` | 종속 서비스를 일시적으로 사용할 수 없습니다. `Retry-After` 기간 이후에 다시 시도하십시오. |

## 예시

```bash
curl "https://api.eu.keenauth.com/v1/connections/conn_01j9xp6q0r1s5t7v9w1x3y5z7b/revisions?limit=20" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY"
```

```bash
keenauth connections revisions list conn_01j9xp6q0r1s5t7v9w1x3y5z7b --limit 20
```
