
# 구성 내보내기

`GET /v1/config-export` · 권한 `config:read` 및 내보내는 각 종류의 읽기 권한

환경의 구성을 환경에 종속되지 않는 하나의 문서로 반환하므로, 검토하거나 버전 관리에 보관하거나 나중에 다른 환경에 적용할 수 있습니다. 이 문서에는 환경별 ID, 버전, 타임스탬프 또는 비밀 값이 포함되지 않습니다. 리소스는 `key`으로 서로를 참조합니다. 같은 구성은 항상 바이트 단위로 동일한 문서를 생성합니다(종류는 아래 순서대로, 그다음 `key` 순으로 정렬하며, 집합형 목록은 정렬됩니다). 응답은 JSON이며 이는 유효한 YAML이기도 합니다. `keenauth config export`는 기본적으로 YAML을 출력합니다.

## 요청

환경은 자격 증명에서 결정됩니다. 유일한 쿼리 매개변수는 선택 사항입니다.

| 매개변수 | 설명 |
|---|---|
| `kinds` | 내보낼 종류를 쉼표로 구분하여 지정합니다(예: `kinds=connection,api`). 지정하지 않으면 모든 종류를 내보냅니다. |

| 종류 | `key` | `config:read` 외 권한 |
|---|---|---|
| `environment_settings` | `default` | `environment-settings:read` |
| `identity_settings` | `default` | `identity-settings:read` |
| `attack_protection` | `default` | `attack-protection:read` |
| `branding` | `default` | `branding:read` |
| `connection` | 연결 `key` | `connections:read` |
| `api` | API `key` | `apis:read`, `applications:read` |
| `role` | 역할 `key` | `roles:read`, `apis:read` |
| `application` | 애플리케이션 `key` | `applications:read`, `apis:read`, `connections:read` |
| `application_branding` | 애플리케이션 `key` | `branding:read`, `applications:read` |

`api`, `role` 및 `application`도 참조하는 종류의 권한이 필요합니다. 참조는 `key`로 해석되기 때문입니다. `config:read`만으로는 리소스 읽기 권한이 부여되지 않습니다.

## 응답

`200 OK` 응답은 `Cache-Control: no-store`과 함께 반환됩니다.

- 참조는 `key` 형태로 표시됩니다: `application.default_api`, `application.connections`(버튼 순서 유지), `application.api_grants[].api` 및 `api.introspection_applications`.
- 엔터프라이즈 OIDC 연결은 페더레이션 자료를 `oidc`로 포함합니다(`issuer`, `client_id`, `client_auth_method`, `provider_profile`). 리디렉션 URI, SP 호스트 및 비밀 값 자체는 환경별 값이므로 내보내지 않으며, 아직 자료가 작성되지 않은 경우 `oidc`는 `null`입니다. 적용하는 문서에서 `oidc: null`는 자료를 변경하지 않은 상태로 둡니다. Entra 테넌트 ID는 읽을 수 없으므로 `entra` 프로필을 사용하는 연결은 아직 문서로 관리할 수 없습니다.
- 비밀 값은 절대 내보내지 않습니다. 사용자가 KeenAuth에 제공한 비밀 값(소셜 또는 엔터프라이즈 OIDC 연결의 `client_secret`)은 플레이스홀더 `{"secret_ref": {"source": "env", "name": "KEENAUTH_CONNECTION_<KEY>_CLIENT_SECRET"}}`로 표시되며, 문서를 적용할 때 CLI가 해당 환경 변수에서 값을 읽습니다. 다른 연결은 `"client_secret": null`를 갖습니다. KeenAuth가 발급하는 비밀 값(애플리케이션 클라이언트 시크릿, API 키, 웹훅 서명 비밀 값)과 개인 키는 전혀 내보내지 않으며, 대상 환경이 자체적으로 발급합니다. `jwks`에는 공개 키만 포함됩니다.
- 내장 시스템 API는 모든 환경에 존재하므로 내보내지 않습니다. 조직이 소유한 애플리케이션과 클라이언트가 직접 등록한 애플리케이션(동적 클라이언트 등록, 클라이언트 ID 메타데이터 문서)도 내보내지 않습니다. 각 항목은 `warnings`에 코드 `resource_skipped`와 함께 나열됩니다.
- 해석할 수 없는 참조(예: 건너뛴 애플리케이션에 대한 참조)는 문서에서 제거되며 `warnings`에 코드 `reference_dropped` 및 JSON `pointer`와 함께 나열됩니다.
- `attack_protection`는 [공격 방어 교체](../attack-protection/put.md)로 작성한 객체이며, 실제 적용 값이 아닙니다. 모든 섹션과 필드가 작성되며, `null`는 설정되지 않음을 뜻하므로 대상 환경이 자체 기본값, 보안 하한선 및 요금제를 적용합니다. 따라서 승격 시 원본의 기본값이 고정되지 않습니다. 대상 환경의 요금제에 작성된 설정(예: `risk_policy.mode: enforce`)이 포함되지 않으면 계획 적용은 `403 plan_feature_unavailable`와 함께 실패하며 아무것도 기록되지 않습니다.
- `role`는 환경 역할입니다. 이 역할은 `name`, `description`, `is_privileged`, `assignable_in_self_service` 및 `permissions`로 구성되며, 각 권한은 `{"api": "<API key>", "value": "<permission value>"}`로 작성됩니다(ID는 환경별 값이므로 표시되지 않습니다). 내장 역할 `admin` 및 `member`는 읽기 전용입니다. 이들은 내보내지 않으며 `warnings`에 코드 `resource_skipped` 및 사유 `system_role`와 함께 나열됩니다. 문서로는 이들을 생성, 변경 또는 삭제할 수 없습니다(`422`, `key_in_use`). 조직 역할은 설정이 아닌 데이터이므로 내보내지 않습니다. 역할은 내장 시스템 API의 권한을 참조할 수 있습니다. 여전히 할당된 역할을 삭제하면 실패하므로, 먼저 할당을 해제하십시오.
- `branding`는 환경의 초안 테마, 사용자 지정 CSS 및 페이지 템플릿입니다. `application_branding`는 애플리케이션의 초안 테마이며, 테마가 있는 애플리케이션에만 나타납니다. 텍스트 재정의와 조직 테마는 아직 내보내지 않습니다.
- 두 플레이스홀더의 변수 이름이 같아지는 경우(`-`와 `_`에서만 다른 키), 두 리소스 모두 코드 `secret_ref_name_shared`와 함께 `warnings`에 나열됩니다. 파일에서 변수 중 하나의 이름을 바꾸십시오.
- 문서의 JSON 스키마는 `https://docs.keenauth.com/config/schema/v1.json`에 게시되어 있으며, 자동 완성과 검증을 위해 편집기에서 이를 지정하십시오.

