JWT 인증 구성
JWT 인증 구성 (Configure JWT authentication)
Grafana를 HTTP 헤더에 제공된 JWT 토큰을 받아들이도록 구성할 수 있어요. 토큰은 다음 중 하나로 검증해요: PEM 인코딩 키 파일, 로컬 파일의 JSON Web Key Set(JWKS), 또는 구성된 JWKS 엔드포인트가 제공하는 JWKS. 이 인증 방법은 JWKS를 쓰지만 Grafana와 직접 통합할 수 없는 다른 시스템과 통합하거나, Grafana를 임베드한 앱에서 패스스루 인증을 쓰고 싶을 때 유용해요.
출처: 문서
본문
Note Grafana는 현재 refresh token을 지원하지 않아요.
JWT 활성화
- 메인 구성 파일에서 JWT를 활성화.
- 토큰을 담은 헤더 이름 지정.
[auth.jwt]
# By default, auth.jwt is disabled.
enabled = true
# HTTP header to look into to get a JWT token.
header_name = X-JWT-Assertion
로그인 클레임 구성
사용자를 식별하려면 일부 클레임을 로그인 정보로 선택해야 해요. sub라는 subject 클레임은 필수이며 JWT의 주체인 principal을 식별해야 해요. 보통 sub를 로그인으로 쓰지만 특정 앱 클레임으로 설정할 수도 있어요.
# [auth.jwt]
# ...
# Specify a claim to use as a username to sign in.
username_claim = sub
# Specify a claim to use as an email to sign in.
email_claim = sub
# auto-create users if they are not already matched
# auto_sign_up = true
auto_sign_up이 활성화되면 sub 클레임이 "external Auth ID"로 쓰이고, name 클레임이 있으면 사용자 전체 이름으로 쓰여요. 로그인 username이나 email 클레임이 JWT 구조 안에 중첩되어 있다면 username_attribute_path와 email_attribute_path 구성 옵션(JMESPath 문법)으로 속성 경로를 지정할 수 있어요.
JWT 구조 예:
{
"user": {
"UID": "1234567890",
"name": "John Doe",
"username": "johndoe",
"emails": ["[email protected]", "[email protected]"]
}
}
# [auth.jwt]
# ...
# Specify a nested attribute to use as a username to sign in.
username_attribute_path = user.username # user's login is johndoe
# Specify a nested attribute to use as an email to sign in.
email_attribute_path = user.emails[1] # user's email is [email protected]
Iframe 임베딩
사용자 ID와 역할 검사 유지하며 iframe에 Grafana를 임베드하려면 JWT 인증으로 iframe을 인증할 수 있어요.
Note Grafana Cloud나 뷰어 ID 검증이 필요 없는 시나리오에서는 공유 대시보드를 임베드하세요.
임베딩이 동작하려면 security 섹션에서
allow_embedding을 활성화해야 해요. 이 설정은 Grafana Cloud에서는 사용할 수 없어요.
이 시나리오에서는 Grafana가 HTTP 헤더에 제공된 JWT를 받아들이도록 구성하고, 리버스 프록시가 Grafana 인스턴스로의 요청을 재작성해 헤더에 JWT를 포함시켜야 해요. 요청 헤더를 재작성할 수 없는 시나리오에는 URL 로그인을 사용할 수 있어요.
URL 로그인
url_login은 Grafana가 URL 쿼리 파라미터 auth_token에서 JWT를 찾아 인증 토큰으로 사용하게 해요.
Warning 이로 인해 서버가 TLS 위에 HTTP를 사용하지 않으면 JWT가 로그에 노출되고 세션 하이재킹이 가능할 수 있어요.
# [auth.jwt]
# ...
url_login = true # enable JWT authentication in the URL
URL JWT 인증으로 Grafana에 접근하는 URL 예:
http://env.grafana.local/d/RciOKLR4z/board-identifier?orgId=1&kiosk&auth_token=eyJhbx...xxxx
이 인증 방법을 쓰는 샘플 저장소는 grafana-iframe-oauth-sample에서 볼 수 있어요.
시그니처 검증
JSON 웹 토큰 무결성을 검증해야 하므로 암호화 서명을 사용해요. 모든 토큰은 알려진 키로 서명되어야 해요. 키 위치를 지정하는 여러 옵션이 있어요.
https 엔드포인트에서 로드한 JWKS로 토큰 검증
# [auth.jwt]
# ...
jwk_set_url = https://your-auth-provider.example.com/.well-known/jwks.json
# When the JWKS url requires an 'Authorization: Bearer ***' header
# jwk_set_bearer_token_file = /path/to/bearer_token
# Cache duration for https endpoint response.
cache_ttl = 60m
# Path to file containing one or more custom PEM-encoded CA certificates.
# tls_client_ca = /path/to/ca.crt
# Skip CA Verification entirely
# tls_skip_verify_insecure = false
Note JWKS 엔드포인트에 캐시 제어 헤더가 있고 그 값이 구성된
cache_ttl보다 작으면 캐시 제어 헤더 값이 사용돼요.cache_ttl이 설정되지 않으면 기본 60m가 사용돼요.no-store와no-cache캐시 제어 헤더는 무시돼요. JWKS 캐싱을 끄려면cache_ttl = 0s.
JSON 파일에서 로드한 JWKS로 토큰 검증
JWKS 엔드포인트와 같은 형식이지만 디스크에 있는 키 셋:
jwk_set_file = /path/to/jwks.json
PEM 인코딩 파일에서 로드한 단일 키로 토큰 검증
PKIX 또는 PKCS #1 형식의 PEM 인코딩 공개 키 파일. 개인 키는 허용되지 않아요.
key_file = /path/to/key.pem
JWT 토큰 헤더가 kid(Key ID)를 지정하면 key_id 구성 옵션으로 Key ID를 설정해야 해요.
key_id = my-key-id
인라인 키 또는 키 셋으로 토큰 검증
디스크에 파일을 놓을 수 없을 때 키 자료를 구성에 직접 넣을 수 있어요. 관리형 인스턴스에 구성을 프로비저닝할 때 유용해요. 두 옵션 모두 파일 기반과 같은 콘텐츠를 한 줄에 들어가도록 base64 인코딩해요.
key_file 대신 단일 PEM 인코딩 공개 키 인라인:
key_value = <base64-encoded PEM key>
jwk_set_file 대신 JWKS 문서 인라인:
jwk_set_value = <base64-encoded JWKS JSON>
기존 파일에서 값을 생성하려면 base64 < key.pem | tr -d '\n' 실행. key_id 옵션은 key_file과 마찬가지로 key_value에도 적용돼요.
Note
key_file,key_value,jwk_set_file,jwk_set_value,jwk_set_url중 정확히 하나로 키 셋을 구성하세요. 둘 이상 설정하면 오류예요.
클레임 검증
기본적으로 exp, nbf, iat 클레임만 검증돼요. 다른 클레임이 기대와 일치하는지 expect_claims 구성 옵션으로 검증하는 것을 고려해요. 토큰 클레임은 여기에 설정된 값과 정확히 일치해야 해요.
# This can be seen as a required "subset" of a JWT Claims Set.
expect_claims = {"iss": "https://your-token-issuer", "your-custom-claim": "foo"}
역할 (Roles)
Grafana는 role_attribute_path 구성 옵션으로 지정된 JMESPath를 JWT 토큰 클레임에 적용해 역할 존재를 확인해요. role_attribute_path JMESPath 표현식 평가 결과는 유효한 Grafana 역할(None, Viewer, Editor, Admin)이어야 해요. 역할을 특정 조직에 할당하려면 Grafana에 API 요청 시 JWT와 함께 X-Grafana-Org-Id 헤더를 포함해요.
역할 매핑 구성
skip_org_role_sync가 활성화되지 않았다면 사용자 역할은 JWT에서 가져온 역할로 설정돼요. 서버 관리자 역할은 allow_assign_grafana_admin으로 매핑. 유효한 역할이 없으면 auto_assign_org_role이 지정한 역할을 할당하고, role_attribute_strict = true로 기본 할당을 비활성화. org_attribute_path와 org_mapping으로 조직·역할을 지정할 수 있어요.
기본 예 — 역할이 Editor인 사용자는 Editor를 얻음:
{
...
"role": "Editor",
...
}
role_attribute_path = role
고급 예 — admin 역할이 있으면 Admin, editor면 Editor, 아니면 Viewer:
{
...
"info": {
...
"roles": [
"engineer",
"admin",
],
...
},
...
}
role_attribute_path = contains(info.roles[*], 'admin') && 'Admin' || contains(info.roles[*], 'editor') && 'Editor' || 'Viewer'
Org roles 매핑 예제 — 사용자는 org_foo에서 Viewer, org_bar·org_baz에서 Editor:
{
...
"info": {
...
"orgs": [
"engineer",
"admin",
],
...
},
...
}
org_attribute_path = info.orgs
org_mapping = engineer:org_foo:Viewer admin:org_bar:Editor *:org_baz:Editor
Grafana Admin 역할
role_attribute_path가 GrafanaAdmin 역할을 반환해도 기본적으로는 Grafana Admin이 아니라 Admin이 할당돼요. allow_assign_grafana_admin = true로 설정하면 Grafana Admin 역할이 할당돼요.
조직 역할 매핑 건너뛰기
JWT 로그인 시 역할·권한 할당을 건너뛰고 UI 같은 다른 메커니즘으로 처리하려면 조직 역할 동기화를 건너뛸 수 있어요.
[auth.jwt]
# ...
skip_org_role_sync = true