> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenID 구성 조회 | Didit Authentication API

> GET /.well-known/openid-configuration은 Didit의 OpenID Connect 디스커버리 문서를 반환합니다: 발급자, 엔드포인트, 권한 부여, ES256, 클레임.

> [!WARNING]
>
> 인증 기능은 새로운 기능입니다. 이 엔드포인트는 `https://<name>.auth.didit.me`와 같이 애플리케이션의 발급자가 제공하며, Didit API 키를 사용하지 않습니다.

구성한 발급자에서 디스커버리 문서를 가져오십시오. 토큰에 적힌 URL에서는 절대 가져오지 마십시오. 응답은 5분 동안 캐시할 수 있습니다. 각 필드가 연동에서 무엇을 의미하는지는 [token 및 JWKS](https://docs.didit.me/ko/authentication/tokens-and-jwks.md#디스커버리-및-키)를 참조하십시오.


## OpenAPI

````yaml ko/openapi-authentication.json GET /.well-known/openid-configuration
openapi: 3.0.3
info:
  title: Didit Authentication API
  version: 1.0.0
  description: >-
    애플리케이션의 최종 사용자를 위한 로그인 제품인 Didit Authentication의 서버용 endpoint입니다.
    Authentication은 **새 제품**이며 2026-11-01 릴리스에서 프로덕션에 적용됩니다.


    ## 기본 URL


    모든 애플리케이션은 자체적인 OpenID Connect 발급자(issuer)이며, 아래의 모든 endpoint는 해당 발급자의 루트에서
    제공됩니다.


    - 프로덕션 환경 애플리케이션의 경우 `https://<name>.auth.didit.me`, 샌드박스 애플리케이션의 경우
    `https://<name>.sandbox.auth.didit.me`.

    - 활성화된 커스텀 도메인. 활성화되면 기본 호스트 대신 발급자 역할을 합니다. 새 token의 `iss`에 해당 도메인이 지정되고,
    discovery가 이를 가리키며, 공개 가능 키(publishable key)가 변경됩니다. 기본 호스트에서 발급된 access
    token은 갱신될 때까지 `/session/`, `/step-up/`, `/monitoring-token/` 호출에 실패합니다.


    프로덕션과 샌드박스는 별개의 애플리케이션이므로, 별도의 키를 가진 서로 다른 발급자입니다. 공개 가능 키는 `pk_live_`(프로덕션)
    또는 `pk_test_`(샌드박스) 뒤에 발급자의 패딩 없는 base64url 인코딩(끝의 슬래시 제외)이 붙은 형태입니다. 이를
    디코딩하면 발급자를 확인할 수 있습니다. 이는 공개 식별자이며 자격 증명이 아닙니다.


    동일한 JSON endpoint는
    `https://apx.didit.me/auth/v2/authentication/{application_id}/`에서도 제공됩니다.
    token은 어느 주소에서 발급되었든 항상 위의 발급자를 지정합니다.


    ## 자격 증명


    이러한 endpoint는 Didit API 키나 콘솔 token을 절대 사용하지 않습니다.


    - Discovery, JWKS 및 `POST /token/`은 자격 증명을 요구하지 않습니다. 클라이언트는 공개 클라이언트(public
    client)입니다. 클라이언트 시크릿(client secret)이 없으며, 인가 코드(authorization code)는 PKCE
    검증자(`S256`)에 바인딩됩니다. `client_id`는 애플리케이션 ID입니다.

    - `/session/`, `/step-up/`, `/monitoring-token/`은 사용자의 access token을 사용합니다:
    `Authorization: Bearer <access_token>`. 성공한 각 호출은 세션의 활동으로 간주되므로 세션의 유휴 시간
    초과(idle timeout)가 재시작됩니다.


    ## 요청 본문


    본문을 받는 모든 endpoint는 JSON, 양식 인코딩(form-encoded) 및 multipart 본문을 허용합니다. 이 문서에는
    JSON과 OAuth 클라이언트가 전송하는 `POST /token/`용 양식 인코딩이 나열되어 있습니다. endpoint가 허용하지 않는
    필드는 `400 {"<field>": "unknown_field"}`를 반환합니다.


    ## Token


    - **Access token**: 헤더 `typ: at+jwt`를 가진 ES256 JWT로, 최대 5분 동안 유효하며 해당 세션보다
    오래 유효할 수 없습니다. 클레임: `AccessTokenClaims`.

    - **ID token**: 헤더 `typ: JWT`를 가진 ES256 JWT입니다. 클레임: `IDTokenClaims`. access
    token으로는 절대 허용되지 않습니다.

    - **Refresh token**: 사용할 때마다 순환(rotate)되는 임의의 문자열입니다. 이미 사용된 refresh token을
    다시 보내면 세션이 취소(revoke)됩니다.


    `GET /.well-known/jwks.json`의 키로 token을 검증하세요. 알고리즘은 `ES256`이어야 하고, `typ`은
    token 유형과 일치해야 하며, `iss`는 구성된 발급자와 같아야 하고, `aud`는 애플리케이션 ID여야 합니다. 오프라인
    검증에서는 access token이 만료되어야만 취소된 세션을 감지할 수 있습니다. 즉각적인 확인을 위해서는 `GET
    /session/`을 사용하세요.


    ## 오류


    | 본문 | 조건 |

    | --- | --- |

    | `{"error": "<code>"}` | `POST /token/`에서 발생하는 오류로, 모두 상태 코드 `400`이며 [RFC
    6749 섹션 5.2](https://www.rfc-editor.org/rfc/rfc6749#section-5.2) 형식의 본문을
    갖습니다: `invalid_grant`, `invalid_client` 및 Didit의 `mfa_required`. 서비스 오류:
    `temporarily_unavailable`, `monitoring_unavailable`, `monitoring_disabled`.
    |

    | `{"<field>": ["<message>"]}` 또는 `{"<field>": "<code>"}` | 요청 필드 유효성 검사에
    실패했습니다. `non_field_errors`는 여러 필드에 걸친 규칙 위반을 나타내며, `unknown_field`는
    endpoint가 허용하지 않는 필드를 나타냅니다. |

    | `{"detail": "<message>"}` | `401`(`invalid_token`),
    `403`(`origin_not_allowed`), `404`(알 수 없는 애플리케이션 또는 step-up), `429`(속도 제한).
    또한 파싱할 수 없는 본문의 경우 `400`(`JSON parse error - ...`), endpoint가 지원하지 않는 메서드의
    경우 `405`, 지원되지 않는 `Content-Type`의 경우 `415`. |


    `401` 응답에는 `WWW-Authenticate: Bearer`도 포함되며, `429` 응답에는 초 단위의 `Retry-After`가
    포함됩니다.


    두 가지 거부 응답은 JSON 형식이 아닙니다. 발급자가 아닌 주소는 이러한 endpoint에 도달하기 전에 거부됩니다(예: 사용되지
    않는 `*.auth.didit.me` 이름에 대한 빈 `404`). UUID가 아닌 `step_up_id`는 `404` 페이지를
    반환합니다.


    ## 속도 제한


    요청은 두 계층을 통과해야 합니다.


    클라이언트 IP 주소당, 애플리케이션당, endpoint당 계산되는 **Endpoint 제한**:


    - Discovery 및 JWKS: 분당 1,200건, 시간당 12,000건의 요청.

    - 기타 모든 endpoint: 분당 30건, 시간당 300건의 요청. `GET` 및 `DELETE /session/`은 동일한 카운트를
    공유합니다.


    제한 초과 시: `429 {"detail": "Too many requests from this IP address. Please
    wait before trying again. Expected available in 60 seconds."}` 또는 시간당 제한의 경우
    `3600 seconds`.


    모든 `POST` 및 `DELETE`에 적용되는 **봇 보호**. 해당 버킷은 호스팅된 로그인 단계를 포함한 애플리케이션의 모든
    `POST` 및 `DELETE` 요청이 공유하며 지속적으로 리필됩니다:


    - 클라이언트 IP 주소당 분당 60건의 요청.

    - 브라우저 및 네이티브 SDK와 같이 기기를 식별하는 요청의 경우 기기당 분당 30건의 요청.

    - 모든 IP 주소를 합산한 전체 애플리케이션 기준 분당 3,000건의 요청. token
    갱신(`grant_type=refresh_token`인 `POST /token/`)은 별도의 독립된 버킷을 사용하며 전체 애플리케이션
    기준 분당 6,000건입니다.


    버킷 초과 시: `429 {"detail": "rate_limited Expected available in N
    seconds."}`(N이 1인 경우 `1 second.`). IP별 버킷은 여러 endpoint에 걸쳐 적용되므로, 한 주소에서
    token, step-up, 로그아웃 호출을 섞어 요청하면 특정 endpoint 제한에 도달하기 전에 버킷이 소진될 수 있습니다.
    애플리케이션 버킷은 브라우저를 포함하여 해당 애플리케이션의 모든 클라이언트를 계산합니다.


    두 계층 모두 endpoint가 실행되기 전에 응답하므로, `429`를 받은 요청은 실행되지 않은 상태입니다. 갱신을 포함하여
    `Retry-After` 시간이 지난 후 다시 재시도하세요.


    ## 브라우저 요청


    `Origin` 헤더를 포함하는 요청은 애플리케이션 자체의 origin 또는 허용된 origin 중 하나에서 시작되어야 하며, 그렇지
    않으면 `403 origin_not_allowed`를 받습니다. 서버 간(server-to-server) 요청은 `Origin`을
    전송하지 않습니다.


    ## 여기에 포함되지 않는 내용


    이러한 경로는 호스팅 페이지, 브라우저 및 네이티브 SDK, AI 에이전트를 위한 경로입니다. 서버 규격(contract)에 포함되지
    않으며 서버 SDK는 이를 호출하지 않습니다:


    - 로그인 단계: `POST /authorize/`, `POST /password/`, `/email/*`, `/phone/*`,
    `/password-reset/*`, `/passkeys/*`, `/mfa/*`, `/social/*` 및
    `/protection/complete/`.

    - 호스팅 페이지 및 콜백: `/sign-in`, `/magic`, `/invite`, `/reset`, `/verify/`,
    `/sso/*`, `/wallet/callback/`, `/logo/` 및 `/.well-known/` 하위의 네이티브 앱 연결 파일.

    - 에이전트 액세스: `/agents/*` 및 `/grants/`(AI 에이전트의 access token 실시간 확인을 위한 `GET
    /agents/session/` 포함). 에이전트 액세스는 본 버전의 규격에 포함되지 않습니다.

    - 콘솔 세션을 사용하는 Authentication 콘솔 관리 API.


    Authentication 이벤트는 아직 webhook으로 전송되지 않으므로, 이 문서에서는 webhook을 정의하지 않습니다.
servers:
  - url: https://{issuer}
    description: '귀하 애플리케이션의 발급자: 로그인 오리진입니다.'
    variables:
      issuer:
        default: your-app.auth.didit.me
        description: >-
          발급자 호스트: `<name>.auth.didit.me`(프로덕션),
          `<name>.sandbox.auth.didit.me`(샌드박스) 또는 활성 커스텀 도메인입니다.
security: []
tags:
  - name: Issuer
    description: token을 검증하기 위한 디스커버리 및 서명 키입니다.
  - name: Tokens
    description: 인가 코드 및 갱신 권한 부여입니다.
  - name: Sessions
    description: 액세스 token 뒤의 세션을 확인하고 종료합니다.
  - name: Step-ups
    description: 민감한 작업 전 수행하는 인증입니다.
  - name: Monitoring
    description: 거래 모니터링 이벤트에 대한 기기 자격 증명입니다.
paths:
  /.well-known/openid-configuration:
    get:
      tags:
        - Issuer
      summary: OpenID 구성 가져오기
      description: >-
        발급자의 디스커버리 문서(endpoint, 권한 부여 유형, 서명 알고리즘, 클레임)입니다. token 내에 있는 URL이 아니라
        직접 설정한 발급자로부터 가져오세요. `Cache-Control`에 명시된 대로 최대 5분 동안 캐시합니다.
      operationId: authentication_get_openid_configuration
      responses:
        '200':
          description: 디스커버리 문서입니다.
          headers:
            Cache-Control:
              description: >-
                `public, max-age=300`: 사용자와 공유 캐시는 성공한 응답을 액세스 토큰 수명인 5분 동안 보관할
                수 있습니다.
              schema:
                type: string
                example: public, max-age=300
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenIDConfiguration'
              examples:
                Discovery:
                  summary: 프로덕션 애플리케이션
                  value:
                    issuer: https://your-app.auth.didit.me
                    authorization_endpoint: https://your-app.auth.didit.me/sign-in
                    token_endpoint: https://your-app.auth.didit.me/token/
                    jwks_uri: https://your-app.auth.didit.me/.well-known/jwks.json
                    response_types_supported:
                      - code
                    response_modes_supported:
                      - query
                    grant_types_supported:
                      - authorization_code
                      - refresh_token
                    subject_types_supported:
                      - public
                    id_token_signing_alg_values_supported:
                      - ES256
                    token_endpoint_auth_methods_supported:
                      - none
                    code_challenge_methods_supported:
                      - S256
                    scopes_supported:
                      - openid
                      - email
                      - phone
                      - profile
                      - offline_access
                    claims_supported:
                      - iss
                      - aud
                      - sub
                      - sid
                      - auth_time
                      - nonce
                      - vendor_data
                      - amr
                      - org
                      - verified
                      - act
                      - email
                      - email_verified
                      - name
                      - phone_number
        '403':
          $ref: '#/components/responses/OriginNotAllowed'
        '404':
          $ref: '#/components/responses/ApplicationNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/TemporarilyUnavailable'
      security:
        - {}
components:
  schemas:
    OpenIDConfiguration:
      type: object
      description: 발급자의 OpenID Connect 디스커버리 문서입니다. endpoint를 직접 구성하지 말고 여기에서 읽어오세요.
      required:
        - issuer
        - authorization_endpoint
        - token_endpoint
        - jwks_uri
        - response_types_supported
        - response_modes_supported
        - grant_types_supported
        - subject_types_supported
        - id_token_signing_alg_values_supported
        - token_endpoint_auth_methods_supported
        - code_challenge_methods_supported
        - scopes_supported
        - claims_supported
      properties:
        issuer:
          type: string
          format: uri
          description: '발급자: 끝에 슬래시가 없는 애플리케이션의 로그인 오리진입니다. 모든 token의 `iss`와 동일합니다.'
          example: https://your-app.auth.didit.me
        authorization_endpoint:
          type: string
          format: uri
          description: 호스팅 로그인 페이지(`/sign-in`)입니다.
          example: https://your-app.auth.didit.me/sign-in
        token_endpoint:
          type: string
          format: uri
          example: https://your-app.auth.didit.me/token/
        jwks_uri:
          type: string
          format: uri
          example: https://your-app.auth.didit.me/.well-known/jwks.json
        response_types_supported:
          type: array
          items:
            type: string
          example:
            - code
        response_modes_supported:
          type: array
          items:
            type: string
          example:
            - query
        grant_types_supported:
          type: array
          items:
            type: string
          example:
            - authorization_code
            - refresh_token
        subject_types_supported:
          type: array
          items:
            type: string
          example:
            - public
        id_token_signing_alg_values_supported:
          type: array
          items:
            type: string
          example:
            - ES256
        token_endpoint_auth_methods_supported:
          type: array
          items:
            type: string
          description: '`none`: 클라이언트가 공개되어 비밀을 전송하지 않습니다.'
          example:
            - none
        code_challenge_methods_supported:
          type: array
          items:
            type: string
          example:
            - S256
        scopes_supported:
          type: array
          items:
            type: string
          example:
            - openid
            - email
            - phone
            - profile
            - offline_access
        claims_supported:
          type: array
          items:
            type: string
          example:
            - iss
            - aud
            - sub
            - sid
            - auth_time
            - nonce
            - vendor_data
            - amr
            - org
            - verified
            - act
            - email
            - email_verified
            - name
            - phone_number
    Detail:
      type: object
      required:
        - detail
      properties:
        detail:
          type: string
          example: invalid_token
    OAuthError:
      title: OAuth error
      type: object
      description: OAuth 오류(RFC 6749 섹션 5.2) 또는 서비스 오류입니다.
      required:
        - error
      properties:
        error:
          type: string
          example: invalid_grant
  responses:
    OriginNotAllowed:
      description: >-
        요청에 애플리케이션 자체의 오리진도 아니고 허용된 오리진 목록에도 없는 `Origin`이 포함되어 있습니다. 서버 요청은
        `Origin`을 보내지 않습니다.
      headers:
        Cache-Control:
          description: 항상 `no-store`입니다. 이 응답은 절대 캐시하지 마십시오.
          schema:
            type: string
            example: no-store
        Pragma:
          description: 항상 `no-cache`입니다.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            OriginNotAllowed:
              summary: 허용되지 않은 오리진(Origin)
              value:
                detail: origin_not_allowed
    ApplicationNotFound:
      description: >-
        주소가 애플리케이션에 속해 있지만 해당 애플리케이션에 인증이 활성화되어 있지 않습니다. `apx.didit.me` 주소에서는
        애플리케이션 ID를 알 수 없습니다. 어떤 애플리케이션에도 속하지 않는 주소는 endpoint에 도달하기 전에 거부되며 해당
        응답은 JSON이 아닙니다.
      headers:
        Cache-Control:
          description: 항상 `no-store`입니다. 이 응답은 절대 캐시하지 마십시오.
          schema:
            type: string
            example: no-store
        Pragma:
          description: 항상 `no-cache`입니다.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            ApplicationNotFound:
              summary: 알 수 없는 애플리케이션
              value:
                detail: No Configuration matches the given query.
    RateLimited:
      description: >-
        이 endpoint에 대해 해당 IP 주소로부터의 요청이 너무 많거나, `POST` 또는 `DELETE` 요청 시 봇 보호 버킷이
        비어 있습니다. 아무 작업도 실행되지 않았습니다. `Retry-After`초 동안 기다린 후 다시 시도하십시오.
      headers:
        Retry-After:
          description: 재시도하기 전 대기할 시간(초)입니다.
          schema:
            type: integer
            example: 60
        Cache-Control:
          description: 항상 `no-store`입니다. 이 응답은 절대 캐시하지 마십시오.
          schema:
            type: string
            example: no-store
        Pragma:
          description: 항상 `no-cache`입니다.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            RateLimited:
              summary: endpoint 제한
              value:
                detail: >-
                  Too many requests from this IP address. Please wait before
                  trying again. Expected available in 60 seconds.
            BotProtection:
              summary: 봇 방지 제한(POST 및 DELETE)
              value:
                detail: rate_limited Expected available in 2 seconds.
    TemporarilyUnavailable:
      description: 요청이 의존하는 서비스를 일시적으로 사용할 수 없습니다. 백오프를 적용하여 다시 시도하십시오.
      headers:
        Cache-Control:
          description: 항상 `no-store`입니다. 이 응답은 절대 캐시하지 마십시오.
          schema:
            type: string
            example: no-store
        Pragma:
          description: 항상 `no-cache`입니다.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/OAuthError'
          examples:
            TemporarilyUnavailable:
              summary: 나중에 재시도
              value:
                error: temporarily_unavailable

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.