```json
{
  "apiVersion": "config.keenauth.com/v1",
  "kinds": ["connection", "api", "application"],
  "resources": [
    {"kind": "connection", "key": "db", "spec": {"type": "database", "strategy": "password", "name": "db", "display_name": null, "status": "active", "settings": {}, "client_secret": null}},
    {"kind": "api", "key": "orders", "spec": {"identifier": "https://api.example.com/orders", "name": "Orders", "access_token_lifetime_s": 3600, "token_format": "jwt", "rbac_mode": "off", "allow_offline_access": false, "require_resource_indicator": false, "dpop_required": false, "mcp_profile": false, "first_party_access": "all", "introspection_applications": [], "permissions": [{"value": "orders:read", "display_name": null, "description": null, "consent_text_i18n": {}, "sensitivity": "normal"}]}},
    {"kind": "application", "key": "web", "spec": {"name": "Web", "app_type": "spa", "default_api": "orders", "connections": ["db"], "api_grants": [{"api": "orders", "scopes": ["orders:read"], "default_scopes": []}], "redirect_uris": ["https://app.example.com/callback"]}}
  ],
  "warnings": [
    {"code": "resource_skipped", "kind": "application", "key": "partner-bot", "reason": "organization_owned"}
  ]
}
```

위 `application` 사양은 축약되었습니다. 전체 필드 목록은 API 참조에 있습니다.

## 오류

| HTTP | 코드 | 발생 시점 |
|---|---|---|
| 401 | `unauthenticated` | 자격 증명이 없거나 잘못되었거나 취소되었습니다. |
| 403 | `insufficient_permissions` | 자격 증명에 필요한 권한이 없습니다. `required_permissions`에 필요한 모든 권한이 나열됩니다. |
| 413 | `config_document_too_large` | 문서가 리소스 5,000개 또는 10 MiB를 초과합니다. `kinds`로 더 적은 종류를 내보내십시오. |
| 422 | `validation_failed` | `kinds`가 반복되거나, 256자를 초과하거나, 알 수 없는 종류를 지정합니다. |
| 429 | `rate_limited` | 요청 한도를 초과했습니다. `Retry-After` 기간 후에 다시 시도하십시오. |
| 503 | `service_unavailable` | 종속 서비스를 일시적으로 사용할 수 없습니다. `Retry-After` 기간 후에 다시 시도하십시오. |

## 예제

```bash
curl "https://api.eu.keenauth.com/v1/config-export?kinds=connection,api,application" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY"

keenauth config export --kinds connection,api,application > keenauth.yaml
```
