JWT/OIDC 인증 사용하기

JWT/OIDC 인증 사용하기

참고: 이 엔진은 TLS 또는 서명 검증의 일부로 외부 X.509 인증서를 사용할 수 있어요. SHA-1을 사용하는 X.509 인증서에 대한 서명 검증은 구식화(Deprecated)되었고 Vault 1.12부터 워크어라운드 없이는 더 이상 사용할 수 없어요. 자세한 내용은 구식화 공지를 참고하세요.

사용자 지정 GUI 로그인을 지원해요.

이 방식은 Vault Enterprise GUI 사용자의 기본 또는 백업 로그인 방식으로 선택될 수 있어요. 자세한 내용은 사용자 지정 로그인 옵션 관리 가이드를 참고하세요.

참고: Vault 1.17부터 인증 요청의 JWT에 aud 클레임(일반적인 경우)이 포함되어 있으면 "jwt" 역할의 연관된 bound_audiences가 JWT에 선언된 aud 클레임 중 정확히 하나 이상과 일치해야 해요. 추가 세부 사항은 JWT 인증 방식 (API) 문서와 1.17 업그레이드 가이드를 참고하세요.

jwt 인증 방식은 OIDC를 사용하거나 JWT를 제공해 Vault로 인증할 수 있게 해요.

OIDC 방식은 구성된 OIDC 프로바이더를 통해 사용자의 웹 브라우저를 사용한 인증을 허용해요. 이 방식은 Vault UI나 명령줄에서 시작될 수 있어요. 또는 JWT를 직접 제공할 수도 있어요. JWT는 로컬로 제공된 키를 사용해 암호학적으로 검증되거나, 구성된 경우 OIDC Discovery 서비스를 사용해 적절한 키를 가져올 수 있어요. 방식 선택은 역할별로 구성돼요.

두 방식 모두 JWT의 클레임 데이터에 대한 추가 처리를 허용해요. 두 방식에 공통된 개념을 먼저 다루고, 그다음 OIDC와 JWT 사용의 구체적인 예시를 제공해요.

출처: 문서

본문

OIDC 인증 (OIDC authentication)

이 섹션은 OIDC 역할의 설정과 사용을 다뤄요. JWT를 직접 제공하려면 아래의 [JWT 인증] 섹션을 참고하세요. OIDC 개념에 대한 기본적인 친숙함을 가정해요. Authorization Code 흐름은 PKCE(Proof Key for Code Exchange) 확장을 사용해요.

Vault는 두 가지 내장 OIDC 로그인 흐름을 포함해요: Vault UI와 vault login을 사용하는 CLI예요.

리디렉트 URI (Redirect URIs)

OIDC 역할 구성의 중요한 부분은 리디렉트 URI를 올바르게 설정하는 것이에요. 이는 Vault와 OIDC 프로바이더 양쪽에서 수행되어야 하고, 이 구성들이 일치해야 해요. 리디렉트 URI는 allowed_redirect_uris 파라미터로 역할에 지정돼요. Vault UI와 CLI 흐름을 구성하는 서로 다른 리디렉트 URI가 있으므로 설치에 따라 하나 또는 둘 다 설정해야 할 수 있어요.

CLI

vault login -method=oidc로 인증을 지원하려면 localhost 리디렉트 URI가 설정되어야 해요. 보통 http://localhost:8250/oidc/callback일 수 있어요. CLI 로그인은 필요시 다른 호스트 및/또는 수신 포트를 지정할 수 있고, 이 호스트/포트가 있는 URI는 구성된 리디렉트 URI 중 하나와 일치해야 해요. 이러한 "localhost" URI는 프로바이더에도 추가되어야 해요.

Vault UI

Vault UI를 통한 로그인은 다음 형식의 리디렉트 URI를 요구해요:

https://{host:port}/ui/vault/auth/{path}/oidc/callback

