애플리케이션 생성
POST /v1/applications · 권한 applications:write
호출 키가 속한 환경에 애플리케이션(OAuth/OIDC 클라이언트)을 생성합니다. key, name, app_type, party는 필수이며, 그 밖의 필드에는 애플리케이션 유형에서 파생된 안전한 기본값이 적용됩니다. 응답에는 ETag가 포함되며, 수정하거나 삭제할 때 이 값을 If-Match로 보내야 합니다. 이 작업은 클라이언트 비밀을 생성하지 않습니다. 비밀과 키는 애플리케이션 자격 증명 엔드포인트에서 관리합니다.
요청
본문 (application/json). 알 수 없는 필드는 거부됩니다. 필수 필드는 key, name, app_type, party뿐입니다.
| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
key |
string | 예 | 안정적인 구성 키이며, ^[a-z0-9_-]{1,64}$ 형식이고 환경 내에서 고유해야 합니다. 생성 시 필수이며, 이후에는 변경할 수 없습니다. |
name |
string | 예 | 표시 이름이며, 1~100자입니다. |
app_type |
string | 예 | web, spa, native, m2m, device 또는 management입니다. 생성 시 필수이며, 이후에는 변경할 수 없습니다. |
party |
string | 예 | first_party 또는 third_party입니다. 생성 시 필수이며, first_party에서 third_party로만 변경할 수 있습니다. |
owner_org_id |
string 또는 null | 아니요 | 소유 조직의 org_… ID입니다. m2m 애플리케이션에만 사용하며, 변경할 수 없습니다. |
status |
string | 아니요 | active 또는 suspended입니다. 일시 중지된 애플리케이션은 새 토큰을 발급받을 수 없습니다. |
allowed_web_origins |
string[] | 아니요 | 허용되는 CORS 출처(https://host[:port])이며, 최대 20개이고 와일드카드는 사용할 수 없습니다. |
organization_usage |
string | 아니요 | deny, allow 또는 require입니다. organization 인가 매개변수(org_… ID 또는 조직의 슬러그)를 제어합니다. deny는 이를 거부하고, allow는 선택 사항으로 만들며, require는 필수로 만듭니다. 토큰에는 사용자의 멤버십이 확인된 후에만 org_id가 포함됩니다. |
org_access_mode |
string | 아니요 | 조직 로그인 접근 방식입니다. all_organizations(기본값, 모든 조직의 모든 멤버), enabled_organizations(애플리케이션이 활성화된 조직만) 또는 assigned_only(추가로 할당된 멤버십 또는 디렉터리 그룹만)입니다. 자세한 내용은 조직 애플리케이션을 참조하십시오. |
registration_mode |
string 또는 null | 아니요 | open, invite_only 또는 closed입니다. 비워 두면 환경 설정을 상속합니다. |
registration_source |
string | 아니요 | 생성 시 dashboard 또는 management_api입니다(기본값 management_api). 변경할 수 없습니다. 응답에는 dcr 또는 cimd도 표시될 수 있습니다. |
verification_status |
string | 아니요 | verified 또는 unverified입니다. |
security_profile |
string | 아니요 | baseline입니다(현재 쓰기 가능한 유일한 프로필). |
token_endpoint_auth_method |
string | 아니요 | private_key_jwt, client_secret_basic, client_secret_post 또는 none이며, app_type에서 허용되어야 합니다. |
grant_types |
string[] | 아니요 | 허용되는 권한 부여 유형이며, app_type이 허용하는 유형의 부분 집합이어야 합니다. |
default_api_id |
string 또는 null | 아니요 | 요청에 resource가 없을 때 사용하는 API의 api_… ID입니다. |
require_par |
boolean | 아니요 | 푸시된 인가 요청(PAR)을 필수로 합니다. |
require_state |
boolean | 아니요 | state를 필수로 합니다. |
require_nonce |
boolean | 아니요 | nonce를 필수로 합니다. |
pkce_required |
boolean | 아니요 | PKCE를 필수로 합니다. 기밀 웹 애플리케이션에 한해서만 비활성화할 수 있습니다. PKCE가 없으면 nonce만이 인가 코드 주입에 대한 방어 수단이 되므로, 개발 환경이 아닌 경우 require_nonce를 켜 두어야 합니다(그렇지 않으면 /require_nonce에서 validation_failed가 발생합니다). |
skip_consent |
boolean | 아니요 | 동의 화면을 건너뜁니다. 자사(first-party) 애플리케이션에만 적용됩니다. |
token_binding_policy |
string | 아니요 | none 또는 dpop_required입니다. |
login_host |
string 또는 null | 아니요 | 환경의 로그인 호스트 중 하나입니다(소문자 DNS 이름). |
default_max_age_s |
integer 또는 null | 아니요 | 초 단위의 기본 max_age입니다. |
min_acr |
string 또는 null | 아니요 | 최소 인증 보증 수준입니다. urn:idp:acr:1fa, urn:idp:acr:mfa 또는 urn:idp:acr:phr입니다. |
access_token_lifetime_s |
integer 또는 null | 아니요 | 액세스 토큰 수명이며, 60~86400초입니다. |
refresh_idle_s |
integer 또는 null | 아니요 | 초 단위의 리프레시 토큰 유휴 수명입니다. refresh_absolute_s를 초과할 수 없습니다. |
refresh_absolute_s |
integer 또는 null | 아니요 | 초 단위의 리프레시 토큰 절대 수명입니다. |
refresh_reuse_interval_s |
integer | 아니요 | 리프레시 토큰 재사용 허용 구간이며, 0~30초입니다(기본값 5). |
backchannel_logout_uri |
string 또는 null | 아니요 | 백채널 로그아웃 URI(https)입니다. |
frontchannel_logout_uri |
string 또는 null | 아니요 | 프런트채널 로그아웃 URI(https)입니다. |
frontchannel_logout_session_required |
boolean | 아니요 | 프런트채널 로그아웃 URI에 iss와 sid를 추가합니다. 환경의 프런트채널 로그아웃 설정이 꺼져 있는 상태에서 true로 설정하면 422가 반환됩니다. 기본값은 false입니다. |
initiate_login_uri |
string | 아니요 | OIDC 로그인 시작 URI입니다(OpenID Connect Core 1.0 §4). IdP가 시작한 SAML 로그인 후 브라우저는 iss와 함께 이 URI로 이동하며, 애플리케이션은 state와 PKCE를 사용해 자체 인가 코드 흐름을 시작합니다. 소문자 DNS 호스트를 가진 절대 https URL이어야 하며, 프래그먼트나 사용자 정보가 없어야 하고, 최대 2048바이트입니다. m2m 및 management 애플리케이션에는 허용되지 않습니다. 이 URI가 있는 애플리케이션만 IdP가 시작한 로그인의 대상이 될 수 있습니다. |
id_token_org_claims |
boolean | 아니요 | true(기본값)이면 조직 로그인의 ID 토큰에 org_id, org_slug, org_roles가 포함됩니다. false이면 ID 토큰에 조직 클레임이 포함되지 않습니다. 액세스 토큰에는 영향이 없으며, ID 토큰에는 권한이 포함되지 않습니다. |
policy_uri |
string 또는 null | 아니요 | 개인정보 처리방침 URI(https)이며, 동의 화면에 표시됩니다. |
tos_uri |
string 또는 null | 아니요 | 서비스 이용약관 URI(https)입니다. |
client_uri |
string 또는 null | 아니요 | 애플리케이션 홈페이지 URI(https)입니다. |
jwks |
object 또는 null | 아니요 | 인라인 JWK 세트({"keys":[…]})입니다. 공개 키 1~5개, 최대 16 KiB이며, 비공개 키 멤버는 거부됩니다. jwks_uri와 함께 사용할 수 없습니다. |
jwks_uri |
string 또는 null | 아니요 | 원격 JWK 세트 URI(https)입니다. jwks와 함께 사용할 수 없습니다. |
software_id |
string 또는 null | 아니요 | DCR 애플리케이션에만 사용합니다. |
software_version |
string 또는 null | 아니요 | DCR 애플리케이션에만 사용합니다. |
m2m_token_lifetime_s |
integer 또는 null | 아니요 | m2m 애플리케이션의 토큰 수명이며, 60~86400초입니다. |
redirect_uris |
string[] | 아니요 | 허용되는 리디렉션 URI이며, 최대 50개입니다. m2m 및 management에서는 비어 있어야 합니다. |
post_logout_redirect_uris |
string[] | 아니요 | 허용되는 로그아웃 후 리디렉션 URI이며, 최대 50개입니다. |
connection_ids |
string[] | 아니요 | 애플리케이션에서 활성화된 연결(conn_…)이며, 순서가 있습니다. 이 순서가 버튼 표시 순서가 됩니다. 최대 100개입니다. |
allowed_first_factors |
string[] | 아니요 | 애플리케이션에서 허용되는 1차 인증 요소입니다. password, passkey, email_otp, magic_link, sms_otp, social, enterprise 중에서 선택하며, 중복은 허용되지 않습니다. 이 순서대로 반환됩니다. 빈 목록(기본값)은 애플리케이션에 추가 제한이 없음을 의미합니다. 이 집합은 환경의 allowed_first_factors와 교차 적용되며, 사용 가능한 방법이 남지 않으면 422 policy_conflict가 반환됩니다. |
allowed_response_modes |
string[] | 아니요 | 인가 요청과 푸시된 인가 요청에서 애플리케이션이 사용할 수 있는 response_mode 값입니다. query, form_post 중 하나 또는 둘 다를 중복 없이 지정할 수 있으며, 이 순서대로 반환됩니다. 기본값은 ["query"]입니다. 폼 POST로 인가 응답을 받는 애플리케이션은 form_post를 명시적으로 추가해야 합니다. 목록에 없는 response_mode를 사용하는 인가 요청은 거부되며, response_mode가 없는 요청은 query를 사용합니다. 빈 목록을 지정하면 422가 반환됩니다. JARM 모드(jwt, query.jwt, fragment.jwt, form_post.jwt)는 아직 지원되지 않습니다. 동적 클라이언트 등록 또는 클라이언트 ID 메타데이터 문서를 통해 등록된 애플리케이션은 ["query"]를 받습니다. |
응답
애플리케이션과 ETag 헤더를 포함한 201 Created가 반환됩니다.
{
"id": "app_6f8d0cjgbmf0gtn2rg6pscp3cg",
"client_id": "app_6f8d0cjgbmf0gtn2rg6pscp3cg",
"version": 1,
"created_at": "2026-10-05T10:00:01Z",
"updated_at": "2026-10-05T10:00:01Z",
"key": "portal",
"name": "Portal",
"app_type": "web",
"party": "first_party",
"status": "active",
"redirect_uris": ["https://portal.example.com/cb"],
"...": "all other fields from the field reference"
}
오류
| HTTP | code |
발생 조건 |
|---|---|---|
| 401 | unauthenticated |
키가 없거나, 잘못되었거나, 취소되었습니다. |
| 403 | insufficient_permissions |
키에 필요한 권한이 없습니다. |
| 409 | conflict |
같은 key를 가진 애플리케이션이 이미 있습니다. |
| 422 | validation_failed |
필드가 잘못되었습니다. errors[].pointer가 해당 필드를 가리킵니다(예: /redirect_uris/0). |
| 422 | policy_conflict |
allowed_first_factors에 환경의 1차 인증 요소 집합과 공통되는 방법이 없습니다. |
| 400 | unknown_field |
본문에 스키마에 없는 필드가 있습니다. |
| 403 | quota_exceeded |
애플리케이션에 대한 요금제 한도에 도달했습니다. |
예시
curl -X POST https://api.eu.keenauth.com/v1/applications \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"key":"portal","name":"Portal","app_type":"web","party":"first_party","redirect_uris":["https://portal.example.com/cb"]}'
응답 필드
id와 client_id는 애플리케이션 ID(app_…)입니다. version은 ETag로도 반환됩니다. created_at, updated_at, last_token_issued_at, last_token_asn은 읽기 전용입니다. 위에 나열된 쓰기 가능한 필드는 모두 반환됩니다. 클라이언트 비밀은 이 리소스에 포함되지 않습니다.