Istio AuthorizationPolicy

개요

접근 제어를 하는 리소스이다.
쿠버네티스의 네트워크 폴리시과 비슷하지만, 훨씬 광범위한 설정이 가능하다.
다른 리소스들이 그렇듯, 셀렉터 - 그냥 네임스페이스 - 루트 네임스페이스 설정이 가능하다.

일단 정책을 적용하는 방식은 다음의 흐름을 따른다.


할 수 있는 동작은 CUSTOM, DENY, ALLOW가 있는데 이들의 적용 순서는 다음과 같다.[1]
(순서가 동작을 기준으로 하기에 위에서도 먼저 언급했다.)

  1. CUSTOM 정책에 매칭된다면 CUSTOM에서 거부될 시 바로 거부된다.
    1. CUSTOM에서 ALLOW했다고 바로 허용되는 건 아니다.
  2. DENY 정책에 매칭된다면 무조건 거부한다.
  3. ALLOW 정책에 매칭된다면 허용한다.
  4. 다 매칭 안 되면 기본값으로서 거부한다.
    1. 예외적으로 ALLOW 정책이 아예 없는 상황이라면 기본값은 허용으로 세팅된다.

그림 상에서 ALLOW 정책 매칭을 나타내는 블록 혼자 분기의 방향이 다른 것을 유의하자.
왜 굳이 이렇게 헷갈리게 만들어뒀는지는 모르겠다.. 정말 이 방법밖에 없었던 거냐..!
아무튼 기본 정책은 허용이고, ALLOW 정책이 생기는 순간 기본 정책은 거부로 바뀐다.
그리고 정책 적용 순위는 CUSTOM - DENY - ALLOW 순이다.

내가 세팅한다면

리소스에 명시가 안 된 모든 요청은 거부한다.
다만 이렇게 하면 처음 기술을 도입하는 조직에서 큰 난항을 겪을 것이다.
그래서 처음 설치할 때 기본 허용을 하는 리소스를 만들어준다.
쿠버네티스에서 네임스페이스를 만들 때 기본으로 서비스 어카운트가 만들어지는 것과 비슷하게 말이다.
네트워크 폴리시도 그렇고 네트워크 정책은 왜 이랬다 저랬다 분기를 이렇게들 두는지 모르겠다.

양식 작성법

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: foo
spec:
 selector:
   matchLabels:
     app: httpbin
     version: v1
 action: ALLOW
 rules:
 - from:
   - source:
       principals: ["cluster.local/ns/default/sa/curl"]
   - source:
       namespaces: ["dev"]
   to:
   - operation:
       methods: ["GET"]
   when:
   - key: request.auth.claims[iss]
     values: ["https://accounts.*"]

위에서 말했듯 action, rules 필드가 있는 것을 볼 수 있다.
핵심이 되는 건 위에서 말한 action 별 적용 순서, 그리고 rules에서 조건을 어떻게 설정할 수 있는지에 대한 것이라 할 수 있다.

일반 패턴

전부 거부

필드를 설명하기 전에, 이 리소스를 사용하는 패턴 중 전체적인 적용을 할 때 설정하는 방법부터 알아보자.

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-nothing # 아무것도 허용하지 않음
spec:
  action: ALLOW

ALLOW 정책이 있으면, 위에서 본 동작 규칙에 따라 매칭되지 않는 모든 요청은 거부된다.
근데 위 예시는 ALLOW에 매칭하는 필드가 없으므로, 그냥 모든 요쳥을 거부 때리게 된다.

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-nothing
spec: {}

action의 기본값은 ALLOW이기 때문에 아예 이렇게 해버리는 것도 가능하다.

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: deny-all
spec:
  action: DENY
  rules:
  - {}

이런 방식으로 명시적으로 모든 대상이 걸리게 만들어서 요청을 거부 설정하는 것도 가능하다.
즉 위 두 예시는 같은 동작을 한다는 것이다.
이걸 거꾸로 하면 모든 요청을 허용하는 것도 가능하다.

익명 요청

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: foo
spec:
 action: ALLOW
 rules:
 - from:
   - source:
       principals: ["*"]

이스티오 시큐리티에서 익명 요청은 인증 단계에서 거르지 않는다고 했다.
익명 요청은 tls 기준으로는 source 부분, http 기준으로는 request.source 부분이 비워져있기 때문에, 위와 같이 세팅하면 익명 요청은 거부해버릴 수 있다.