"host:port"는 Vault 서버에 대해 올바른 값이어야 하고, "path"는 JWT 백엔드가 마운트된 경로(예: "oidc" 또는 "jwt")와 일치해야 해요.

oidc_response_mode가 form_post로 설정된 경우 Vault UI 로그인은 다음 형식의 리디렉트 URI를 요구해요:

https://{host:port}/v1/auth/{path}/oidc/callback

Vault 1.6 이전에는 네임스페이스를 사용하면 쿼리 파라미터로 추가해야 했어요. 예:

https://vault.example.com:8200/ui/vault/auth/oidc/oidc/callback?namespace=my_ns

Vault 1.6+부터는 namespace_in_state가 true로 설정되면(새 구성의 기본값) 리디렉트 URI에 네임스페이스를 쿼리 파라미터로 추가할 필요가 없어요.

OIDC 로그인 (Vault UI)

  1. "OIDC" 로그인 방식을 선택합니다.
  2. 필요시 역할 이름을 입력합니다.
  3. "Sign In"을 누르고 구성된 프로바이더로 인증을 완료합니다.

OIDC 로그인 (CLI)

CLI 로그인은 기본적으로 /oidc 경로를 사용해요. 이 인증 방식이 다른 경로에 활성화되었다면 CLI에서 -path=/my-path를 지정하세요.

$ vault login -method=oidc port=8400 role=test

Complete the login via your OIDC provider. Launching browser to:

    https://myco.auth0.com/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A8400%2Foidc%2Fcallback&client_id=r3qXc2bix9eF...

브라우저가 생성된 URL로 열려 프로바이더 로그인을 완료해요. 브라우저를 자동으로 열 수 없으면 URL을 수동으로 입력할 수 있어요.

  • skip_browser (기본값: "false") — 로그인 URL로 기본 브라우저의 자동 실행을 토글.

콜백 리스너는 다음 선택적 파라미터로 사용자 지정할 수 있어요. 보통 설정할 필요는 없어요:

  • mount (기본값: "oidc")
  • listenaddress (기본값: "localhost")
  • port (기본값: 8250)
  • callbackhost (기본값: "localhost")
  • callbackmethod (기본값: "http")
  • callbackport (기본값: port에 설정된 값) — 이 값은 redirect_uri에 사용되고, port는 리스너가 사용하는 localhost 포트예요. 고급 구성에서는 이 두 값이 다를 수 있어요.

OIDC 프로바이더 구성 (OIDC provider configuration)

OIDC 인증 흐름은 많은 프로바이더로 성공적으로 테스트되었어요. OAuth/OIDC 애플리케이션 구성의 전체 가이드는 Vault 문서의 범위를 벗어나지만, 시작하는 데 도움이 되도록 프로바이더 구성 단계 모음이 수집되어 있어요: OIDC 프로바이더 설정

OIDC 구성 문제 해결 (OIDC configuration troubleshooting)

OIDC에 필요한 구성량은 상대적으로 적지만, 왜 작동하지 않는지 디버그하는 것은 까다로울 수 있어요. OIDC 설정을 위한 몇 가지 팁:

  • 역할 파라미터(예: bound_claims)가 맵 값을 요구하면 Vault CLI로 개별 설정할 수 없어요. 이런 경우 최상의 접근은 전체 구성을 단일 JSON 객체로 쓰는 것이에요:
