JSON Web Token authentication
출처: 문서
본문
JSON Web Token 인증
JSON Web Token(JWT)은 하나 이상의 클레임을 표명하는 JSON 기반 액세스 토큰이에요. JWT는 싱글 사인온(SSO) 솔루션을 구현하는 데 흔히 사용되며, 토큰 기반 인증 시스템 범주에 속해요. JWT의 기본적인 정보 전송 및 신원 확인 수명 주기는 다음 단계에서 설명해요:
- 사용자가 자격 증명(예: 사용자 이름과 비밀번호)을 제공해 인증 서버에 로그인해요.
- 인증 서버가 자격 증명을 검증해요.
- 인증 서버가 액세스 토큰을 만들고 서명해요.
- 인증 서버가 토큰을 사용자에게 반환해요.
- 사용자가 액세스 토큰을 저장해요.
- 사용자가 사용하려는 서비스로 보내는 모든 요청에 액세스 토큰을 함께 전달해요.
- 서비스가 토큰을 검증해 액세스를 허용하거나 거부해요.
- 액세스가 허용되면 사용자는 토큰의 만료 시간까지 액세스할 수 있어요. 만료 시간은 보통 발급자가 토큰의 페이로드에 설정해요.
JWT는 사용자를 검증하는 데 필요한 모든 정보를 그 자체에 담고 있다는 점에서 자기 완결적이에요. 토큰은 Base64로 인코딩되고 서명된 JSON 객체예요.
JWT 구성 요소
JWT는 세 부분으로 구성돼요:
- 헤더
- 페이로드
- 서명
헤더
헤더에는 토큰을 인코딩하는 데 사용되는 알고리즘을 포함해, 사용 중인 서명 메커니즘에 대한 정보가 담겨 있어요. 다음 예제는 헤더의 일반적인 속성과 값을 보여줘요:
{
"alg": "HS256",
"typ": "JWT"
}
이 경우 헤더는 메시지가 해싱 알고리즘 HMAC-SHA256으로 서명되었음을 나타내요.
페이로드
JWT의 페이로드에는 JWT 클레임이 담겨 있어요. 클레임은 고유 식별자 역할을 하는, 토큰 사용자에 대한 정보예요. 이 덕분에 토큰 발급자가 신원을 검증할 수 있어요. 클레임은 이름-값 쌍이며, 페이로드에는 보통 여러 클레임이 포함돼요. 클레임을 추가할 수 있는 옵션은 매우 다양하지만, 너무 많이 추가해 페이로드가 지나치게 커지면 JWT가 컴팩트하려는 취지가 사라지므로 피하는 것이 좋아요.
클레임에는 세 가지 유형이 있어요:
- 등록된 클레임(Registered claims)은 JWT 사양에서 정의한 것으로, 예약된 이름을 가진 표준 클레임 집합으로 이루어져 있어요. 이러한 클레임의 예로는 토큰 발급자(
iss), 만료 시간(exp), 주제(sub)가 있어요. - 반면 퍼블릭 클레임(public claims)은 토큰을 공유하는 당사자들이 재량에 따라 정의해요. 퍼블릭 클레임에는 사용자 이름이나 사용자의 역할 같은 임의의 정보를 담을 수 있어요. 주의를 위해 사양에서는 클레임 이름을 등록하거나, 최소한 그 이름이 다른 클레임과 충돌하지 않도록(collision resistant) 보장하라고 권고해요.
- 프라이빗 클레임(private claims)은 페이로드에 사용자 지정 정보를 할당하는 또 다른 방법이에요. 예를 들어 이메일 주소를 담을 수 있죠. 그래서 커스텀(custom) 클레임이라고도 불려요. 프라이빗 클레임은 등록된 클레임도 퍼블릭 클레임도 아닌 것으로 간주되기 때문에, 토큰을 공유하는 두 당사자가 사용 방식에 합의해야 해요.
다음 예제는 이러한 JSON 속성을 이름-값 쌍으로 보여줘요:
{
"iss": "example.com",
"exp": 1300819380,
"name": "John Doe",
"roles": "admin, devops"
}
서명
토큰의 발급자는 Base64로 인코딩된 헤더와 페이로드에 암호화 해시 함수를 적용해 토큰 서명을 생성해요. JWT를 전달받은 클라이언트는 전송의 마지막 단계에서 이 서명을 복호화하고 검증해요.
헤더, 페이로드, 서명 이 세 부분은 마침표로 연결되어 하나의 완전한 JWT를 이뤄요:
encoded = base64UrlEncode(header) + "." + base64UrlEncode(payload)
signature = HMACSHA256(encoded, 'secretkey');
jwt = encoded + "." + base64UrlEncode(signature)
예제:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI
JWT 구성
JWT를 유일한 인증 방법으로 사용한다면, plugins.security.cache.ttl_minutes 속성을 0으로 설정해 사용자 캐시를 비활성화하세요. 이 속성에 대한 자세한 내용은 opensearch.yml을 참조하세요.
{: .important }
인증 도메인을 설정하고 HTTP 인증 유형으로 jwt를 선택하세요. 토큰에 이미 요청 검증에 필요한 모든 정보가 들어 있기 때문에, challenge는 false로, authentication_backend는 noop으로 설정해야 해요:
jwt_auth_domain:
http_enabled: true
transport_enabled: true
order: 0
http_authenticator:
type: jwt
challenge: false
config:
signing_key: "base64 encoded key"
jwt_header: "Authorization"
jwt_url_parameter: null
subject_key: null
roles_key: null
required_audience: null
required_issuer: null
jwt_clock_skew_tolerance_seconds: 20
authentication_backend:
type: noop
구성 파라미터는 다음 표에 정리되어 있어요.
| 이름 | 설명 |
|---|---|
signing_key |
토큰을 검증하는 데 사용되는 서명 키예요. 대칭 키 알고리즘을 사용한다면 Base64로 인코딩된 공유 시크릿이고, 비대칭 알고리즘을 사용한다면 공개 키를 포함해요. 여러 키를 전달하려면 쉼표로 구분된 목록을 사용하거나 키를 나열하세요. |
jwt_header |
토큰이 전송되는 HTTP 헤더예요. 일반적으로 Bearer 스키마를 사용하는 Authorization 헤더, 즉 Authorization: Bearer <token>이에요. 기본값은 Authorization이에요. 이 필드를 Authorization이 아닌 다른 값으로 바꾸면 감사 로그가 감사 메시지에서 JWT 헤더를 제대로 가리지 못하게 돼요. 감사 로깅과 함께 JWT를 사용할 때는 Authorization만 사용하는 것이 권장돼요. |
jwt_url_parameter |
토큰이 HTTP 헤더가 아니라 URL 파라미터로 전송된다면 여기서 파라미터 이름을 정의하세요. |
subject_key |
사용자 이름을 저장하는 JSON 페이로드의 키예요. 설정하지 않으면 subject 등록 클레임이 사용돼요. 중첩된 JWT 클레임에서 사용자 이름을 추출하려면 subject_key를 목록으로 구성할 수 있어요. |
roles_key |
사용자의 역할을 저장하는 JSON 페이로드의 키예요. 값은 쉼표로 구분된 역할 목록이어야 해요. 중첩된 JWT 클레임에서 역할을 추출하려면 roles_key를 목록으로 구성할 수 있어요. |
required_audience |
JWT가 지정해야 하는 오디언스(audience)의 이름이에요. 단일 값(예: project1) 또는 쉼표로 구분된 여러 값(예: project1,admin)을 설정할 수 있어요. 여러 값을 설정하면 JWT에 필수 오디언스가 최소 하나 이상 있어야 해요. 이 파라미터는 JWT의 aud 클레임에 해당해요. |
required_issuer |
JSON 페이로드에 저장된 JWT의 대상 발급자예요. 이는 JWT의 iss 클레임에 해당해요. |
jwt_clock_skew_tolerance_seconds |
JWT 인증 서버와 OpenSearch 노드의 시계 시간 사이에 생길 수 있는 불일치를 보완해, 시간 어긋남으로 인한 인증 실패를 막기 위한 시간 창을 초 단위로 설정해요. Security는 기본값으로 30초를 사용해요. 사용자 지정 값을 적용하려면 이 설정을 활용하세요. |
JWT는 자기 완결적이고 사용자가 HTTP 수준에서 인증되기 때문에, 별도의 authentication_backend는 필요하지 않아요. 이 값을 noop으로 설정하세요.
대칭 키 알고리즘: HMAC
해시 기반 메시지 인증 코드(HMAC)는 공유 키를 이용해 메시지에 서명하는 방법을 제공하는 알고리즘 그룹이에요. 이 키는 인증 서버와 Security 플러그인이 서로 공유해요. 키는 signing_key 설정에 Base64로 인코딩된 값으로 구성해야 해요:
jwt_auth_domain:
...
config:
signing_key: "a3M5MjEwamRqOTAxOTJqZDE="
...
비대칭 키 알고리즘: RSA와 ECDSA
RSA와 ECDSA는 공개/개인 키 쌍을 사용해 토큰을 서명하고 검증하는 비대칭 암호화 및 디지털 서명 알고리즘이에요. 즉, 토큰 서명에는 개인 키를 사용하고, Security 플러그인은 토큰 검증을 위해 공개 키만 알면 돼요.
공개 키로는 새 토큰을 발급할 수 없고, 토큰 생성자가 누구인지 타당하게 판단할 수 있기 때문에, RSA와 ECDSA는 HMAC보다 더 안전한 것으로 여겨져요.
RS256을 사용하려면 JWT 구성에서 (Base64로 인코딩되지 않은) RSA 공개 키만 signing_key로 구성하면 돼요:
jwt_auth_domain:
...
config:
signing_key: |-
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQK...
-----END PUBLIC KEY-----
...
Security 플러그인이 알고리즘(RSA/ECDSA)을 자동으로 감지해요. 필요하다면 키를 여러 줄로 나눠 작성할 수도 있어요.
HTTP 요청의 Bearer 인증
HTTP 요청에서 JWT를 전송하는 가장 일반적인 방법은 bearer 인증 스키마를 사용하는 HTTP 헤더로 추가하는 거예요:
Authorization: Bearer <JWT>
헤더의 기본 이름은 Authorization이에요. 인증 서버나 프록시가 요구한다면 jwt_header 구성 키를 사용해 다른 HTTP 헤더 이름을 쓸 수도 있어요.
HTTP 기본 인증과 마찬가지로, HTTP 요청에서 JWT를 전송할 때는 HTTP 대신 HTTPS를 사용해야 해요.
HTTP 요청의 쿼리 파라미터
HTTP 요청에서 JWT를 전송하는 가장 일반적인 방법은 헤더 필드를 사용하는 것이지만, Security 플러그인은 파라미터도 지원해요. 다음 키를 사용해 GET 파라미터의 이름을 구성하세요:
config:
signing_key: ...
jwt_url_parameter: "parameter_name"
subject_key: ...
roles_key: ...
HTTP 기본 인증과 마찬가지로, HTTP 대신 HTTPS를 사용해야 해요.
검증되는 등록 클레임
다음 등록 클레임은 자동으로 검증돼요:
iat(Issued At) 클레임nbf(Not Before) 클레임exp(Expiration Time) 클레임
지원되는 포맷과 알고리즘
Security 플러그인은 모든 표준 알고리즘으로 디지털 서명된 컴팩트 JWT를 지원해요:
HS256: HMAC using SHA-256
HS384: HMAC using SHA-384
HS512: HMAC using SHA-512
RS256: RSASSA-PKCS-v1_5 using SHA-256
RS384: RSASSA-PKCS-v1_5 using SHA-384
RS512: RSASSA-PKCS-v1_5 using SHA-512
PS256: RSASSA-PSS using SHA-256 and MGF1 with SHA-256
PS384: RSASSA-PSS using SHA-384 and MGF1 with SHA-384
PS512: RSASSA-PSS using SHA-512 and MGF1 with SHA-512
ES256: ECDSA using P-256 and SHA-256
ES384: ECDSA using P-384 and SHA-384
ES512: ECDSA using P-521 and SHA-512
JWKS 엔드포인트를 사용해 JWT 검증하기
서명된 JWT의 시그니처를 검증하는 것은 사용자 접근을 허가하는 마지막 단계예요. 클라이언트가 REST 요청과 함께 JWT를 보내면 OpenSearch가 시그니처를 검증해요. 시그니처는 매 인증 요청마다 확인돼요.
검증에 사용되는 암호화 키를 로컬 config.yml 파일의 authc 섹션에 저장하는 대신, JSON Web Key Set(JWKS) 엔드포인트를 지정하여 발급자(issuer) 서버에 저장된 위치에서 키를 가져올 수 있어요. 이 JWT 검증 방식은 공개 키와 인증서 관리를 간소화하는 데 도움이 될 수 있어요.
JSON Web Key의 내용과 형식에 대한 자세한 내용은 JSON Web Key(JWK) 형식을 참고하세요.
JWT 인증을 위한 JWKS 엔드포인트 구성
JWKS 엔드포인트는 JWT 인증 도메인에 직접 구성할 수 있어요. 이 방식은 자동 키 순환과 동적 키 관리를 통해 향상된 보안을 제공해요:
jwt_auth_domain:
description: "Authenticate via JSON Web Token"
http_enabled: true
transport_enabled: true
order: 0
http_authenticator:
type: jwt
challenge: false
config:
jwks_uri: "https://example.com/.well-known/jwks.json"
signing_key: null # Not used when jwks_uri is specified
jwt_header: "Authorization"
jwt_url_parameter: null
jwt_clock_skew_tolerance_seconds: 30
roles_key: "roles"
subject_key: "sub"
authentication_backend:
type: noop
{% include copy.html %}
JWKS 구성 파라미터
다음 표는 JWKS 관련 구성 파라미터를 설명해요.
| 이름 | 설명 | 기본값 |
|---|---|---|
jwks_uri |
JWKS 엔드포인트 URL이에요. 지정하면 signing_key는 무시되고 이 엔드포인트에서 키를 가져와요. |
null |
(고급) 보안 보호
서비스 거부(DoS) 공격으로부터 보호하고 안전한 JWKS 작업을 보장하기 위해, Security 플러그인은 요청 제한, 타임아웃, 응답 크기 제한 등 여러 보호 조치를 제공해요. 다음 표는 JWKS 작업을 보호하기 위해 사용할 수 있는 설정을 설명해요.
| 이름 | 설명 | 기본값 |
|---|---|---|
max_jwks_keys |
JWKS 응답에서 처리할 키의 최대 개수예요. 무제한으로 설정하려면 -1을 지정하세요. |
-1 |
jwks_request_timeout_ms |
JWKS 엔드포인트로의 단일 HTTP 요청에 허용되는 최대 시간이에요. 단위는 밀리초예요. | 5000 |
jwks_queued_thread_timeout_ms |
요청이 처리되기 전까지 큐에서 대기할 수 있는 최대 시간이에요. 단위는 밀리초예요. | 2500 |
max_jwks_response_size_bytes |
JWKS 엔드포인트 응답의 최대 크기예요. 단위는 바이트예요. | 1048576 (1 MB) |
refresh_rate_limit_count |
시간 창 내에서 허용되는 JWKS 새로 고침 요청의 최대 개수예요. | 10 |
refresh_rate_limit_time_window_ms |
JWKS 새로 고침 요청에 대한 속도 제한 시간 창이에요. 단위는 밀리초예요. | 10000 (10초) |
키 ID가 포함된 JWT 헤더
JWKS를 사용할 때는 JWT 헤더에 검증에 사용할 특정 키를 식별하는 키 ID(kid)가 반드시 포함되어야 해요:
{
"alg": "RS256",
"typ": "JWT",
"kid": "V-diposfUJIk5jDBFi_QRouiVinG5PowskcSWy5EuCo"
}
{% include copy.html %}
kid 파라미터는 JWKS 엔드포인트를 사용할 때 필수이며, JWKS 응답의 키 식별자 중 하나와 일치해야 해요.
JWKS 응답 예시
JWKS 엔드포인트는 공개 키 배열을 담은 JSON 객체를 반환해야 해요. 각 키에는 키 타입(kty), 용도(use), 키 ID(kid), 알고리즘(alg) 같은 메타데이터가 반드시 포함되어야 해요:
{
"keys": [
{
"kty": "RSA",
"use": "sig",
"kid": "V-diposfUJIk5jDBFi_QRouiVinG5PowskcSWy5EuCo",
"alg": "RS256",
"n": "nCJ9ve8zRv_4pdSja5i_8GgozoVZrUocD6UnMyQmh6fRBZWspoIRSGdTjcKktevnKWXlg7mqe7FIx6CdVqR5rVfM0o61_7cgxJqdNdnCXsFR8_S_98qMIJ-gxmlwE2a1X1VrCSmYh60APUGoGypm0sAsjvYTzU04LTN7K0Gip3H5qpkFD-Mxlev75WeC8WrvsfUFl6XN1h55HZW2wlYJGmbFVQx5839d8o6BxDVvQrGdN8MzLRFTMG8wiPhVDQL5NHt3vKgDnD6zT0c_S5Kz42i4bcktRRoAbR3LjDn5YbAatmfKzwOuL0XsbEnn-kgnt2aJ5GCaggukY3mMc-Bhew",
"e": "AQAB"
}
]
}
{% include copy.html %}
캐싱과 성능
성능 최적화를 위해 JWKS 응답은 캐시돼요:
- 초기 캐시: JWKS가 활성화되면 시스템이 JWKS 엔드포인트 응답을 캐시해요.
- 다음과 같은 상황에서 캐시 새로 고침이 트리거돼요:
- JWT에 캐시에서 찾을 수 없는
kid가 포함된 경우 - HTTP 캐시 헤더에 따라 캐시 항목이 만료된 경우
- 백그라운드 새로 고침 주기 동안
- JWT에 캐시에서 찾을 수 없는
- 속도 제한: JWKS 엔드포인트로의 과도한 요청을 방지해요(기본적으로 10초 창당 10개의 요청).
하위 호환성
JWT 인증은 OpenSearch 3.3부터 JWKS 엔드포인트 직접 구성을 지원해요. 이 기능은 완전한 하위 호환성을 유지해요:
jwks_uri를 지정하지 않거나null로 설정하면 시스템이 기존의 정적signing_key메커니즘을 사용해요.- 기존 JWT 구성은 수정 없이도 계속 동작해요.
- 구성을 업데이트하여 정적 키와 JWKS 간에 전환할 수 있어요.
jwks_uri와signing_key를 모두 구성하면jwks_uri가 우선 적용되고signing_key는 무시돼요.
Teleport와 함께 JWT 사용하기
Teleport에서 발급한 JWT 토큰을 사용하여 OpenSearch Dashboards에서 사용자를 인증할 수 있어요. 이 통합은 접근 제어를 위해 Teleport 역할을 OpenSearch 백엔드 역할에 매핑해요.
Teleport 구성
Teleport에서 OpenSearch 인스턴스의 백엔드 역할과 동일한 이름을 가진 역할을 만들어야 해요:
apiVersion: resources.teleport.dev/v1
kind: TeleportRoleV7
metadata:
name: admin # Match Opensearch "Backend roles" names
spec:
allow:
# App
app_labels_expression: |
regexp.match(labels["hostname"], "^(.*)opensearch(.*)$")
{% include copy.html %}
그런 다음 해당 역할을 사용할 사용자에게 이 역할을 적용하세요.
OpenSearch Dashboards 구성
Teleport를 사용하도록 OpenSearch를 구성하려면 다음 작업을 수행하세요.
Teleport 구성
에이전트 구성 파일(보통 /etc/teleport.yaml에 위치)에서 애플리케이션 서비스가 요청 헤더에 JWT를 자동으로 포함하도록 구성하세요:
# [...]
app_service:
enabled: "yes"
apps:
- name: opensearch-dashboard
uri: "https://127.0.0.1:5601"
insecure_skip_verify: true
rewrite:
headers:
- "Authorization: {% raw %}{{internal.jwt}}{% endraw %}"
labels:
# [...]
{% include copy.html %}
그런 다음 이 명령을 실행해 새 구성을 적용하세요:
systemctl restart teleport
{% include copy.html %}
OpenSearch Dashboards 구성
OpenSearch Dashboards 구성 파일(보통 /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml에 위치)에서 JWT 인증을 활성화하고 기본 HTTP 인증은 폴백 방법으로 유지하세요:
opensearch_security.auth.multiple_auth_enabled: true
opensearch_security.auth.type: ["basicauth", "jwt"]
{% include copy.html %}
그런 다음 이 명령을 실행해 새 구성을 적용하세요:
systemctl restart dashboards
{% include copy.html %}
Security 노드 구성
securityadmin.sh 스크립트를 실행하는 노드에서 Security 플러그인 구성 파일(예: /usr/share/opensearch/config/opensearch-security/config.yml)을 업데이트하여 두 가지 인증 방법을 모두 구성하세요:
_meta:
type: "config"
config_version: 2
config:
dynamic:
authc:
basic_internal_auth_domain:
description: "Authenticate via HTTP Basic against internal users database"
http_enabled: true
transport_enabled: true
order: 1
http_authenticator:
type: basic
challenge: true
authentication_backend:
type: internal
jwt_auth_domain:
description: "Authenticate via Json Web Token provide by Teleport"
http_enabled: true
transport_enabled: true
order: 0
http_authenticator:
type: jwt
challenge: false
config:
signing_key: null
jwks_uri: "https://example.com/.well-known/jwks.json" # URL of the Teleport's leaf the machine is in, not the root
jwt_header: "Authorization"
jwt_url_parameter: null
jwt_clock_skew_tolerance_seconds: 30
subject_key: "sub"
roles_key: "roles"
authentication_backend:
type: noop
{% include copy.html %}
기본 인증은 order: 1과 challenge: true로, JWT 인증은 order: 0과 challenge: false로 구성되어 있는지 확인하세요. 그렇지 않으면 JWT 헤더를 명시적으로 포함하지 않는 한 직접 API 호출이 실패해요.
새 구성을 적용하려면 다음 명령을 실행하세요:
{% raw %}
export JAVA_HOME="[OPENSEARCH_INSTALL_DIR]/jdk"
bash [OPENSEARCH_INSTALL_DIR]/plugins/opensearch-security/tools/securityadmin.sh \
-cacert [PATH_TO_ROOT_CA] \
-cert [PATH_TO_ADMIN_CERT_PEM] \
-key [PATH_TO_ADMIN_CERT_KEY] \
-cd [PATH_TO_OPENSEARCH_SECURITY_CONFIG_DIR] \
-nhnv -icl \
-h 127.0.0.1
{% endraw %}
{% include copy.html %}
gRPC와 함께 JWT 인증 사용하기
3.5에 도입됨 {: .label .label-purple }
JWT 인증은 gRPC 전송에서 지원돼요. gRPC 전송은 HTTP 계층과 동일한 인증 도메인을 공유하기 때문에, JWT 토큰은 동일한 인증 백엔드 구성을 기준으로 검증돼요. REST API를 사용할 때와 마찬가지로 gRPC를 통해서도 동일한 JWT 헤더를 제공할 수 있어요.
gRPC를 통해 JWT를 전송할 때는 TLS를 반드시 활성화해야 해요. gRPC용 TLS 구성 방법은 gRPC용 TLS 인증서 구성을 참고하세요.
다음 제한 사항에 유의하세요:
- 슈퍼유저 인증(클라이언트 인증서 인증)은 gRPC에서 지원되지 않아요. 슈퍼유저 권한이 필요한 구성 변경은 REST API를 사용해야 해요.
- 익명 인증은 gRPC에서 지원되지 않아요. 익명 인증 헤더가 포함된 요청은 권한 없음으로 거부돼요.
일반적인 문제 해결
이 섹션에서는 보안 구성에서 발생하는 일반적인 문제를 해결하는 방법을 자세히 설명해요.
올바른 클레임 확인하기
JWT 토큰에 올바른 iat(issued at, 발급 시각), nbf(not before, 유효 시작 시각), exp(expiry, 만료 시각) 클레임이 포함되어 있는지 확인하세요. 이 클레임들은 모두 OpenSearch가 자동으로 검증해요.
JWT URL 파라미터
기본 관리자 역할인 all_access가 포함된 JWT URL 파라미터를 사용하면(예: curl http://localhost:9200?jwtToken=<jwt-token>) 요청이 실패하면서 다음 오류가 발생해요:
{
"error":{
"root_cause":[
{
"type":"security_exception",
"reason":"no permissions for [cluster:monitor/main] and User [name=admin, backend_roles=[all_access], requestedTenant=null]"
}
],
"type":"security_exception",
"reason":"no permissions for [cluster:monitor/main] and User [name=admin, backend_roles=[all_access], requestedTenant=null]"
},
"status":403
}
이 문제를 해결하려면 all_access 역할이 백엔드 역할이 아닌 내부 사용자에게 직접 매핑되어 있는지 확인하세요. 이렇게 하려면 Security > Roles > all_access로 이동한 다음 Mapped users 탭을 선택하세요. Manage mapping을 선택하고 Users 섹션에 "admin"을 추가하세요.

그러면 해당 사용자가 Mapped Users 탭에 나타나요.

OpenSearch Dashboards 구성
JWT URL 파라미터 인증은 OpenSearch를 직접 쿼리할 때는 잘 동작하지만, OpenSearch Dashboards에 접근하는 데 사용하면 실패해요.
해결 방법: opensearch_dashboards.yml 구성 파일에 다음 줄이 포함되어 있는지 확인하세요:
opensearch_security.auth.type: "jwt"
opensearch_security.jwt.url_param: <your-param-name-here>