CIMD(Client ID Metadata Documents)

OAuth로 로그인을 붙일 때, 클라이언트 등록은 보통 이렇게 시작합니다. 인가 서버 콘솔에 앱을 미리 등록하고 client_id를 발급받아 코드에 박아 두는 거죠. 클라이언트와 서버가 서로를 아는 고정된 관계라 이 방식으로 충분했습니다.
그런데 이 전제가 통하지 않는 세계가 있습니다. 클라이언트와 서버가 처음 만나는 게 일상인 개방형 생태계예요. “Bluesky로 로그인”하는 서드파티 앱이 사용자마다 다른 서버에 붙고, AI 에이전트가 그날 처음 발견한 도구 서버에 연결하는 식이죠. 미리 등록할 시간도, 모두를 아우르는 중앙 등록소도 없습니다.
이 문제를 푸는 방식이 클라이언트 ID 메타데이터 문서(Client ID Metadata Documents, 이하 CIMD)입니다. 한 문장으로 요약하면 “URL이 곧 client_id가 된다”는 발상인데요 🤔 이 글에서는 CIMD가 어떤 문제를 어떻게 푸는지 개념부터 잡고, 인가 서버가 무엇을 검증해야 하는지, 그리고 실제로 어디에 쓰이는지까지 차근차근 살펴보겠습니다.
클라이언트 등록이 왜 골칫거리일까요
전통적인 OAuth에서 클라이언트 등록은 사람이 개입하는 일이었습니다. 개발자가 인가 서버 콘솔에 들어가 앱 이름과 리다이렉트 URI를 입력하고 client_id와 client_secret을 발급받아 코드에 박아 두는 식이죠. 관계가 고정되어 있으니 이 방식으로 충분했습니다.
그런데 개방형 생태계는 전제가 다릅니다. 사용자가 그날 처음 발견한 서버에 클라이언트가 곧바로 연결합니다. 서로를 모르는 상태에서 만나는 거죠. 사람이 매번 콘솔에서 등록을 눌러 줄 수는 없으니 자동화가 필요합니다.
기존의 자동화 답안은 동적 클라이언트 등록(Dynamic Client Registration, 이하 DCR)이었습니다. RFC 7591에 정의된 방식으로, 클라이언트가 인가 서버의 /register 엔드포인트에 POST를 보내면 그 자리에서 client_id를 발급받습니다. 동작은 하는데, 운영 부담이 만만치 않습니다. 우선 인가 서버는 아무나 호출할 수 있는 쓰기 엔드포인트를 열어 둬야 하고, 등록 요청이 들어올 때마다 새 레코드를 데이터베이스에 쌓아야 합니다. 클라이언트가 같은 서버에 기기마다, 세션마다 새로 등록하면 client_id가 끝없이 늘어나죠. 게다가 클라이언트 입장에서도 서버가 천 개면 client_id도 천 개라, 어느 서버에서 어떤 식별자를 받았는지 일일이 관리해야 합니다.
정리하면 DCR은 “상태를 쌓는” 방식입니다. 열린 생태계에서 규모가 커질수록 이 상태가 양쪽 모두에게 짐이 됩니다. CIMD는 바로 이 지점을 다르게 풉니다.
URL이 곧 client_id다
CIMD의 발상은 단순합니다. 클라이언트가 자기 메타데이터를 JSON 문서로 만들어 HTTPS URL에 올려 두고, 그 URL 자체를 client_id로 쓰는 겁니다. 예를 들어 https://app.example.com/oauth/client-metadata.json이 그대로 client_id가 됩니다.
흐름을 그려 보면 이렇습니다. 클라이언트가 인가 요청을 보낼 때 client_id에 평범한 문자열 대신 자기 메타데이터 URL을 넣습니다. 인가 서버는 client_id가 URL 형태인 걸 보고 “아, CIMD구나” 하고 그 URL을 직접 GET으로 가져옵니다. 돌아온 JSON을 검증한 뒤, 거기 적힌 정보를 바탕으로 인가 흐름을 이어 갑니다.
다만 클라이언트가 무작정 URL 형태의 client_id를 보내면 안 됩니다.
먼저 인가 서버의 인가 서버 메타데이터(Authorization Server Metadata)를 조회해서 CIMD 지원 여부를 확인해야 해요.
CIMD를 지원하는 인가 서버는 메타데이터에 client_id_metadata_document_supported: true를 공개합니다.
{
"issuer": "https://as.example.com",
"authorization_endpoint": "https://as.example.com/oauth2/authorize",
"token_endpoint": "https://as.example.com/oauth2/token",
"client_id_metadata_document_supported": true
}
이 값이 true가 아니라면 클라이언트는 URL형 client_id를 보내도 인가 서버가 메타데이터 문서를 가져와 주리라고 기대할 수 없습니다.
그 상태로 사용자를 리다이렉트하면 보통 invalid_client 같은 막다른 오류를 만나게 되죠.
그래서 실제 구현에서는 AS Metadata를 먼저 읽고, client_id_metadata_document_supported가 true이면 CIMD를 시도합니다.
그 값이 없거나 false라면 registration_endpoint가 있는지 확인해 Dynamic Client Registration으로 내려가고, 그마저 없으면 사전 등록된 client ID나 사용자 입력 같은 방식으로 가야 합니다.
지원 여부를 확인했다면 그제야 인가 요청에 URL형 client_id를 넣습니다.
실제 요청은 대략 이렇게 생겼습니다.
GET /authorize?
response_type=code&
client_id=https%3A%2F%2Fapp.example.com%2Foauth%2Fclient-metadata.json&
redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&
code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&
code_challenge_method=S256
이 요청을 받으면 인가 서버는 먼저 client_id 값을 디코딩해 https://app.example.com/oauth/client-metadata.json을 가져옵니다.
그리고 문서 안의 client_id가 요청의 client_id와 정확히 같은지, redirect_uri가 문서의 허용 목록에 들어 있는지, 공개 클라이언트라면 PKCE 파라미터가 제대로 왔는지 확인합니다.
이 검증을 통과한 뒤에야 사용자를 로그인과 동의 화면으로 보내고, 사용자가 승인하면 redirect_uri로 인가 코드(authorization code)를 돌려줍니다.
그러니까 CIMD 확인과 메타데이터 검증은 인가 코드를 받은 뒤가 아니라, 인가 코드를 발급하기 전에 일어나는 일입니다.
여기서 결정적인 차이가 드러나는데요. DCR이 서버에 데이터를 쓰는 방식이라면, CIMD는 서버가 필요할 때 데이터를 읽어 오는 방식입니다. 인가 서버는 클라이언트를 영구 저장소에 등록하지 않습니다. 요청이 들어온 순간 메타데이터를 가져와 검증하고, HTTP 캐시 규칙에 따라 잠깐 들고 있다가 버리면 그만이죠. 등록이 가볍고 되돌릴 수 있으며 자연스럽게 한계가 지어집니다.
클라이언트에게도 이득이 큽니다. 도메인 하나에 메타데이터를 올려 두면 그 URL이 모든 서버에서 통하는 단 하나의 신원이 됩니다. 서버마다 다른 비밀을 들고 다닐 필요가 없어지는 거죠.
메타데이터 문서 들여다보기
그럼 이 JSON 문서는 실제로 어떻게 생겼을까요. 공개 클라이언트의 가장 단순한 형태는 다음과 같습니다.
{
"client_id": "https://app.example.com/oauth/client-metadata.json",
"client_name": "Example Client",
"client_uri": "https://app.example.com",
"logo_uri": "https://app.example.com/logo.png",
"redirect_uris": ["https://app.example.com/callback"],
"grant_types": ["authorization_code"],
"response_types": ["code"],
"token_endpoint_auth_method": "none"
}
필드 하나하나가 인가 서버의 판단 근거가 되므로 의미를 짚고 넘어가겠습니다.
client_id: 문서가 호스팅된 URL과 한 글자도 틀리지 않게 일치해야 합니다. 신원의 닻 역할을 하는 가장 중요한 필드입니다.redirect_uris: 인가 코드를 돌려받을 콜백 URL의 허용 목록입니다. 사칭을 막는 핵심 방어선입니다.grant_types: 지원하는 인가 방식으로, 보통authorization_code를 씁니다.response_types: 인가 엔드포인트에서 받을 응답 타입으로, 보통code입니다.token_endpoint_auth_method: 토큰 엔드포인트에서 자기를 어떻게 인증할지 정합니다. 비밀을 숨길 수 없는 공개 클라이언트는none, 키 기반 인증을 쓰는 비밀 클라이언트는private_key_jwt를 씁니다. 공개 클라이언트라면 이 빈자리를 PKCE가 메워야 합니다.jwks_uri:private_key_jwt를 쓸 때 공개 키 묶음을 가리키는 URL입니다. 공개 클라이언트라면 생략합니다.
client_name과 logo_uri는 사용자에게 보여 줄 동의 화면을 꾸미는 용도라 필수는 아니지만 넣어 두는 편이 친절합니다. 이 문서가 client_id가 가리키는 URL에 그대로 노출된다는 점도 기억해 두세요. 비밀 값을 여기 담으면 안 됩니다.
client_secret이 없으면 PKCE가 중요합니다
위 예시에서 눈여겨봐야 할 필드는 token_endpoint_auth_method: "none"입니다.
이 값은 토큰 엔드포인트에서 client_secret으로 클라이언트를 인증하지 않겠다는 뜻입니다.
CIMD 문서는 공개 URL에 올라가고, 그 URL 자체가 client_id가 되므로 여기에 비밀을 넣을 수도 없습니다.
다시 말해 공개 클라이언트에서는 client_id가 “누구인지”를 나타낼 뿐, “정말 그 클라이언트가 맞는지”를 증명하는 비밀번호가 아닙니다.
그래서 Authorization Code 흐름을 쓸 때 PKCE가 핵심 방어선이 됩니다.
클라이언트는 인가 요청을 보내기 전에 code_verifier라는 무작위 비밀값을 만들고, 그 해시값인 code_challenge를 /authorize 요청에 실어 보냅니다.
이때 원본 code_verifier는 클라이언트가 로컬에만 보관합니다.
GET /authorize
?response_type=code
&client_id=https%3A%2F%2Fapp.example.com%2Foauth%2Fclient-metadata.json
&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256
사용자가 동의하면 인가 서버는 authorization code를 돌려줍니다.
그다음 클라이언트가 이 code를 액세스 토큰(access token)으로 바꿀 때는, 처음에 숨겨 두었던 code_verifier를 함께 제출합니다.
POST /token HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&client_id=https%3A%2F%2Fapp.example.com%2Foauth%2Fclient-metadata.json
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
인가 서버는 받은 code_verifier를 해시해서 처음 저장해 둔 code_challenge와 비교합니다.
둘이 맞아야만 토큰을 내줍니다.
만약 공격자가 중간에서 authorization code만 훔쳤다면 어떻게 될까요?
공개 클라이언트에는 client_secret이 없으니 PKCE가 없다면 그 code를 곧바로 토큰으로 바꿔 볼 수 있습니다.
하지만 PKCE가 있으면 공격자는 원본 code_verifier를 모르기 때문에 토큰 교환에 실패합니다.
따라서 CIMD에서 공개 클라이언트를 허용한다면 Authorization Code + PKCE 조합을 기본값으로 봐야 합니다.
특히 code_challenge_method는 plain이 아니라 S256을 강제하는 편이 안전합니다.
PKCE가 클라이언트의 정체성 자체를 증명하는 것은 아니지만, “인가 요청을 시작한 클라이언트”와 “토큰을 요청하는 클라이언트”가 같은지를 묶어 주는 역할을 합니다.
이 차이가 client_secret 없는 CIMD 흐름에서 아주 중요합니다.
인가 서버는 무엇을 검증할까요
CIMD의 안전성은 결국 인가 서버가 가져온 문서를 얼마나 깐깐하게 검증하느냐에 달려 있습니다. 인가 서버를 직접 구현한다면 다음 검사들은 빠뜨리면 안 됩니다.
우선 client_id URL은 HTTPS여야 하고, http://나 커스텀 스킴은 거절합니다. 가져온 응답은 파싱 가능한 JSON이어야 하며, 무한정 큰 문서를 받지 않도록 크기 상한(보통 수 KB)을 둡니다. 그다음 문서 안의 client_id 필드가 요청에 쓰인 URL과 정확히 일치하는지 확인합니다. 이 결합이 깨지면 CIMD의 신뢰 모델 전체가 무너지므로 가장 엄격하게 봐야 합니다.
리다이렉트 URI 검증도 빠뜨릴 수 없습니다. 인가 요청에 담긴 redirect_uri 파라미터가 문서의 redirect_uris 배열에 정확히 들어 있는지 봅니다. 부분 일치나 와일드카드는 절대 안 되고, 문자열이 통째로 같아야 합니다. 리다이렉트 URI 검증을 느슨하게 풀면 PKCE로 코드를 보호하더라도 코드가 엉뚱한 곳으로 새어 나갈 수 있습니다.
공개 클라이언트라면 PKCE도 함께 검증해야 합니다.
인가 요청에 code_challenge와 code_challenge_method=S256이 없으면 거절하고, 토큰 요청에서는 code_verifier가 원래 challenge와 맞는지 확인해야 합니다.
token_endpoint_auth_method가 none인데 PKCE까지 빠지면 authorization code 하나만으로 토큰 교환이 가능해지므로, CIMD의 공개 클라이언트 모델이 지나치게 약해집니다.
마지막으로 문서를 가져온 뒤에는 HTTP 캐시 헤더(Cache-Control, ETag)를 존중해 일정 시간 캐싱하고, TTL이나 LRU로 캐시가 무한히 부풀지 않게 관리합니다. 매 요청마다 외부 URL을 새로 긁어 오면 지연도 늘고 클라이언트 도메인에 부하를 주니까요.
SSRF, 가장 조심해야 할 위협
CIMD에는 DCR에 없던 새로운 위험이 하나 따라옵니다. 인가 서버가 클라이언트가 건넨 URL을 직접 요청한다는 점인데요. 이게 바로 서버 측 요청 위조(Server-Side Request Forgery, 이하 SSRF)의 전형적인 통로입니다.
악의적인 클라이언트가 client_id로 http://169.254.169.254/latest/meta-data/(클라우드 메타데이터 엔드포인트)나 http://127.0.0.1:8080/admin 같은 내부 주소를 넣으면 어떻게 될까요. 인가 서버가 아무 생각 없이 그 URL을 가져오면, 외부에서는 닿을 수 없는 내부 자원을 공격자 대신 긁어다 줄 수 있습니다. 클라우드 환경에서는 자격 증명 탈취로 이어지는 치명적인 경로죠.
그래서 인가 서버는 URL을 가져오기 전에 호스트 이름을 실제 IP로 해석한 뒤, 루프백(127.0.0.0/8), 링크 로컬(169.254.0.0/16), 그리고 사설 IP 대역(RFC 1918)을 모두 차단해야 합니다. 여기에 더해 HTTPS만 허용하고, 연결과 읽기에 2~3초짜리 짧은 타임아웃을 걸고, 리다이렉트를 따라가지 않도록 막아야 공격 표면을 좁힐 수 있습니다. CIMD를 도입할 때 가장 신경 써야 할 부분이 바로 이 SSRF 방어인데요. SSRF가 왜 그렇게 치명적이고 어떤 방어가 필요한지는 SSRF 공격과 방어에서 더 깊이 다뤘습니다.
DCR과 무엇이 다를까요
여기까지 보면 CIMD와 DCR의 차이가 또렷해집니다. DCR은 클라이언트가 서버에 자기를 등록하고 서버가 그 상태를 데이터베이스에 보관하는, 상태를 쌓는 방식입니다. 반대로 CIMD는 서버가 그때그때 메타데이터를 읽어 와 검증하고 캐시만 하는, 상태를 두지 않는 방식이죠.
두 방식은 공격 표면도 다릅니다. DCR은 누구나 호출할 수 있는 등록 엔드포인트를 열어 두는 대신 SSRF 위험은 없습니다. CIMD는 쓰기 엔드포인트가 아예 없어 등록 스팸을 걱정하지 않아도 되지만, 외부 URL을 가져오는 탓에 SSRF를 막아야 합니다. 한쪽의 부담을 다른 쪽으로 옮긴 셈인데, 클라이언트가 서버 수천 개를 옮겨 다니는 개방형 환경에서는 CIMD 쪽 트레이드오프가 훨씬 유리합니다.
그렇다고 둘이 양자택일인 것도 아니에요. 클라이언트가 여러 방식을 지원한다면 사전 등록과 CIMD, DCR, 사용자 직접 입력을 우선순위를 두고 함께 쓸 수 있습니다.
다만 DCR도 아무 URL이나 추측해서 호출하는 방식은 아닙니다.
AS Metadata에 registration_endpoint가 있을 때만 그 URL로 등록 요청을 보내야 합니다.
실제로 그렇게 순서를 정해 둔 예는 뒤의 MCP에서 보겠습니다.
클라이언트 사칭은 어떻게 막을까요
“URL만 알면 아무나 그 클라이언트인 척할 수 있는 거 아닌가요?”라는 의문이 들 수 있습니다. 실제로는 그 반대인데요. CIMD의 구조가 사칭을 오히려 어렵게 만듭니다.
공격자가 합법적인 클라이언트의 client_id URL을 그대로 가져다 쓴다고 해 봅시다. 인가 서버는 그 URL에서 진짜 메타데이터를 가져옵니다. 진짜 문서에는 합법적인 클라이언트의 redirect_uris만 적혀 있죠. 공격자가 코드를 자기 콜백으로 빼돌리려 해도, 그 콜백 주소는 문서의 허용 목록에 없으니 인가 서버가 거절합니다. 결국 공격자가 사칭에 성공하려면 합법적인 클라이언트의 호스팅 도메인 자체를 장악해야 합니다. 신뢰의 닻이 도메인 통제권으로 옮겨 간 거죠.
다만 한 가지 주의할 점이 있습니다. 로컬호스트 리다이렉트입니다. 공격자가 합법적인 클라이언트의 이름과 로고를 그대로 빌리되 redirect_uri를 자기가 열어 둔 로컬호스트 포트로 지정하는 변종 공격이 가능한데요. 사용자는 익숙한 클라이언트 화면을 보면서 실제로는 공격자에게 코드를 넘기게 됩니다. 그래서 CIMD에서는 로컬호스트 리다이렉트를 금지하거나, 허용하더라도 인가 서버가 추가 경고를 띄우도록 권합니다.
비밀 클라이언트와 키 회전
지금까지는 비밀을 숨길 수 없는 공개 클라이언트를 주로 이야기했습니다. 서버에서 도는 비밀 클라이언트(confidential client)는 좀 더 강한 인증을 쓸 수 있는데요. 바로 private_key_jwt입니다.
이 경우 클라이언트는 메타데이터에 token_endpoint_auth_method를 private_key_jwt로 적고, 자기 공개 키 묶음을 jwks_uri로 알립니다. 토큰을 요청할 때는 개인 키로 서명한 JWT를 함께 보내고, 인가 서버는 jwks_uri에서 가져온 공개 키로 서명을 검증합니다. 공개 키와 개인 키, 그리고 JWKS가 어떻게 맞물리는지 익숙하지 않다면 관련 글을 함께 보시면 좋습니다.
이 방식의 진가는 키 회전에서 드러납니다. 서버마다 다른 비밀을 쥐여 주는 DCR이라면 키를 바꿀 때 천 개 서버를 일일이 갱신해야 합니다. CIMD에서는 jwks_uri가 가리키는 키 묶음 하나만 새 키로 교체하면 끝입니다. 그다음부터 각 인가 서버가 검증할 때 알아서 새 키를 가져가니까요. 중앙에서 한 번 바꾸면 모든 서버에 반영되는 셈입니다. 분산된 환경에서 비밀을 관리하는 부담을 크게 덜어 줍니다.
CIMD는 새로 나온 아이디어가 아닙니다
여기까지 오면 CIMD가 꽤 참신하게 느껴지지만, 사실 갑자기 등장한 방식이 아닙니다. URL을 client_id로 쓰는 아이디어는 여러 곳에서 이미 오래 다듬어져 왔어요.
- IndieAuth: IndieWeb 진영에서 10년 넘게 클라이언트를 URL로 식별해 왔습니다. 처음엔 HTML 마이크로포맷(h-app)을 읽다가 JSON 메타데이터로 옮겨왔죠. 사실상 원조입니다.
- Solid-OIDC: Tim Berners-Lee의 분산 데이터 파드 프로젝트 Solid가 “Client Identifier Documents”를 정의했고, 지금의 CIMD 초안이 여기서 영감을 받았다고 밝히고 있습니다.
- IETF 표준화: 이 방식을 정식 표준으로 다듬는 작업이 IETF OAuth 워킹그룹에서 진행 중입니다(Aaron Parecki의 초안이 워킹그룹에 채택돼 Standards Track으로 올라갔어요).
공통점이 보이시나요. 전부 중앙 등록소가 없는 개방형 생태계라는 점입니다. 아무 클라이언트가 아무 서버에 처음 붙는 판에서 “미리 등록”이 불가능하니, “URL을 신원으로” 쓰는 답에 다들 도달한 거죠.
오늘날 CIMD가 가장 큰 규모로 돌아가는 곳은 Bluesky를 떠받치는 AT Protocol입니다. 2024년 OAuth 프로필에 URL 기반 client_id를 채택했는데요. “Bluesky로 로그인”하는 모든 서드파티 앱(대체 클라이언트, 피드 생성기 등)이 자기 client-metadata.json을 client_id로 씁니다. 수백만 사용자 규모에서 이미 검증된 방식이라, “CIMD가 현실에서 정말 되나?”라는 의문에 대한 답이 여기 있어요.
사용처 살펴보기: MCP
가장 최근에 CIMD를 앞세운 곳이 MCP(Model Context Protocol)입니다. MCP는 AI 에이전트가 외부 도구와 데이터에 접근하도록 잇는 프로토콜인데, 여기서 클라이언트 등록 문제가 특히 도드라져요. Claude 같은 AI 클라이언트 하나가 사용자가 그날 처음 발견한 MCP 서버 수천 개에 그때그때 붙어야 하거든요. 서로 처음 만나는 상황이 일상이라, 사전 등록은 물론이고 DCR로 매번 등록하는 것조차 상태가 끝없이 쌓여 부담입니다. 앞서 본 “개방형 생태계” 문제의 교과서 같은 사례죠.
그래서 MCP는 2025년 11월 25일 개정 스펙(SEP-991)에서 CIMD를 클라이언트 등록의 새 기본값으로 채택했습니다. 다만 CIMD 하나만 강제하진 않아요. 클라이언트가 여러 방식을 지원한다면 사전 등록 → CIMD → DCR → 사용자 직접 입력 순으로 시도하라고 권장합니다.
여기서 CIMD는 AS Metadata의 client_id_metadata_document_supported가 true일 때, DCR은 registration_endpoint가 있을 때만 시도할 수 있습니다.
CIMD가 앞자리 기본값으로 서고, DCR은 호환성을 위한 차선책으로 물러난 모양새죠. 아무 서버에나 즉석에서 붙어야 하는 AI 클라이언트에게 “URL 하나로 어디서든 통하는 단일 신원”이 정확히 필요했던 겁니다.
MCP 인증 전체가 OAuth 2.1 위에서 어떻게 맞물리는지 더 깊이 보고 싶다면 MCP Authentication에서 전체 그림을 이어서 확인해 보세요. CIMD와 DCR을 실제 인가 서버에서 함께 활성화하는 예는 WorkOS AuthKit의 MCP 지원에서 볼 수 있습니다.
마치며
CIMD를 한마디로 요약하면 “client_id를 데이터베이스가 아니라 웹에 둔다”입니다. URL 하나로 신원을 표현하니 등록이 상태를 남기지 않고, 클라이언트는 모든 서버에서 통하는 단일 신원을 갖게 되며, 키 회전도 중앙에서 한 번에 처리됩니다. IndieWeb, Bluesky, MCP처럼 클라이언트와 서버가 처음 만나는 일이 일상인 열린 생태계에 두루 맞는 모델이죠.
물론 공짜는 아닙니다. 외부 URL을 가져오는 구조라 SSRF 방어가 필수이고, client_id와 문서 URL의 결합, 리다이렉트 URI의 엄격한 검증을 빠뜨리면 신뢰 모델이 무너집니다. 인가 서버를 직접 구현한다면 이 검증 절차부터 단단히 잡아 두시길 권합니다.
CIMD는 아직 IETF 표준화가 진행 중인 주제라 세부 규정이 계속 다듬어지고 있는데요. 더 자세한 내용은 OAuth Client ID Metadata Document 초안이나 MCP Authorization 스펙을 참고하세요.
This work is licensed under CC BY 4.0