vault write auth/oidc/role/demo -<<EOF
{
  "user_claim": "sub",
  "bound_audiences": "abc123",
  "role_type": "oidc",
  "policies": "demo",
  "ttl": "1h",
  "bound_claims": { "groups": ["mygroup/mysubgroup"] }
}
EOF
  • Vault의 로그 출력을 모니터링하세요. OIDC 검증 실패에 대한 중요한 정보가 출력될 거예요.
  • 리디렉트 URI가 Vault와 프로바이더에서 올바른지 확인하세요. 정확히 일치해야 해요. http/https, 127.0.0.1/localhost, 포트 번호, 후행 슬래시 존재 여부를 확인하세요.
  • 간단하게 시작하세요. 역할이 요구하는 유일한 클레임 구성은 user_claim이에요. 인증이 작동하는 것으로 확인되면 추가 클레임 바인딩과 메타데이터 복사를 추가할 수 있어요.
  • bound_audiences는 OIDC 역할에 대해 선택 사항이고 보통 필요하지 않아요. OIDC 프로바이더는 client_id를 오디언스로 사용하고 OIDC 검증은 이를 기대해요.
  • 필요한 모든 정보를 받으려면 프로바이더에서 어떤 스코프가 필요한지 확인하세요. "profile"과 "groups" 스코프가 자주 요청되어야 하며 역할에 oidc_scopes="profile,groups"를 설정해 추가할 수 있어요.
  • 로그에서 클레임 관련 오류가 보이면 프로바이더 문서를 매우 주의 깊게 검토해 클레임을 어떻게 명명하고 구성하는지 확인하세요. 프로바이더에 따라 검사할 수 있는 JWT를 얻는 간단한 curl 암시적 허가 요청을 구성할 수 있어요. JWT를 디코딩하는 예시(이 경우 JSON 응답의 "access_token" 필드에 있음):

cat jwt.json | jq -r .access_token | cut -d. -f2 | base64 -D

  • Vault 1.2부터 verbose_oidc_logging 역할 옵션을 사용할 수 있으며, 디버그 수준 로깅이 활성화된 경우 수신한 OIDC 토큰을 서버 로그에 기록해요. 이는 프로바이더 설정을 디버그하고 수신한 클레임이 기대한 것인지 확인할 때 유용해요. 클레임 데이터가 그대로 기록되고 민감한 정보를 포함할 수 있으므로 이 옵션은 프로덕션에서 사용하면 안 돼요.
  • Azure는 사용자가 200개 이상의 그룹 구성원일 때 약간의 추가 구성이 필요해요. Azure 전용 처리 구성에 설명되어 있어요.

JWT 인증 (JWT authentication)

"jwt" 유형 역할의 인증 흐름은 Vault가 제공된 JWT만 검증하면 되므로 OIDC보다 간단해요.

JWT 검증 (JWT verification)

Vault는 발급자의 공개 키에 대해 JWT 서명을 검증해요. 마운트된 백엔드당 다음 옵션 중 하나의 JWT 서명 검증 방식만 구성할 수 있어요:

  • 정적 키 (Static Keys) — 공개 키 세트가 백엔드 구성에 직접 저장돼요. jwt_validation_pubkeys 구성 옵션을 참고하세요.
  • JWKS — JSON Web Key Set (JWKS) URL과 선택적 인증서 체인이 구성돼요. 인증을 위해 키가 이 엔드포인트에서 가져와져요. jwks_url과 jwks_ca_pem 구성 옵션을 참고하세요.
  • JWKS 쌍 (JWKS Pairs) — 각각 대한 JSON Web Key Set (JWKS) URL 목록과 선택적 인증서 체인이 구성돼요. 인증을 위해 각 엔드포인트에서 키가 가져와지며, JWT 서명을 성공적으로 검증하는 첫 번째 세트에서 멈춰요. jwks_pairs 구성 옵션을 참고하세요.
  • OIDC Discovery — OIDC Discovery URL과 선택적 인증서 체인이 구성돼요. 인증 중에 키가 이 URL에서 가져와져요. OIDC Discovery를 사용하면 OIDC 검증 기준(예: iss, aud 등)이 적용돼요. oidc_discovery_url과 oidc_discovery_ca_pem 구성 옵션을 참고하세요.

추가 검증 방식을 구성하려면 다른 경로에 백엔드 인스턴스 하나를 방식별로 마운트하고 구성해야 해요.

JWT 서명을 검증한 후 Vault는 해당 aud 클레임을 확인해요.

