问题
I defined the following first policy to deny all requests to workload1 in namespace foo unless they come from workload2 or workload3 I get RBAC: access denied when trying to access from workload2 to workload1. But when rewritten them with ALLOW policy shown below the access from workload2 to workload1 succeeded.
I wonder why is that as the two rules should be equivalent (taken from https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule where Fields in the source are ANDed together.)
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: ingress-policy
namespace: foo
spec:
selector:
matchLabels:
app: workload1
action: DENY
rules:
- from:
- source:
notPrincipals: ["cluster.local/ns/foo/sa/workload2"]
- source:
notPrincipals: ["cluster.local/ns/foo/sa/workload3"]
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: ingress-policy
namespace: foo
spec:
selector:
matchLabels:
app: workload1
action: ALLOW
rules:
- from:
- source:
Principals: ["cluster.local/ns/foo/sa/workload2"]
- source:
Principals: ["cluster.local/ns/foo/sa/workload3"]
回答1:
According to istio documentation:
Istio Authorization Policy enables access control on workloads in the mesh.
Authorization policy supports both allow and deny policies. When allow and deny policies are used for a workload at the same time, the deny policies are evaluated first. The evaluation is determined by the following rules:
- If there are any DENY policies that match the request, deny the request.
- If there are no ALLOW policies for the workload, allow the request.
- If any of the ALLOW policies match the request, allow the request.
- Deny the request.
So if deny policies are evaluated first. Your request could have been first denied and then allowed again. That's why your access from workload2 to workload1 succeeded after you add allow policy.
My question was - it seems that the two AuthorizationPolicies are the same and I wanted to validate that as I get different behavior.
Yes, they are the same, if you delete 1 of the sources it's gonna work as desired.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: ingress-policy
namespace: foo
spec:
selector:
matchLabels:
app: workload1
action: DENY
rules:
- from:
- source:
notPrincipals: ["cluster.local/ns/foo/sa/workload2"]
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: ingress-policy
namespace: foo
spec:
selector:
matchLabels:
app: workload1
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/foo/sa/workload2"]
Test results.
DENY - > notPrincipals[workload2] -> workload2 -> 200, workload3 -> 403
DENY - > principals[workload2] -> workload2 -> 403, workload3 -> 200
ALLOW -> notPrincipals[workload2] -> workload2 -> 403, workload3 -> 200
ALLOW -> principals[workload2] -> workload2 -> 200, workload3 -> 403
If you want to add 2 sources, workload2
and workload3
, then use 1 source with few principals.
Use this:
rules:
- from:
- source:
notPrincipals: ["cluster.local/ns/foo/sa/workload2","cluster.local/ns/foo/sa/workload3"]
rules:
- from:
- source:
principals: ["cluster.local/ns/foo/sa/workload2","cluster.local/ns/foo/sa/workload3"]
instead of this:
rules:
- from:
- source:
notPrincipals: ["cluster.local/ns/foo/sa/workload2"]
- source:
notPrincipals: ["cluster.local/ns/foo/sa/workload3"]
rules:
- from:
- source:
principals: ["cluster.local/ns/foo/sa/workload2"]
- source:
principals: ["cluster.local/ns/foo/sa/workload3"]
Test results.
DENY - > notPrincipals[workload2,workload3] -> workload2 -> 200, workload3 -> 200
DENY - > Principals[workload2,workload3] -> workload2 -> 403, workload3 -> 403
ALLOW -> notPrincipals[workload2,workload3] -> workload2 -> 403, workload3 -> 403
ALLOW -> Principals[workload2,workload3] -> workload2 -> 200, workload3 -> 200
来源:https://stackoverflow.com/questions/64843547/istio-authorizationpolicy-deny-rule-question