Ssoon
[5주차] 마이크로서비스 통신 보안 : 최종 사용자 인증 및 권한 부여 본문
🔒 Istio를 활용한
End-User 인증과 권한 부여
🛡️ End-User 인증과 JWT의 역할
Istio는 서비스 간 통신뿐만 아니라 최종 사용자(end-user)의 인증과 권한 부여를 지원합니다. 이를 위해 JWT를 사용하며, JWT는 클라이언트의 신원을 확인하고 권한을 부여하는 데 중요한 역할을 합니다. JWT는 컴팩트한 형태로 사용자 정보를 전달하며, Istio는 이를 활용해 보안 정책을 적용합니다.
- JWT는 클라이언트의 신원과 권한 정보를 포함하여, Istio가 이를 검증하고 정책을 적용하도록 돕습니다.
Istio는 JWT를 사용해 end-user 인증과 권한 부여를 구현하며,
보안 정책 적용을 지원합니다.
📜 JSON Web Token(JWT)이란?
- JWT는 클라이언트와 서버 간 인증을 위해 사용되는 컴팩트한 claims 표현 형식입니다.
JWT는 세 가지 주요 부분으로 구성되며, 각 부분은 점(.)으로 구분되고 Base64 URL로 인코딩됩니다. 이는 HTTP 요청에 적합하게 설계되었습니다. - JWT의 구성 요소는 다음과 같습니다:
- Header: 토큰의 유형(JWT)과 사용된 해싱 알고리즘(예: RS256)을 포함합니다.
- Payload: 사용자 정보(claims)를 포함하며, 예를 들어 사용자의 그룹이나 만료 시간이 들어갑니다.
- Signature: JWT의 진위 여부를 확인하기 위한 서명으로, 토큰의 무결성을 보장합니다
- JWT는 Header, Payload, Signature로 구성되며, 각 부분은 Base64 URL로 인코딩되어 점(.)으로 연결됩니다.
JWT는 Header, Payload, Signature로 구성된 컴팩트한 토큰으로,
클라이언트 인증에 사용됩니다.
🔍 JWT의 실제 예시
- JWT(JSON Web Token) 관련 도구를 설치
$ sudo apt install jwt
[sudo] password for ssoon:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
jwt
0 upgraded, 1 newly installed, 0 to remove and 86 not upgraded.
Need to get 1222 kB of archives.
...
- JWT의 예시 토큰을 살펴보겠습니다.
아래는 ./ch9/enduser/user.jwt 파일에 포함된 토큰을 jwt-cli 유틸리티(https://github.com/mike-engel/jwt-cli)로 디코딩한 결과입니다.
$ cat ./ch9/enduser/user.jwt | jwt -show -
Header:
{
"alg": "RS256",
"kid": "CU-ADJJEbH9bXl0tpsQWYuo4EwlkxFUHbeJ4ckkakCM",
"typ": "JWT"
}
Claims:
{
"exp": 4745145038,
"group": "user",
"iat": 1591545038,
"iss": "auth@istioinaction.io",
"sub": "9b792b56-7dfa-4e4b-a83f-e20679115d79"
}
Token Header
Header:
{
"alg": "RS256",
"kid": "CU-ADJJEbH9bXl0tpsQWYuo4EwlkxFUHbeJ4ckkakCM",
"typ": "JWT"
}
Token Claims (Payload)
Claims:
{
"exp": 4745145038,
"group": "user",
"iat": 1591545038,
"iss": "auth@istioinaction.io",
"sub": "9b792b56-7dfa-4e4b-a83f-e20679115d79"
}
- exp: 토큰의 만료 시간(expiration time)을 나타냅니다.
- group: 사용자가 속한 그룹(여기서는 user)을 나타내는 클레임입니다.
- iat: 토큰 발급 시간(issued at)을 나타냅니다.
- iss: 토큰 발급자(issuer), 여기서는 testing@secure.istio.io입니다.
- sub: 토큰의 주체(subject), 즉 사용자의 고유 식별자입니다.
- 이 클레임들은 서비스가 클라이언트의 신원과 권한을 판단하는 데 사용됩니다. 예를 들어, group: user 클레임을 통해 서비스는 해당 사용자가 user 그룹에 속해 있음을 확인하고, 적절한 접근 수준을 부여할 수 있습니다.
JWT의 Payload는 사용자 신원과 권한 정보를 포함하며,
서비스는 이를 기반으로 접근을 제어합니다.
🔐 JWT 발급 및 검증 과정
- JWT는 신뢰할 수 있는 인증 서버에서 발급되며, 검증 과정을 통해 무결성과 진위 여부가 확인됩니다. 이 과정은 다음과 같이 진행됩니다:
- 발급: 인증 서버는 private key를 사용해 JWT에 서명을 추가합니다. 이 서명은 토큰의 무결성을 보장합니다.
- 검증: 서버는 public key를 사용해 서명을 검증합니다. 이 공용 키는 JWKS(JSON Web Key Set)라는 형태로, 잘 알려진 HTTP 엔드포인트에서 제공됩니다.
JWKS의 역할
- JWKS는 인증 서버의 공용 키를 포함하며, 서비스는 이를 가져와 JWT의 서명을 검증합니다.
- 검증 과정에서는 서명을 복호화하여 토큰 데이터의 해시와 비교합니다. 일치하면 토큰이 신뢰할 수 있는 것으로 간주됩니다.
- 서버는 JWKS에서 공용 키를 가져와 JWT의 서명을 검증하고, 토큰의 신뢰성을 확인합니다.
JWT는 인증 서버에서 발급되고,
JWKS의 공용 키를 통해 검증되어 신뢰성을 보장합니다.
🚀 인증 서버 구현 옵션
- 인증 서버를 설정해 JWT를 발급하고 검증하는 방법에는 여러 가지가 있습니다:
- 애플리케이션 백엔드: 애플리케이션 프레임워크 내에서 인증 서버를 구현할 수 있습니다.
- 독립 서비스: OpenIAM(openiam.com) 또는 Keycloak(keycloak.org) 같은 전용 인증 서비스를 사용할 수 있습니다.
- Identity-as-a-Service: Auth0(auth0.com), Okta(okta.com) 같은 클라우드 기반 인증 솔루션을 활용할 수 있습니다.
- 이러한 옵션은 애플리케이션의 요구사항과 인프라에 따라 선택할 수 있습니다.
인증 서버는 애플리케이션 백엔드, 독립 서비스,
또는 Identity-as-a-Service로 구현할 수 있습니다.
📌 핵심 요약
- End-User 인증: Istio는 JWT를 사용해 end-user 인증과 권한 부여를 지원합니다.
- JWT 구조: Header, Payload, Signature로 구성되며, Base64 URL로 인코딩되어 HTTP 요청에 적합합니다.
- JWT 클레임: Payload의 클레임(예: group, exp, iss, sub)은 사용자 신원과 권한을 정의합니다.
- 발급 및 검증: 인증 서버는 private key로 JWT를 발급하고, JWKS의 public key로 검증합니다.
- 인증 서버 옵션: 애플리케이션 백엔드, OpenIAM/Keycloak, Auth0/Okta 같은 솔루션으로 인증 서버를 구축할 수 있습니다.
🔒 Istio Ingress Gateway에서
End-User 인증과 권한 부여
Istio는 JWT(JSON Web Token)를 사용해 end-user의 인증과 권한 부여를 지원하며, 특히 ingress gateway에서 이를 처리하는 것이 일반적입니다.
🛡️ Ingress Gateway에서의 End-User 인증
End-user는 identity provider에서 인증을 받아 JWT를 발급받은 사용자를 의미합니다. 이 JWT는 사용자의 신원과 권한 정보를 포함합니다. Istio 워크로드는 이 JWT를 검증하여 요청을 인증하고 권한을 부여할 수 있습니다.
이 기능은 모든 워크로드에서 수행할 수 있지만, ingress gateway에서 처리하는 것이 일반적입니다. 그 이유는 다음과 같습니다:
- 성능 향상: 유효하지 않은 요청을 초기에 차단하여 후속 서비스의 부담을 줄입니다.
- 보안 강화: JWT를 요청에서 제거(redact)하여, 후속 서비스에서 JWT가 유출되거나 재사용(replay attack)되는 것을 방지합니다.
Ingress Gateway에서 JWT 기반 end-user 인증을 처리하면
성능과 보안이 향상됩니다.
🧹 작업 환경 초기화
- RequestAuthentication 설정을 시작하기 전에, 기존 리소스를 정리하고 새로운 환경을 준비해야 합니다.
아래 명령어를 사용해 istioinaction 네임스페이스의 기존 리소스를 모두 삭제합니다.
$ kubectl delete virtualservice,deployment,service,\
destinationrule,gateway,peerauthentication,authorizationpolicy --all -n istioinaction
virtualservice.networking.istio.io "webapp-virtualservice" deleted
deployment.apps "catalog" deleted
deployment.apps "webapp" deleted
service "catalog" deleted
service "webapp" deleted
gateway.networking.istio.io "coolstore-gateway" deleted
peerauthentication.security.istio.io "webapp" deleted
authorizationpolicy.security.istio.io "catalog-viewer" deleted
authorizationpolicy.security.istio.io "webapp-allow-unauthenticated-view-default-ns" deleted
authorizationpolicy.security.istio.io "webapp-allow-view-default-ns" deleted
- 이 과정을 통해 깨끗한 환경에서 실습을 시작할 수 있습니다.
기존 리소스를 삭제하여 새로운 환경을 준비합니다.
🚀 샘플 워크로드 설정
- 환경 초기화 후, 실습에 필요한 샘플 워크로드를 배포합니다. 아래 명령어로 catalog와 webapp 서비스를 배포합니다.
$ kubectl apply -f services/catalog/kubernetes/catalog.yaml -n istioinaction
serviceaccount/catalog unchanged
service/catalog created
deployment.apps/catalog created
$ kubectl apply -f services/webapp/kubernetes/webapp.yaml -n istioinaction
serviceaccount/webapp unchanged
service/webapp created
deployment.apps/webapp created
- catalog.yaml: catalog 서비스를 배포합니다.
- webapp.yaml: webapp 서비스를 배포합니다.
- 이 워크로드는 ingress gateway를 통해 들어오는 트래픽을 처리할 준비를 합니다.
catalog와 webapp 워크로드를 배포하여
실습 환경을 구성합니다.
🌐 Ingress Gateway와 VirtualService 설정
- RequestAuthentication을 설정하기 전에, 트래픽이 Istio ingress gateway를 통해 들어오도록 Gateway와 VirtualService 리소스를 설정해야 합니다. 이는 트래픽을 webapp 서비스로 라우팅하는 역할을 합니다.
아래 명령어로 관련 리소스를 배포합니다:
$ kubectl apply -f ch9/enduser/ingress-gw-for-webapp.yaml -n istioinaction
gateway.networking.istio.io/webapp-gateway created
virtualservice.networking.istio.io/webapp-virtualservice created
- Gateway: 외부 트래픽이 ingress gateway로 들어오도록 허용합니다.
- VirtualService: 들어온 트래픽을 webapp 서비스로 라우팅합니다.
- 이 설정은 RequestAuthentication 실습을 위한 기반 환경을 완성합니다.
Gateway와 VirtualService를 설정하여
트래픽이 ingress gateway를 통해 webapp으로 라우팅되도록 합니다.
🔐 RequestAuthentication 준비
- 이제 워크로드와 트래픽 라우팅 설정이 완료되었으므로, RequestAuthentication 리소스를 사용해 JWT 기반 인증을 설정할 준비가 되었습니다. 다음 섹션에서는 RequestAuthentication의 구체적인 설정 방법과 동작 원리를 다룰 것입니다.
핵심 내용: 환경 설정 완료 후, RequestAuthentication을 통해 JWT 인증을 설정할 준비가 되었습니다.
📌 핵심 요약
- End-User 인증: Istio는 JWT를 사용해 end-user 인증과 권한 부여를 지원하며, ingress gateway에서 처리하는 것이 효율적입니다.
- Ingress Gateway의 장점: 유효하지 않은 요청을 초기에 차단하고 JWT를 제거하여 성능과 보안을 강화합니다.
- 환경 초기화: 기존 리소스를 삭제하여 깨끗한 환경을 준비합니다.
- 워크로드 배포: catalog와 webapp 서비스를 배포하여 실습 환경을 구성합니다.
- Gateway와 VirtualService: 트래픽을 ingress gateway를 통해 webapp으로 라우팅하도록 설정합니다.
🔒 Istio RequestAuthentication으로
JWT 검증하기
Istio의 RequestAuthentication 리소스는 JWT(JSON Web Token)를 검증하고, 유효한 토큰의 claims를 추출해 filter metadata에 저장합니다. 이를 통해 AuthorizationPolicy가 사용자 신원에 따라 요청을 허용하거나 거부할 수 있습니다.
🛡️ RequestAuthentication의 역할
RequestAuthentication은 ingress gateway에서 JWT를 검증하는 핵심 리소스입니다. 주요 기능은 다음과 같습니다:
- JWT 검증: 토큰의 유효성을 확인합니다.
- Claims 추출: 유효한 토큰의 claims(예: group: admin)를 추출합니다.
- Filter Metadata 저장: 추출된 claims를 filter metadata에 저장하여 AuthorizationPolicy에서 사용할 수 있게 합니다.
Filter metadata는 서비스 프록시가 요청을 처리하는 동안 필터 간에 공유되는 키-값 쌍입니다. 예를 들어, group: admin 클레임이 포함된 요청이 검증되면, 이 정보가 filter metadata에 저장되어 권한 정책에서 활용됩니다.
RequestAuthentication은
JWT를 검증하고 claims를 filter metadata에 저장해 권한 부여를 지원합니다.
📊 JWT 요청의 세 가지 결과
RequestAuthentication은 요청의 JWT 유무와 유효성에 따라 세 가지 결과를 생성합니다:
- 유효한 토큰: 토큰이 유효하면 요청이 클러스터에 허용되고, claims가 filter metadata에 저장됩니다.
- 유효하지 않은 토큰: 토큰이 유효하지 않으면 요청이 거부됩니다.
- 토큰 없는 요청: 토큰이 없으면 요청이 클러스터에 허용되지만, request identity가 없으므로 claims가 filter metadata에 저장되지 않습니다.
RequestAuthentication은 JWT 검증만 담당하며,
권한 부여는 AuthorizationPolicy가 처리합니다.
📜 RequestAuthentication 리소스 생성
- 다음은 ingress gateway에서 auth@istioinaction.io 발급자의 토큰을 검증하도록 설정한 RequestAuthentication 리소스입니다.
$ cat ch9/enduser/jwt-token-request-authn.yaml
apiVersion: "security.istio.io/v1beta1"
kind: "RequestAuthentication"
metadata:
name: "jwt-token-request-authn"
namespace: istio-system
spec:
selector:
matchLabels:
app: istio-ingressgateway
jwtRules:
- issuer: "auth@istioinaction.io" #JWT 토큰을 발급한 주체를 지정
jwks: | #JWT를 검증할 때 사용할 공개 키들을 담고 있는 JSON 형식
{ "keys":[ {"e":"AQAB","kid":"CU-ADJJEbH9bXl0tpsQWYuo4EwlkxFUHbeJ4ckkakCM","kty":"RSA","n":"zl9VRDbmVvyXNdyoGJ5uhuTSRA2653KHEi3XqITfJISvedYHVNGoZZxUCoiSEumxqrPY_Du7IMKzmT4bAuPnEalbY8rafuJNXnxVmqjTrQovPIerkGW5h59iUXIz6vCznO7F61RvJsUEyw5X291-3Z3r-9RcQD9sYy7-8fTNmcXcdG_nNgYCnduZUJ3vFVhmQCwHFG1idwni8PJo9NH6aTZ3mN730S6Y1g_lJfObju7lwYWT8j2Sjrwt6EES55oGimkZHzktKjDYjRx1rN4dJ5PR5zhlQ4kORWg1PtllWy1s5TSpOUv84OPjEohEoOWH0-g238zIOYA83gozgbJfmQ"}]}
- selector: 정책이 적용될 워크로드를 지정합니다. 여기서는 istio-ingressgateway에 적용됩니다.
- issuer: 기대하는 토큰 발급자를 정의합니다(여기서는 auth@istioinaction.io).
- jwks: 토큰 검증에 사용할 공용 키(JSON Web Key Set)를 정의합니다.
- 이 리소스를 클러스터에 적용하려면 다음 명령어를 실행합니다:
$ kubectl apply -f ch9/enduser/jwt-token-request-authn.yaml
requestauthentication.security.istio.io/jwt-token-request-authn created
RequestAuthentication 리소스는 ingress gateway에서
특정 발급자의 JWT를 검증하도록 설정합니다.
✅ 유효한 토큰 요청 테스트
- 유효한 JWT(ch9/enduser/user.jwt)를 사용해 요청을 테스트해 보겠습니다.
$ cat ch9/enduser/user.jwt
eyJhbGciOiJSUzI1NiIsImtpZCI6IkNVLUFESkpFYkg5YlhsMHRwc1FXWXVvNEV3bGt4RlVIYmVKNGNra2FrQ00iLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ3NDUxNDUwMzgsImdyb3VwIjoidXNlciIsImlhdCI6MTU5MTU0NTAzOCwiaXNzIjoiYXV0aEBpc3Rpb2luYWN0aW9uLmlvIiwic3ViIjoiOWI3OTJiNTYtN2RmYS00ZTRiLWE4M2YtZTIwNjc5MTE1ZDc5In0.jNDoRx7SNm8b1xMmPaOEMVgwdnTmXJwD5jjCH9wcGsLisbZGcR6chkirWy1BVzYEQDTf8pDJpY2C3H-aXN3IlAcQ1UqVe5lShIjCMIFTthat3OuNgu-a91csGz6qtQITxsOpMcBinlTYRsUOICcD7UZcLugxK4bpOECohHoEhuASHzlH-FYESDB-JYrxmwXj4xoZ_jIsdpuqz_VYhWp8e0phDNJbB6AHOI3m7OHCsGNcw9Z0cks1cJrgB8JNjRApr9XTNBoEC564PX2ZdzciI9BHoOFAKx4mWWEqW08LDMSZIN5Ui9ppwReSV2ncQOazdStS65T43bZJwgJiIocSCg
$ USER_TOKEN=$(< ch9/enduser/user.jwt)
$ echo "$USER_TOKEN" | jwt -show -
Header:
{
"alg": "RS256",
"kid": "CU-ADJJEbH9bXl0tpsQWYuo4EwlkxFUHbeJ4ckkakCM",
"typ": "JWT"
}
Claims:
{
"exp": 4745145038,
"group": "user",
"iat": 1591545038,
"iss": "auth@istioinaction.io",
"sub": "9b792b56-7dfa-4e4b-a83f-e20679115d79"
$ curl -H "Authorization: Bearer $USER_TOKEN" \
-sSl -o /dev/null -w "%{http_code}" webapp.istioinaction.io:30000/api/catalog
200
}
- 응답 코드 200은 인증이 성공했음을 나타냅니다. 현재 AuthorizationPolicy가 없으므로 요청이 기본적으로 허용됩니다.
유효한 JWT를 포함한 요청은 인증 후 클러스터에 허용됩니다.
❌ 유효하지 않은 토큰 요청 테스트
- 유효하지 않은 발급자(old-auth@istioinaction.io)의 토큰(ch9/enduser/not-configured-issuer.jwt)으로 요청을 테스트합니다.
$ cat ch9/enduser/not-configured-issuer.jwt
eyJhbGciOiJSUzI...
$ WRONG_ISSUER=$(< ch9/enduser/not-configured-issuer.jwt)
$ echo "$WRONG_ISSUER" | jwt -show -
Header:
{
"alg": "RS256",
"kid": "CU-ADJJEbH9bXl0tpsQWYuo4EwlkxFUHbeJ4ckkakCM",
"typ": "JWT"
}
Claims:
{
"exp": 4745151548,
"group": "user",
"iat": 1591551548,
"iss": "old-auth@istioinaction.io",
"sub": "79d7506c-b617-46d1-bc1f-f511b5d30ab0"
}
$ curl -H "Authorization: Bearer $WRONG_ISSUER" \
-sSl -o /dev/null -w "%{http_code}" webapp.istioinaction.io:30000/api/catalog
401
- 요청이 실패하며, 오류 메시지는 토큰의 발급자가 설정되지 않았음을 나타냅니다.
유효하지 않은 발급자의 토큰은
RequestAuthentication에 의해 거부됩니다.
🌐 토큰 없는 요청 테스트
- 토큰 없이 요청을 보냅니다.
$ curl -sSl -o /dev/null -w "%{http_code}" webapp.istioinaction.io:30000/api/cataloglog
200
- 응답 코드 200은 요청이 클러스터에 허용되었음을 보여줍니다. 이는 RequestAuthentication이 토큰 없는 요청을 기본적으로 허용하기 때문입니다. 하지만 이는 보안상 문제가 될 수 있으므로, 토큰 없는 요청을 차단하려면 추가 설정이 필요합니다.
토큰 없는 요청은 기본적으로 허용되지만,
보안을 위해 차단할 수 있습니다.
🚫 토큰 없는 요청 차단
- 토큰 없는 요청을 차단하려면 AuthorizationPolicy를 사용해 requestPrincipals가 없는 요청을 명시적으로 거부해야 합니다.
$ cat ch9/enduser/app-gw-requires-jwt.yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: app-gw-requires-jwt
namespace: istio-system
spec:
selector:
matchLabels:
app: istio-ingressgateway #istio-ingressgateway라는 라벨을 가진 워크로드에 적용
action: DENY #조건에 일치하는 요청은 거부됩니다.
rules:
- from:
- source:
notRequestPrincipals: ["*"] #JWT 발급자 정보가 없는 요청을 대상
to:
- operation:
hosts: ["webapp.istioinaction.io:30000"]
#대상 호스트가 webapp.istioinaction.io:30000 인 경우에만 DENY가 적용
- notRequestPrincipals: ["*"]: requestPrincipals가 없는 모든 요청을 매칭합니다.
- action: DENY: 매칭된 요청을 거부합니다.
- hosts: 특정 호스트(webapp.istioinaction.io)에만 적용됩니다.
- requestPrincipals는 JWT의 issuer와 subject 클레임을 결합한 형태(iss/sub)로, RequestAuthentication에서 검증된 후 filter metadata에 저장됩니다.
이 리소스를 적용합니다:
$ kubectl apply -f ch9/enduser/app-gw-requires-jwt.yaml
Warning: configured AuthorizationPolicy will deny all traffic to TCP ports under its scope due to the use of only HTTP attributes in a DENY rule; it is recommended to explicitly specify the port
authorizationpolicy.security.istio.io/app-gw-requires-jwt created
- 이제 토큰 없는 요청을 다시 테스트합니다:
$ curl -sSl -o /dev/null -w "%{http_code}" webapp.istioinaction.io:30000/api/catalog
403
- 응답 코드 403은 요청이 거부되었음을 나타냅니다. 이제 토큰 없는 요청이 차단됩니다.
AuthorizationPolicy를 사용해
토큰 없는 요청을 차단하여 보안을 강화할 수 있습니다.
🔐 JWT 클레임 기반 접근 제어
- 다양한 사용자에게 서로 다른 접근 수준을 부여하려면, JWT의 claims를 기반으로 AuthorizationPolicy를 설정할 수 있습니다.
예를 들어, 일반 사용자(group: user)는 읽기(GET)만 허용하고, 관리자(group: admin)는 모든 작업을 허용하도록 설정해 보겠습니다.
# 일반 사용자 토큰 : 'group: user' 클레임
$ cat ch9/enduser/user.jwt | jwt -show -
Header:
{
"alg": "RS256",
"kid": "CU-ADJJEbH9bXl0tpsQWYuo4EwlkxFUHbeJ4ckkakCM",
"typ": "JWT"
}
Claims:
{
"exp": 4745145038,
"group": "user",
"iat": 1591545038,
"iss": "auth@istioinaction.io",
"sub": "9b792b56-7dfa-4e4b-a83f-e20679115d79"
}
# 관리자 토큰 : 'group: admin' 클레임
$ cat ch9/enduser/admin.jwt | jwt -show -
Header:
{
"alg": "RS256",
"kid": "CU-ADJJEbH9bXl0tpsQWYuo4EwlkxFUHbeJ4ckkakCM",
"typ": "JWT"
}
Claims:
{
"exp": 4745145071,
"group": "admin",
"iat": 1591545071,
"iss": "auth@istioinaction.io",
"sub": "218d3fb9-4628-4d20-943c-124281c80e7b"
}
일반 사용자 정책
- 일반 사용자가 webapp의 읽기 요청(GET)을 수행할 수 있도록 설정합니다.
$ cat ch9/enduser/allow-all-with-jwt-to-webapp.yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all-with-jwt-to-webapp
namespace: istio-system
spec:
selector:
matchLabels:
app: istio-ingressgateway
action: ALLOW
rules:
- from:
- source:
requestPrincipals: ["auth@istioinaction.io/*"]
to:
- operation:
hosts: ["webapp.istioinaction.io:30000"]
methods: ["GET"]
관리자 정책
- 관리자가 모든 작업을 수행할 수 있도록 설정합니다.
$ cat ch9/enduser/allow-mesh-all-ops-admin.yaml
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "allow-mesh-all-ops-admin"
namespace: istio-system
spec:
selector:
matchLabels:
app: istio-ingressgateway
action: ALLOW
rules:
- from:
- source:
requestPrincipals: ["auth@istioinaction.io/*"]
when:
- key: request.auth.claims[group]
values: ["admin"]
- action: ALLOW는 생략되었으며, 기본값으로 적용됩니다.
- when: group 클레임이 admin인 경우에만 정책을 적용합니다.
- 이 리소스들을 클러스터에 적용합니다:
$ kubectl apply -f ch9/enduser/allow-all-with-jwt-to-webapp.yaml
authorizationpolicy.security.istio.io/allow-all-with-jwt-to-webapp created
$ kubectl apply -f ch9/enduser/allow-mesh-all-ops-admin.yaml
authorizationpolicy.security.istio.io/allow-mesh-all-ops-admin created
일반 사용자 테스트
- 일반 사용자 토큰(ch9/enduser/user.jwt)으로 읽기 요청을 테스트합니다:
$ USER_TOKEN=$(< ch9/enduser/user.jwt)
$ curl -H "Authorization: Bearer $USER_TOKEN" \
-sSl -o /dev/null -w "%{http_code}\n" webapp.istioinaction.io:30000/api/catalog
200
- 결과: 200 => 읽기 요청은 성공합니다. 하지만 쓰기 요청(POST)은 실패합니다:
$ curl -H "Authorization: Bearer $USER_TOKEN" \
-XPOST webapp.istioinaction.io:30000/api/catalog \
--data '{"id": 2, "name": "Shoes", "price": "84.00"}'
RBAC: access denied
관리자 테스트
- 관리자 토큰(ch9/enduser/admin.jwt)으로 쓰기 요청을 테스트합니다:
$ ADMIN_TOKEN=$(< ch9/enduser/admin.jwt)
$ curl -H "Authorization: Bearer $ADMIN_TOKEN" \
-sSl -o /dev/null -w "%{http_code}\n" webapp.istioinaction.io:30000/api/catalog
200
- 결과: 200 => 관리자는 쓰기 요청이 허용됩니다.
JWT claims를 기반으로 사용자별 접근 수준을 세밀하게 제어할 수 있습니다.
📌 핵심 요약
- RequestAuthentication의 역할: JWT를 검증하고 claims를 filter metadata에 저장하여 AuthorizationPolicy와 연동됩니다.
- 요청 결과: 유효한 토큰은 허용, 유효하지 않은 토큰은 거부, 토큰 없는 요청은 claims 없이 허용됩니다.
- 리소스 설정: ingress gateway에서 특정 발급자의 JWT를 검증하도록 RequestAuthentication을 설정합니다.
- 토큰 없는 요청 차단: AuthorizationPolicy로 notRequestPrincipals를 사용해 토큰 없는 요청을 거부합니다.
- 접근 제어: JWT claims를 활용해 일반 사용자는 읽기만, 관리자는 모든 작업을 허용하도록 설정할 수 있습니다.
'Istio Hands-on Study [1기]' 카테고리의 다른 글
[6주차] 데이터 플레인 문제 해결 : 잘못 구성된 데이터 플레인 (0) | 2025.04.22 |
---|---|
[5주차] 마이크로서비스 통신 보안 : 맞춤형 외부 인증 서비스와의 통합 (0) | 2025.04.22 |
[5주차] 마이크로서비스 통신 보안 : 서비스 간 트래픽 권한 부여 (0) | 2025.04.22 |
[5주차] 마이크로서비스 통신 보안 : 자동 mTLS (0) | 2025.04.22 |
[5주차] 마이크로서비스 통신 보안 : 애플리케이션-네트워킹 보안의 필요성 (0) | 2025.04.22 |