<p>I have a cluster with istio injection enabled and cockroach db stateful set defined:</p>
<pre><code>apiVersion: v1
kind: ServiceAccount
metadata:
  name: cockroachdb-serviceaccount
---
apiVersion: v1
kind: Service
metadata:
  # This service is meant to be used by clients of the database. It exposes a ClusterIP that will
  # automatically load balance connections to the different database pods.
  name: cockroachdb-public
  labels:
    app: cockroachdb
spec:
  ports:
  # The main port, served by gRPC, serves Postgres-flavor SQL, internode
  # traffic and the cli.
  - port: 26257
    targetPort: 26257
    name: tcp
  # The secondary port serves the UI as well as health and debug endpoints.
  - port: 8080
    targetPort: 8080
    name: http
  selector:
    app: cockroachdb
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: cockroachdb-statefulset
  labels:
    version: v20.1.2
spec:
  serviceName: cockroachdb
  replicas: 3
  selector:
    matchLabels:
      app: cockroachdb
  template:
    metadata:
      labels:
        app: cockroachdb
        version: v20.1.2
    spec:
      serviceAccountName: cockroachdb-serviceaccount
      containers:
      - name: cockroachdb
        image: cockroachdb/cockroach:v20.1.2
        ports:
        - containerPort: 26257
          name: tcp
        - containerPort: 8080
          name: http
        volumeMounts:
        - name: datadir
          mountPath: /cockroach/cockroach-data
        env:
        - name: COCKROACH_CHANNEL
          value: kubernetes-insecure
        command:
          - &quot;/bin/bash&quot;
          - &quot;-ecx&quot;
          # The use of qualified `hostname -f` is crucial:
          # Other nodes aren't able to look up the unqualified hostname.
          - &quot;exec /cockroach/cockroach start --logtostderr --insecure --advertise-host $(hostname -f) --http-addr 0.0.0.0 --join cockroachdb-statefulset-0.cockroachdb,cockroachdb-statefulset-1.cockroachdb,cockroachdb-statefulset-2.cockroachdb --cache 25% --max-sql-memory 25%&quot;
      # No pre-stop hook is required, a SIGTERM plus some time is all that's
      # needed for graceful shutdown of a node.
      terminationGracePeriodSeconds: 5
      volumes:
      - name: datadir
        persistentVolumeClaim:
          claimName: datadir
  podManagementPolicy: Parallel
  updateStrategy:
    type: RollingUpdate
  volumeClaimTemplates:
  - metadata:
      name: datadir
    spec:
      accessModes:
        - &quot;ReadWriteOnce&quot;
      resources:
        requests:
          storage: 4Gi
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: cockroachdb-public
spec:
  host: cockroachdb-public
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: cockroachdb-public
spec:
  hosts:
  - cockroachdb-public
  http:
  - match:
    - port: 8080
    route:
    - destination:
        host: cockroachdb-public
        port:
          number: 8080
  tcp:
  - match:
    - port: 26257
    route:
    - destination:
        host: cockroachdb-public
        port:
          number: 26257
</code></pre>
<p>and a service that accesses it:</p>
<pre><code>apiVersion: v1
kind: ServiceAccount
metadata:
  name: downstream-serviceaccount
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: downstream-deployment-v1
  labels:
    app: downstream
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: downstream
      version: v1
  template:
    metadata:
      labels:
        app: downstream
        version: v1
    spec:
      serviceAccountName: downstream-serviceaccount
      containers:
      - name: downstream
        image: downstream:0.1
        ports:
        - containerPort: 80
        env:
          - name: DATABASE_URL
            value: postgres://roach@cockroachdb-public:26257/roach?sslmode=disable
---
apiVersion: v1
kind: Service
metadata:
  name: downstream-service
  labels:
    app: downstream
spec:
  type: ClusterIP
  selector:
    app: downstream
  ports:
    - port: 80
      targetPort: 80
      name: http
      protocol: TCP
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: downstream-service
spec:
  host: downstream-service
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: downstream-service
spec:
  hosts:
  - downstream-service
  http:
  - name: &quot;downstream-service-routes&quot;
    match:
    - port: 80
    route:
    - destination:
        host: downstream-service
        port:
          number: 80
</code></pre>
<p>Now I'd like to restrict access to cockroach db only to <code>downstream-service</code> and to cockroachdb itself (since nodes need intercommunication between each other).</p>
<p>I'm trying to restrict the traffic with something like this:</p>
<pre><code>apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: default-deny-all
 namespace: default
spec:
  {}
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: cockroachdb-authorizationpolicy-allow-from-downstream
 namespace: default
spec:
 selector:
   matchLabels:
     app: cockroachdb
 action: ALLOW
 rules:
  - from:
    - source:
       principals: [&quot;cluster.local/ns/default/sa/downstream-serviceaccount&quot;]
  - to:
    - operation:
       ports: [&quot;26257&quot;]
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: cockroachdb-authorizationpolicy-allow-from-cockroachdb
 namespace: default
spec:
 selector:
   matchLabels:
     app: cockroachdb
 action: ALLOW
 rules:
  - from:
    - source:
       principals: [&quot;cluster.local/ns/default/sa/cockroachdb-serviceaccount&quot;]
  - to:
    - operation:
       ports: [&quot;26257&quot;]
</code></pre>
<p>but doesn't seem to do anything. I can still e.g. access <code>cockroachdb-public:8080</code> cluster HTTP UI from downstream-service.</p>
<p>Now when I add the following:</p>
<pre><code>apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: default-deny-all-to-cockroachdb
 namespace: default
spec:
  selector:
    matchLabels:
      app: cockroachdb
  action: DENY
  rules:
  - to:
    - operation:
        ports: [&quot;26257&quot;]
</code></pre>
<p>then all the traffic is blocked (including the traffic between cockroachdb nodes).</p>
<p>What am I doing wrong here?</p>

<p>You are having the same problem that a guy couple of days ago. In your authorization policy you have two policies:</p>
<ul>
<li>service account <code>downstream-serviceaccount</code> (and <code>cockroachdb-serviceaccount</code> for the other authorization policy) from default namespace can access the service with labels <code>app: cockroachdb</code> on any port on <code>default</code> namespace.</li>
<li>Any service account, from any namespace can access the service with labels <code>app: cockroachdb</code>, on port 26257.</li>
</ul>
<p>In order to make it an AND, you would do this:</p>
<pre><code>apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: cockroachdb-authorizationpolicy-allow-from-cockroachdb
 namespace: default
spec:
 selector:
   matchLabels:
     app: cockroachdb
 action: ALLOW
 rules:
  - from:
    - source:
       principals: [&quot;cluster.local/ns/default/sa/cockroachdb-serviceaccount&quot;]
    to:                  &lt;- remove the dash from here
    - operation:
       ports: [&quot;26257&quot;]
</code></pre>
<p>Same with the other <code>AuthorizationPolicy</code> object. Also note that you don't need to explicitly create a <strong>DENY</strong> policy. When you create an <strong>ALLOW</strong> one, it automatically denies everything else.</p>