인증 요청의 JWT에 aud 클레임이 포함되어 있으면 역할의 연관된 bound_audiences가 JWT에 선언된 aud 클레임 중 정확히 하나 이상과 일치해야 해요.

CLI를 통해

$ vault write auth/<path-to-jwt-backend>/login role=demo jwt=...

JWT 인증 백엔드의 기본 경로는 /jwt이므로 기본 백엔드를 사용한다면 명령은:

$ vault write auth/jwt/login role=demo jwt=...

fetch_groups가 활성화된 Azure 프로바이더를 사용해 JWT의 groups 클레임에 의존하는 대신 Microsoft Graph API에서 그룹 멤버십을 직접 가져온다면 distributed_claim_access_token 파라미터를 포함하세요:

$ vault write auth/jwt/login role=demo jwt=... distributed_claim_access_token=...

JWT 인증 백엔드가 다른 경로를 사용한다면 그 경로를 사용하세요.

API를 통해

기본 엔드포인트는 auth/jwt/login이에요. 이 인증 방식이 다른 경로에 활성화되었다면 jwt 대신 그 값을 사용하세요.

$ curl \
    --request POST \
    --data '{"jwt": "your_jwt", "role": "demo"}' \
    http://127.0.0.1:8200/v1/auth/jwt/login

응답은 auth.client_token에 토큰을 포함해요:

{
  "auth": {
    "client_token": "38fe9691-e623-7238-f618-c94d4e7bc674",
    "accessor": "78e87a38-84ed-2692-538f-ca8b9f400ab3",
    "policies": ["default"],
    "metadata": {
      "role": "demo"
    },
    "lease_duration": 2764800,
    "renewable": true
  }
}

구성 (Configuration)

인증 방식은 사용자나 머신이 인증하기 전에 미리 구성되어야 해요. 이 단계들은 보통 운영자나 설정 관리 도구가 수행해요.

1. JWT 인증 방식을 활성화합니다. "jwt" 또는 "oidc" 이름 중 하나를 사용할 수 있어요. 백엔드는 선택한 이름으로 마운트돼요.

$ vault auth enable jwt
  or
$ vault auth enable oidc

2. /config 엔드포인트를 사용해 Vault를 구성합니다. JWT 역할을 지원하려면 로컬 키, JWKS URL, 또는 OIDC Discovery URL이 있어야 해요. OIDC 역할에는 OIDC Discovery URL, OIDC Client ID, OIDC Client Secret이 필요해요. 사용 가능한 구성 옵션 목록은 API 문서를 참고하세요.

$ vault write auth/jwt/config \
    oidc_discovery_url="https://myco.auth0.com" \
    oidc_client_id="m5i8bj3iofytj" \
    oidc_client_secret="f4ubv72nfiu23hnsj" \
    default_role="demo"

JWT 토큰 검증으로 JWT 검증을 수행해야 한다면 oidc_client_id와 oidc_client_secret을 비워 두세요.

$ vault write auth/jwt/config \
   oidc_discovery_url="https://MYDOMAIN.eu.auth0.com" \
   oidc_client_id="" \
   oidc_client_secret="" \

3. 이름 있는 역할을 만듭니다.

vault write auth/jwt/role/demo \
    allowed_redirect_uris="http://localhost:8250/oidc/callback" \
    bound_subject="r3qX9DljwFIWhsiqwFiu38209F10atW6@clients" \
    bound_audiences="https://vault.plugin.auth.jwt.test" \
    user_claim="https://vault/user" \
    groups_claim="https://vault/groups" \
    policies=webapps \
    ttl=1h

이 역할은 주어진 주체와 오디언스 클레임이 있는 JWT를 인가하고, webapps 정책을 주며, 주어진 user/groups 클레임을 사용해 Identity 별칭을 설정해요.

전체 구성 옵션 목록은 API 문서를 참고하세요.

바운드 클레임 (Bound claims)