tcp 정책

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: mongodb-policy
spec:
 selector:
   matchLabels:
     app: mongodb
 action: ALLOW
 rules:
 - from:
   - source:
       principals: ["cluster.local/ns/default/sa/bookinfo-ratings-v2"]
   to:
   - operation:
       ports: ["27017"]

대체로 인가 정책을 만들 때는 http 기반으로 세팅하지만, 순수한 TCP 요청에 대해서 정책을 적용해야 하는 경우도 있다.
이럴 때는 HTTP의 필드를 이용한 방식은 불가능하고, 위의 방법 정도만이 가능하다.
to 쪽에서는 포트 설정, source쪽에서는 tls로 들어온 신원만 사용이 가능하다(tls는 https에만 사용되진 않으니..).

dry-run

  annotations:
    "istio.io/dry-run": "true"

운영 단계에서 바로 정책을 적용했다가 나가리되는 케이스를 막기 위해, 세팅을 적용해서 테스트만 해보는 드라이 런이 가능하다.[2]
image.png
이걸 세팅하면 실제 요청에 영향을 끼치지는 않지만, 로그로 이렇게 남기 때문에 디버깅을 하기에 용이하다.
이 값은 프로메테우스 메트릭으로도 집계되니 조금 더 쉽게 모니터링할 수 있다.
참고로 1.25 기준 CUSTOM 동작에 대해서는 적용되지 않는다.

action

동작을 나타내는 필드이다.
위에서 봤듯이 CUSTOM, ALLOW, DENY가 가능하다.
여기에 추가적으로 AUDIT이라 하여 그냥 기록만 남기는 동작도 가능하다.
이걸 설정하면 로그나 메트릭, 트레이싱 정보가 추가된다.

rules

rules에 대해 들어가보자면, 웬만한 모든 값은 웬만해서 전부 GLOB 패턴을 지원한다.
다만 when.key, source.ipBlocks, to.ports 는 무조건 정확하게 값을 지정해야 한다.
또한 안티 매칭도 지원하는데, notPathes, notValues와 같은 식의 필드를 써주면된다.

from

source 필드를 리스트로 설정해 들어온 트래픽의 조건을 바탕으로 처리한다.
아래 필드들은 s가 붙은 복수형으로서 리스트로 쓸 수 있다.
그러나 s를 빼서 하나의 값만 넣는 것도 가능하고, 앞에 not을 넣어서 안티 매칭도 가능하다.

to

operation필드를 리스트로 설정한다.

when

인증된 정보나 추가 조건을 기반으로 규칙을 적용할 때 쓰는 필드로, 키값쌍을 리스트로 설정한다.

   when:
   - key: request.headers[version]
     values: ["v1", "v2"]

재밌는 건 위와 같이 []을 직접적으로 넣어 특정 키를 더 세부적으로 지정할 수 있다는 것.
위의 from, to에서 걸었던 매칭 조건들을 그냥 이 when으로 거는 것도 가능하다.
몇 개만 나열하는데 자세한 건 문서 참고.[3]

providers

spec:
  action: CUSTOM
  providers:
    name: "my-cusom-authz"

CUSTOM 동작일 때 인가 작업을 위임할 제공자를 지정하는 필드이다.
해당 제공자는 이스티오 오퍼레이터 meshConfig쪽에 지정해야 한다.
유의할 점은 CUSTOM 동작이 있다고 해서 기존 ALLOW, DENY 동작을 무시해버리는 것은 아니라는 것이다.
위에서도 봤듯이 CUSTOM이 요청에 바로 직접적인 영향을 끼치는 것은 DENY 동작 뿐이다.
ALLOW에 대해서는 여전히 이후 정책들의 적용 여부가 판단돼야 한다.

관련 문서

이름 noteType created
5W - 이스티오 mTLS와 SPIFFE published 2025-05-11
5W - 이스티오 JWT 인증 published 2025-05-11
5W - 이스티오 인가 정책 설정 published 2025-05-11
E-istio-csr 사용 실습 topic/explain 2025-06-09
E-앰비언트 모드에서 메시 기능 활용 topic/explain 2025-06-07

참고


  1. https://istio.io/latest/docs/concepts/security/#mutual-tls-authentication ↩︎

  2. https://istio.io/latest/docs/tasks/security/authorization/authz-dry-run/ ↩︎

  3. https://istio.io/latest/docs/reference/config/security/conditions/ ↩︎