Istio AuthorizationPolicy
개요
접근 제어를 하는 리소스이다.
쿠버네티스의 네트워크 폴리시과 비슷하지만, 훨씬 광범위한 설정이 가능하다.
다른 리소스들이 그렇듯, 셀렉터 - 그냥 네임스페이스 - 루트 네임스페이스 설정이 가능하다.
일단 정책을 적용하는 방식은 다음의 흐름을 따른다.
- 대상 지정
- 셀렉터를 쓰던, 네임스페이스건 아무튼 대상 지정
- 동작 - 허용할지 말지에 대한 정의
- 이 동작에 매칭될 규칙(rule) 정의
- from으로 요청의 출처 기반
- to로 요청 동작 기반
- when으로 규칙을 적용할 조건 제시
할 수 있는 동작은 CUSTOM, DENY, ALLOW가 있는데 이들의 적용 순서는 다음과 같다.[1]
(순서가 동작을 기준으로 하기에 위에서도 먼저 언급했다.)
- CUSTOM 정책에 매칭된다면 CUSTOM에서 거부될 시 바로 거부된다.
- CUSTOM에서 ALLOW했다고 바로 허용되는 건 아니다.
- DENY 정책에 매칭된다면 무조건 거부한다.
- ALLOW 정책에 매칭된다면 허용한다.
- 다 매칭 안 되면 기본값으로서 거부한다.
- 예외적으로 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]
이걸 세팅하면 실제 요청에 영향을 끼치지는 않지만, 로그로 이렇게 남기 때문에 디버깅을 하기에 용이하다.
이 값은 프로메테우스 메트릭으로도 집계되니 조금 더 쉽게 모니터링할 수 있다.
참고로 1.25 기준 CUSTOM 동작에 대해서는 적용되지 않는다.
action
동작을 나타내는 필드이다.
위에서 봤듯이 CUSTOM, ALLOW, DENY가 가능하다.
여기에 추가적으로 AUDIT이라 하여 그냥 기록만 남기는 동작도 가능하다.
이걸 설정하면 로그나 메트릭, 트레이싱 정보가 추가된다.
rules
rules
에 대해 들어가보자면, 웬만한 모든 값은 웬만해서 전부 GLOB 패턴을 지원한다.
다만 when.key
, source.ipBlocks
, to.ports
는 무조건 정확하게 값을 지정해야 한다.
또한 안티 매칭도 지원하는데, notPathes
, notValues
와 같은 식의 필드를 써주면된다.
from
source
필드를 리스트로 설정해 들어온 트래픽의 조건을 바탕으로 처리한다.
아래 필드들은 s가 붙은 복수형으로서 리스트로 쓸 수 있다.
그러나 s를 빼서 하나의 값만 넣는 것도 가능하고, 앞에 not을 넣어서 안티 매칭도 가능하다.
- principals - 인증서 기반으로 밝혀진 신원
- SPIFFE 형식으로
"<TRUST_DOMAIN>/ns/<NAMESPACE>/sa/<SERVICE_ACCOUNT>"
으로 쓰면 된다. - 이거 말고 serviceAccoun
- SPIFFE 형식으로
- requestPrincipals - http에서 JWT 기반으로 밝혀진 신원
<ISS>/<SUB>
방식으로 들어온다.
- namspaces, serviceAccounts
- ipBlocks - 단일 소스 IP, 혹은 CIDR 대역을 매칭한다.
- remoteIpBlocks -
X-Forwarded-For
헤더 기반으로 매칭한다.
to
operation
필드를 리스트로 설정한다.
- hosts - http 요청 헤더에 들어온 값 기준 매칭으로, 포트 정보까지 담긴다.
- ports - 이건 tcp 요청에서의 포트를 말한다.
- methods - gRPC를 매칭하려면 POST를 써줘야 한다.
- paths -
/foo/{*}/bar/{**}
와 같은 식으로 괄호로 감싸서 glob를 쓰면 된다.
when
인증된 정보나 추가 조건을 기반으로 규칙을 적용할 때 쓰는 필드로, 키값쌍을 리스트로 설정한다.
when:
- key: request.headers[version]
values: ["v1", "v2"]
재밌는 건 위와 같이 []
을 직접적으로 넣어 특정 키를 더 세부적으로 지정할 수 있다는 것.
위의 from, to에서 걸었던 매칭 조건들을 그냥 이 when
으로 거는 것도 가능하다.
몇 개만 나열하는데 자세한 건 문서 참고.[3]
- request.headers
- source.ip
- source.principal
- request.auth.principal
- request.auth.audiences
- connection.sni - tls의 sni 값.
- experimental.envoy.filters.*
- 엔보이에서 추가적인 필터를 걸어 생긴 메타데이터.
experimental.envoy.filters.network.mysql_proxy[db.table]
와 같은 식으로 세팅한다.["[update]"]
와 같은 식으로 value를 적는다.
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 |