JWT가 올바르게 서명되고 만료되지 않은 것으로 검증되면 인가 흐름은 구성된 "bound" 파라미터가 일치하는지 검증해요. 경우에 따라 제공된 sub 클레임과 일치해야 하는 bound_subject와 같은 전용 파라미터가 있어요. "jwt" 유형 역할의 경우:

  1. aud 클레임이 설정되면 bound_audiences 파라미터가 필요해요.
  2. bound_audiences 파라미터는 제공된 aud 클레임 중 정확히 하나 이상과 일치해야 해요.

또한 bound_claims 맵으로 임의의 클레임 및 요구 값 집합을 확인하도록 역할을 구성할 수 있어요. 예를 들어 bound_claims가 다음과 같이 설정되었다고 가정해요:

{
  "division": "Europe",
  "department": "Engineering"
}

"division"과 "department" 클레임을 모두 포함하고 각각 "Europe"과 "Engineering"과 일치하는 값을 가진 JWT만 인가돼요. 기대 값이 목록이면 클레임은 목록의 항목 중 하나와 일치해야 해요. 이메일 주소 집합으로 인가를 제한하려면:

{
  "email": ["[email protected]", "[email protected]"]
}

바운드 클레임은 선택적으로 글로브(globs)로 구성될 수 있어요. 자세한 내용은 API 문서를 참고하세요.

메타데이터로서의 클레임 (Claims as metadata)

claim_mappings를 구성해 클레임의 데이터를 결과 인증 토큰과 별칭 메타데이터로 복사할 수 있어요. 이 역할 파라미터는 복사할 항목의 맵이에요. 맵 요소는 "<JWT claim>":"<metadata key>" 형식이에요. claim_mappings가 다음과 같이 설정되었다고 가정해요:

{
  "division": "organization",
  "department": "department"
}

이것은 JWT 클레임 "division"의 값이 메타데이터 키 "organization"으로 복사되어야 함을 지정해요. JWT "department" 클레임 값도 메타데이터로 복사되지만 키 이름을 유지해요. claim_mappings에 구성된 클레임은 JWT에 존재해야 하며 그렇지 않으면 인증이 실패해요.

참고: 메타데이터 키 이름 "role"은 예약되어 있어 클레임 매핑에 사용할 수 없어요. Vault 1.16부터 성공적인 로그인 후 엔티티의 별칭 메타데이터에서 role 키로 역할 이름을 사용할 수 있어요.

클레임 지정 및 JSON 포인터 (Claim specifications and JSON pointer)

일부 파라미터(예: bound_claims, groups_claim, claim_mappings, user_claim)는 JWT 내의 데이터를 가리키는 데 사용돼요. 원하는 키가 JWT의 최상위 수준에 있다면 이름을 직접 제공할 수 있어요. 더 낮은 수준에 중첩되어 있다면 JSON Pointer를 사용할 수 있어요.

참조할 다음 JSON 데이터를 가정해요:

{
  "division": "North America",
  "groups": {
    "primary": "Engineering",
    "secondary": "Software"
  }
}

"division" 파라미터는 최상위 키이므로 "North America"를 참조해요. "/groups/primary" 파라미터는 JSON Pointer 구문을 사용해 더 낮은 수준에서 "Engineering"을 참조해요. 유효한 JSON Pointer는 선택자로 사용될 수 있어요. 구문의 전체 설명은 JSON Pointer RFC를 참고하세요.

튜토리얼 (Tutorial)

OIDC 인증 방식 사용 예시에 대해서는 다음 튜토리얼을 참고하세요:

API

JWT Auth 플러그인은 완전한 HTTP API를 제공해요. 자세한 내용은 API 문서를 참고하세요.

Terraform

Vault Terraform 프로바이더로 JWT 인증 리소스를 프로그래밍 방식으로 관리할 수 있어요. 자세한 내용은 Terraform Registry 문서를 참고하세요.

더 알아보기 (Learn more)