Repository: linkerd/linkerd2
Pull request #6890 (2021-09-15 06:19:01)

integrationtests: check for stat output of policy resources
This PR adds a new `policy` integration tests suite
to check the output of for the `srv` and `saz` commands and
make sure they have the expected format.

This is majorly needed to make sure things work as expected
with stat cmd output without having to do manual testing.

Signed-off-by: Tarun Pothulapati <tarunpothulapati@outlook.com>

<!--  Thanks for sending a pull request!

If you already have a well-structured git commit message, chances are GitHub
set the title and description of this PR to the git commit message subject and
body, respectively. If so, you may delete these instructions and submit your PR.

If this is your first time, please read our contributor guide:
https://github.com/linkerd/linkerd2/blob/main/CONTRIBUTING.md

The title and description of your Pull Request should match the git commit
subject and body, respectively. Git commit messages are structured as follows:

```
Subject

Problem

Solution

Validation

Fixes #[GitHub issue ID]

DCO Sign off
```

Example git commit message:

```
Introduce Pull Request Template

GitHub's community guidelines recommend a pull request template, the repo was
lacking one.

Introduce a `PULL_REQUEST_TEMPLATE.md` file.

Once merged, the
[Community profile checklist](https://github.com/linkerd/linkerd2/community)
should indicate the repo now provides a pull request template.

Fixes #3321

Signed-off-by: Jane Smith <jane.smith@example.com>
```

Note the git commit message subject becomes the pull request title.

For more details around git commits, see the section on Committing in our
contributor guide:
https://github.com/linkerd/linkerd2/blob/main/CONTRIBUTING.md#committing
-->



Patch:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 51f541eeb..0a30571fd 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -131,7 +131,10 @@ jobs:
         - uninstall
         - upgrade-edge
         - upgrade-stable
-        - cni-calico-deep
+          # temporarily disabled; 
+          # image used in manifests for calico-operator
+          # does not exist in image repository yet
+          #- cni-calico-deep
     needs: [docker_build, policy_controller_manifest]
     name: Integration tests (${{ matrix.integration_test }})
     timeout-minutes: 60
diff --git a/.proxy-version b/.proxy-version
index fe67ec870..19ecb4e10 100644
--- a/.proxy-version
+++ b/.proxy-version
@@ -1,1 +1,1 @@
-v2.158.0
+v2.159.0
diff --git a/CHANGES.md b/CHANGES.md
index 3b168b34e..69eda5c62 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,40 @@
 # Changes
 
+## edge-21.9.3
+
+This edge is a release candidate for `stable-2.11.0`! It features a new `linkerd
+authz` CLI command to list servers and authorizations for a workload, as well as
+policy resources support for `linkerd viz stat`. Furthermore, this edge release
+adds support for JSON log formatting, enables TLS detection on port 443
+(previously marked as opaque), and further improves policy features.
+
+* Removed port 443 from the default list of opaque ports, this will allow the
+  proxy to report metadata (such as the connection's SNI value) on TLS
+  connections to port 443
+* Added default policies for core Linkerd extensions
+* Added support for JSON log formatting to the policy controller
+* Added support for new policy resources to `viz stat` command
+* Added default policy annotation to `linkerd-identity`
+* Added a new `linkerd authz` command to the CLI to list all server and
+  authorization resources that apply to a specific resource
+* Added TLS labels (including client identity) to authorization metrics in the
+  proxy
+* Changed the opaque ports CLI check to consider service and pod ports when
+  checking annotation values; previously, the check would naively issue warnings
+  when the service annotation values were different from the pod it selected
+* Changed how the proxy forwards inbound connections to a pod locally; the proxy
+  now targets the original address instead of a port bound on localhost to
+  protect services that are only bound on loopback from being exposed to other
+  pods
+* Improved memory utilization in the proxy, especially for TCP forwarding, where
+  the memory allocated was reduced from 128KB to 16KB
+* Updated the inbound policy system for the proxies to always allow connections
+  from localhost
+* Fixed an issue where the policy controller would not detect changes to the
+  `proxyProtocol` field of `Server` resources
+* Fixed an issue where the policy admission controller would log a `WARN`
+  message when deserializing `Server` structs
+
 ## edge-21.9.2
 
 This edge release gets us closer to 2.11 by further polishing the policy
diff --git a/bin/helm-build b/bin/helm-build
index bfeb90dc8..7ab8976ac 100755
--- a/bin/helm-build
+++ b/bin/helm-build
@@ -30,6 +30,7 @@ rm -f viz/charts/linkerd-viz/charts/*
 
 "$bindir"/helm dep up "$rootdir"/multicluster/charts/linkerd-multicluster
 "$bindir"/helm lint "$rootdir"/multicluster/charts/linkerd-multicluster
+"$bindir"/helm dep up "$rootdir"/multicluster/charts/linkerd-multicluster-link
 "$bindir"/helm lint "$rootdir"/multicluster/charts/linkerd-multicluster-link
 "$bindir"/helm lint "$rootdir"/charts/partials
 "$bindir"/helm dep up "$rootdir"/charts/linkerd2-cni
diff --git a/charts/linkerd2/templates/destination.yaml b/charts/linkerd2/templates/destination.yaml
index fb5ca1b4a..bbea55d92 100644
--- a/charts/linkerd2/templates/destination.yaml
+++ b/charts/linkerd2/templates/destination.yaml
@@ -50,7 +50,6 @@ metadata:
     linkerd.io/control-plane-ns: {{.Values.namespace}}
   annotations:
     {{ include "partials.annotations.created-by" . }}
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/jaeger/charts/linkerd-jaeger/templates/jaeger-injector-policy.yaml b/jaeger/charts/linkerd-jaeger/templates/jaeger-injector-policy.yaml
new file mode 100644
index 000000000..301fd67f2
--- /dev/null
+++ b/jaeger/charts/linkerd-jaeger/templates/jaeger-injector-policy.yaml
@@ -0,0 +1,56 @@
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: jaeger-injector-webhook
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+      component: jaeger-injector
+  port: jaeger-injector
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: jaeger-injector-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+      component: jaeger-injector
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: jaeger-injector
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    selector:
+      matchLabels:
+        linkerd.io/extension: jaeger
+        component: jaeger-injector
+  client:
+    # traffic coming from the kubelet and from kube-api
+    unauthenticated: true
diff --git a/jaeger/charts/linkerd-jaeger/templates/proxy-admin-policy.yaml b/jaeger/charts/linkerd-jaeger/templates/proxy-admin-policy.yaml
new file mode 100644
index 000000000..9f936b1cc
--- /dev/null
+++ b/jaeger/charts/linkerd-jaeger/templates/proxy-admin-policy.yaml
@@ -0,0 +1,33 @@
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: jaeger
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: jaeger
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
diff --git a/jaeger/charts/linkerd-jaeger/templates/tracing-policy.yaml b/jaeger/charts/linkerd-jaeger/templates/tracing-policy.yaml
new file mode 100644
index 000000000..007a73e51
--- /dev/null
+++ b/jaeger/charts/linkerd-jaeger/templates/tracing-policy.yaml
@@ -0,0 +1,232 @@
+{{ if .Values.collector.enabled -}}
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: collector-otlp
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 4317
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: collector-opencensus
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 55678
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: collector-zipkin
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 9411
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: collector-jaeger-thrift
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 14268
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: collector-jaeger-grpc
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 14250
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: collector-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 13133
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: collector
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    selector:
+      matchLabels:
+        linkerd.io/extension: jaeger
+        component: collector
+  client:
+    # allow connections from any pod (meshed or not) sending trace data
+    unauthenticated: true
+{{ end -}}
+{{ if .Values.jaeger.enabled -}}
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: jaeger-grpc
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      component: jaeger
+  port: grpc
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: jaeger-grpc
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: jaeger-grpc
+  client:
+    meshTLS:
+      serviceAccounts:
+      - name: collector
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: jaeger-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      component: jaeger
+  port: admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: jaeger-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: jaeger-admin
+  client:
+    meshTLS:
+      serviceAccounts:
+      # if not using linkerd-viz' prometheus, replace its SA here
+      - name: prometheus
+        namespace: linkerd-viz
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: jaeger-ui
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      component: jaeger
+  port: ui
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: jaeger-ui
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: jaeger-ui
+  client:
+    meshTLS:
+      serviceAccounts:
+      # for the optional dashboard integration
+      - name: web
+        namespace: linkerd-viz
+{{ end -}}
diff --git a/jaeger/charts/linkerd-jaeger/templates/tracing.yaml b/jaeger/charts/linkerd-jaeger/templates/tracing.yaml
index 4b479fd60..285fc4e03 100644
--- a/jaeger/charts/linkerd-jaeger/templates/tracing.yaml
+++ b/jaeger/charts/linkerd-jaeger/templates/tracing.yaml
@@ -9,6 +9,7 @@ metadata:
   name: collector-config
   namespace: {{.Values.namespace}}
   labels:
+    linkerd.io/extension: jaeger
     component: collector
 data:
   collector-config: |
@@ -20,6 +21,7 @@ metadata:
   name: collector
   namespace: {{.Values.namespace}}
   labels:
+    linkerd.io/extension: jaeger
     component: collector
 spec:
   type: ClusterIP
@@ -51,6 +53,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
+    linkerd.io/extension: jaeger
     app.kubernetes.io/name: collector
     app.kubernetes.io/part-of: Linkerd
     component: collector
@@ -70,6 +73,7 @@ spec:
         prometheus.io/port: "8888"
         prometheus.io/scrape: "true"
       labels:
+        linkerd.io/extension: jaeger
         component: collector
     spec:
       {{- if .Values.collector.tolerations -}}
@@ -96,6 +100,7 @@ spec:
             port: 13133
         name: ot-collector
         ports:
+        - containerPort: 13133
         - containerPort: 4317
         - containerPort: 55678
         - containerPort: 9411
@@ -132,6 +137,7 @@ metadata:
   name: jaeger
   namespace: {{.Values.namespace}}
   labels:
+    linkerd.io/extension: jaeger
     component: jaeger
 spec:
   type: ClusterIP
@@ -149,6 +155,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
+    linkerd.io/extension: jaeger
     app.kubernetes.io/name: jaeger
     app.kubernetes.io/part-of: Linkerd
     component: jaeger
@@ -167,6 +174,7 @@ spec:
         prometheus.io/port: "14269"
         prometheus.io/scrape: "true"
       labels:
+        linkerd.io/extension: jaeger
         component: jaeger
     spec:
       {{- if .Values.jaeger.tolerations -}}
diff --git a/jaeger/cmd/install.go b/jaeger/cmd/install.go
index 6fd228fe5..2a86464bd 100644
--- a/jaeger/cmd/install.go
+++ b/jaeger/cmd/install.go
@@ -25,10 +25,13 @@ import (
 var (
 	templatesJaeger = []string{
 		"templates/namespace.yaml",
+		"templates/proxy-admin-policy.yaml",
 		"templates/jaeger-injector.yaml",
+		"templates/jaeger-injector-policy.yaml",
 		"templates/rbac.yaml",
 		"templates/psp.yaml",
 		"templates/tracing.yaml",
+		"templates/tracing-policy.yaml",
 	}
 )
 
diff --git a/multicluster/charts/linkerd-multicluster-link/templates/service-mirror-policy.yaml b/multicluster/charts/linkerd-multicluster-link/templates/service-mirror-policy.yaml
new file mode 100644
index 000000000..6bdb1ccfe
--- /dev/null
+++ b/multicluster/charts/linkerd-multicluster-link/templates/service-mirror-policy.yaml
@@ -0,0 +1,34 @@
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: service-mirror
+  labels:
+    linkerd.io/control-plane-component: linkerd-service-mirror
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/control-plane-component: linkerd-service-mirror
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: service-mirror
+  labels:
+    linkerd.io/control-plane-component: linkerd-service-mirror
+spec:
+  server:
+    name: service-mirror
+  client:
+    # In order to use `linkerd mc gateways` you need viz' Prometheus instance
+    # to be able to reach the service-mirror. In order to also have a separate
+    # Prometheus scrape the service-mirror an additional ServerAuthorization
+    # resource should be created.
+    meshTLS:
+      serviceAccounts:
+      - name: prometheus
+        namespace: linkerd-viz
diff --git a/multicluster/charts/linkerd-multicluster-link/templates/service-mirror.yaml b/multicluster/charts/linkerd-multicluster-link/templates/service-mirror.yaml
index 31a2ad9e8..375d8763c 100644
--- a/multicluster/charts/linkerd-multicluster-link/templates/service-mirror.yaml
+++ b/multicluster/charts/linkerd-multicluster-link/templates/service-mirror.yaml
@@ -4,6 +4,7 @@ apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   name: linkerd-service-mirror-access-local-resources-{{.Values.targetClusterName}}
   labels:
+    linkerd.io/extension: multicluster
     linkerd.io/control-plane-component: service-mirror
     mirror.linkerd.io/cluster-name: {{.Values.targetClusterName}}
 rules:
@@ -19,6 +20,7 @@ apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   name: linkerd-service-mirror-access-local-resources-{{.Values.targetClusterName}}
   labels:
+    linkerd.io/extension: multicluster
     linkerd.io/control-plane-component: service-mirror
     mirror.linkerd.io/cluster-name: {{.Values.targetClusterName}}
 roleRef:
@@ -36,6 +38,7 @@ metadata:
   name: linkerd-service-mirror-read-remote-creds-{{.Values.targetClusterName}}
   namespace: {{.Values.namespace}}
   labels:
+      linkerd.io/extension: multicluster
       linkerd.io/control-plane-component: service-mirror
       mirror.linkerd.io/cluster-name: {{.Values.targetClusterName}}
 rules:
@@ -53,6 +56,7 @@ metadata:
   name: linkerd-service-mirror-read-remote-creds-{{.Values.targetClusterName}}
   namespace: {{.Values.namespace}}
   labels:
+      linkerd.io/extension: multicluster
       linkerd.io/control-plane-component: service-mirror
       mirror.linkerd.io/cluster-name: {{.Values.targetClusterName}}
 roleRef:
@@ -70,6 +74,7 @@ metadata:
   name: linkerd-service-mirror-{{.Values.targetClusterName}}
   namespace: {{.Values.namespace}}
   labels:
+    linkerd.io/extension: multicluster
     linkerd.io/control-plane-component: service-mirror
     mirror.linkerd.io/cluster-name: {{.Values.targetClusterName}}
 ---
@@ -77,6 +82,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
+    linkerd.io/extension: multicluster
     linkerd.io/control-plane-component: service-mirror
     mirror.linkerd.io/cluster-name: {{.Values.targetClusterName}}
   name: linkerd-service-mirror-{{.Values.targetClusterName}}
@@ -85,6 +91,7 @@ spec:
   replicas: 1
   selector:
     matchLabels:
+      linkerd.io/extension: multicluster
       linkerd.io/control-plane-component: linkerd-service-mirror
       mirror.linkerd.io/cluster-name: {{.Values.targetClusterName}}
   template:
@@ -92,6 +99,7 @@ spec:
       annotations:
         linkerd.io/inject: enabled
       labels:
+        linkerd.io/extension: multicluster
         linkerd.io/control-plane-component: linkerd-service-mirror
         mirror.linkerd.io/cluster-name: {{.Values.targetClusterName}}
     spec:
diff --git a/multicluster/charts/linkerd-multicluster/templates/gateway-policy.yaml b/multicluster/charts/linkerd-multicluster/templates/gateway-policy.yaml
new file mode 100644
index 000000000..e8e53b4d7
--- /dev/null
+++ b/multicluster/charts/linkerd-multicluster/templates/gateway-policy.yaml
@@ -0,0 +1,66 @@
+{{if .Values.gateway.enabled -}}
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: linkerd-gateway
+  labels:
+    linkerd.io/extension: multicluster
+    app: {{.Values.gateway.name}}
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      app: {{.Values.gateway.name}}
+  port: linkerd-proxy
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: linkerd-gateway
+  labels:
+    linkerd.io/extension: multicluster
+    app: {{.Values.gateway.name}}
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: linkerd-gateway
+  client:
+    meshTLS:
+      identities:
+      - '*'
+    networks:
+    # Change this to the source cluster cidrs pointing to this gateway.
+    # Note that the source IP in some providers (e.g. GKE) will be the local
+    # node's IP and not the source cluster's
+    - cidr: 0.0.0.0/0
+    - cidr: ::/0
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: linkerd-gateway-probe
+  labels:
+    linkerd.io/extension: multicluster
+    app: {{.Values.gateway.name}}
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # allows probes from outside the cluster, as long as they have an identity
+    meshTLS:
+      identities:
+      - '*'
+    networks:
+    # cf note for linkerd-gateway ServerAuthorization
+    - cidr: 0.0.0.0/0
+    - cidr: ::/0
+{{end -}}
diff --git a/multicluster/charts/linkerd-multicluster/templates/gateway.yaml b/multicluster/charts/linkerd-multicluster/templates/gateway.yaml
index 6b3bcc6e2..e4e5d93e9 100644
--- a/multicluster/charts/linkerd-multicluster/templates/gateway.yaml
+++ b/multicluster/charts/linkerd-multicluster/templates/gateway.yaml
@@ -18,6 +18,7 @@ spec:
   replicas: 1
   selector:
     matchLabels:
+      linkerd.io/extension: multicluster
       app: {{.Values.gateway.name}}
   template:
     metadata:
@@ -27,6 +28,7 @@ spec:
         config.linkerd.io/proxy-require-identity-inbound-ports: "{{.Values.gateway.port}}"
         config.linkerd.io/enable-gateway: "true"
       labels:
+        linkerd.io/extension: multicluster
         app: {{.Values.gateway.name}}
     spec:
       containers:
diff --git a/multicluster/charts/linkerd-multicluster/templates/proxy-admin-policy.yaml b/multicluster/charts/linkerd-multicluster/templates/proxy-admin-policy.yaml
new file mode 100644
index 000000000..889349c0e
--- /dev/null
+++ b/multicluster/charts/linkerd-multicluster/templates/proxy-admin-policy.yaml
@@ -0,0 +1,33 @@
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: multicluster
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: multicluster
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: multicluster
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
diff --git a/multicluster/cmd/install.go b/multicluster/cmd/install.go
index 2c6520391..e2fe1ffc6 100644
--- a/multicluster/cmd/install.go
+++ b/multicluster/cmd/install.go
@@ -85,6 +85,8 @@ A full list of configurable values can be found at https://github.com/linkerd/li
 				{Name: chartutil.ChartfileName},
 				{Name: "templates/namespace.yaml"},
 				{Name: "templates/gateway.yaml"},
+				{Name: "templates/proxy-admin-policy.yaml"},
+				{Name: "templates/gateway-policy.yaml"},
 				{Name: "templates/psp.yaml"},
 				{Name: "templates/remote-access-service-mirror-rbac.yaml"},
 				{Name: "templates/link-crd.yaml"},
diff --git a/multicluster/cmd/link.go b/multicluster/cmd/link.go
index 6c472e39e..6dcd5009b 100644
--- a/multicluster/cmd/link.go
+++ b/multicluster/cmd/link.go
@@ -259,6 +259,7 @@ A full list of configurable values can be found at https://github.com/linkerd/li
 			files := []*chartloader.BufferedFile{
 				{Name: chartutil.ChartfileName},
 				{Name: "templates/service-mirror.yaml"},
+				{Name: "templates/service-mirror-policy.yaml"},
 				{Name: "templates/psp.yaml"},
 				{Name: "templates/gateway-mirror.yaml"},
 			}
diff --git a/pkg/healthcheck/healthcheck.go b/pkg/healthcheck/healthcheck.go
index d6ffaa5ee..fb81d9d67 100644
--- a/pkg/healthcheck/healthcheck.go
+++ b/pkg/healthcheck/healthcheck.go
@@ -2355,7 +2355,7 @@ func checkPodPorts(service *corev1.Service, pod *corev1.Pod, podPorts []string,
 						if util.ContainsString(strPort, podPorts) {
 							return nil
 						}
-						return fmt.Errorf("service %s expects %d to be opaque; add it to pod %s's %s annotation", service.Name, port, pod.Name, k8s.ProxyOpaquePortsAnnotation)
+						return fmt.Errorf("service %s expects target port %s to be opaque; add it to pod %s %s annotation", service.Name, strPort, pod.Name, k8s.ProxyOpaquePortsAnnotation)
 					}
 				}
 			}
diff --git a/policy-controller/src/admission.rs b/policy-controller/src/admission.rs
index a35296267..2731eca8a 100644
--- a/policy-controller/src/admission.rs
+++ b/policy-controller/src/admission.rs
@@ -1,5 +1,6 @@
 use crate::api;
 use anyhow::{anyhow, bail, Result};
+use api::policy::ServerSpec;
 use kube::{api::Api, core::DynamicObject, ResourceExt};
 use std::convert::{Infallible, TryInto};
 use tracing::{debug, info, warn};
@@ -26,7 +27,7 @@ pub fn routes(client: kube::Client) -> BoxedFilter<(impl warp::Reply,)> {
 
             // Parse the server instance under review before doing anything with the API--i.e., if
             // this fails we don't have to waste the API calls.
-            let (ns, review_server) = match parse_server(req) {
+            let (ns, name, review_spec) = match parse_server(req) {
                 Ok(s) => s,
                 Err(error) => {
                     warn!(%error, "Failed to deserialize server from admission request");
@@ -48,10 +49,10 @@ pub fn routes(client: kube::Client) -> BoxedFilter<(impl warp::Reply,)> {
             };
 
             // If validation fails, deny admission.
-            let rsp = match validate(&review_server, &*servers.items) {
+            let rsp = match validate(&name, &review_spec, &*servers.items) {
                 Ok(()) => rsp,
                 Err(error) => {
-                    info!(%error, %ns, name = %review_server.name(), "Denying server");
+                    info!(%error, %ns, %name, "Denying server");
                     rsp.deny(error)
                 }
             };
@@ -72,27 +73,37 @@ fn ok(reply: impl warp::Reply + 'static) -> Result<Box<dyn warp::Reply>, Infalli
 }
 
 /// Parses a `Server` instance and it's namespace from the admission request.
-fn parse_server(req: Request) -> Result<(String, api::policy::Server)> {
+fn parse_server(req: Request) -> Result<(String, String, api::policy::ServerSpec)> {
     let obj = req.object.ok_or_else(|| anyhow!("missing server"))?;
-    let server = serde_json::from_value::<api::policy::Server>(obj.data)?;
-    let ns = server
+    let ns = obj
         .namespace()
         .ok_or_else(|| anyhow!("no 'namespace' field set on server"))?;
-    Ok((ns, server))
+    let name = obj.name();
+    let data = obj
+        .data
+        .get("spec")
+        .cloned()
+        .ok_or_else(|| anyhow!("no 'spec' field set on server"))?;
+    let spec = serde_json::from_value::<ServerSpec>(data)?;
+    Ok((ns, name, spec))
 }
 
 /// Validates a new server (`review`) against existing `servers`.
-fn validate(review: &api::policy::Server, servers: &[api::policy::Server]) -> Result<()> {
+fn validate(
+    review_name: &str,
+    review_spec: &api::policy::ServerSpec,
+    servers: &[api::policy::Server],
+) -> Result<()> {
     for s in servers {
         // If the port and pod selectors select the same resources, fail the admission of the
         // server. Ignore existing instances of this Server (e.g., if the server's metadata is
         // changing).
-        if s.name() != review.name()
+        if s.name() != review_name
             // TODO(ver) this isn't rigorous about detecting servers that select the same port if one port
             // specifies a numeric port and the other specifies the port's name.
-            && s.spec.port == review.spec.port
+            && s.spec.port == review_spec.port
             // TODO(ver) We can probably detect overlapping selectors more effectively.
-            && s.spec.pod_selector == review.spec.pod_selector
+            && s.spec.pod_selector == review_spec.pod_selector
         {
             bail!("identical server spec already exists");
         }
diff --git a/viz/charts/linkerd-viz/templates/admin-policy.yaml b/viz/charts/linkerd-viz/templates/admin-policy.yaml
new file mode 100644
index 000000000..d361224d0
--- /dev/null
+++ b/viz/charts/linkerd-viz/templates/admin-policy.yaml
@@ -0,0 +1,33 @@
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: admin
+  client:
+    # for kubelet probes and prometheus scraping
+    unauthenticated: true
+
diff --git a/viz/charts/linkerd-viz/templates/grafana-policy.yaml b/viz/charts/linkerd-viz/templates/grafana-policy.yaml
new file mode 100644
index 000000000..2282f2514
--- /dev/null
+++ b/viz/charts/linkerd-viz/templates/grafana-policy.yaml
@@ -0,0 +1,37 @@
+{{ if .Values.grafana.enabled -}}
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: grafana
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: grafana
+  client:
+    # web, prometheus and the kubelet probes
+    unauthenticated: true
+{{ end -}}
diff --git a/viz/charts/linkerd-viz/templates/metrics-api-policy.yaml b/viz/charts/linkerd-viz/templates/metrics-api-policy.yaml
new file mode 100644
index 000000000..ebbf4f949
--- /dev/null
+++ b/viz/charts/linkerd-viz/templates/metrics-api-policy.yaml
@@ -0,0 +1,37 @@
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: metrics-api
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: metrics-api
+  client:
+    meshTLS:
+      serviceAccounts:
+      - name: web
+      - name: prometheus
diff --git a/viz/charts/linkerd-viz/templates/proxy-admin-policy.yaml b/viz/charts/linkerd-viz/templates/proxy-admin-policy.yaml
new file mode 100644
index 000000000..54831784f
--- /dev/null
+++ b/viz/charts/linkerd-viz/templates/proxy-admin-policy.yaml
@@ -0,0 +1,33 @@
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
diff --git a/viz/charts/linkerd-viz/templates/tap-injector-policy.yaml b/viz/charts/linkerd-viz/templates/tap-injector-policy.yaml
new file mode 100644
index 000000000..4f7d8c0e5
--- /dev/null
+++ b/viz/charts/linkerd-viz/templates/tap-injector-policy.yaml
@@ -0,0 +1,35 @@
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: tap-injector-webhook
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap-injector
+  port: tap-injector
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: tap-injector
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: tap-injector-webhook
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
diff --git a/viz/charts/linkerd-viz/templates/tap-policy.yaml b/viz/charts/linkerd-viz/templates/tap-policy.yaml
new file mode 100644
index 000000000..f897c8fa2
--- /dev/null
+++ b/viz/charts/linkerd-viz/templates/tap-policy.yaml
@@ -0,0 +1,35 @@
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: tap-api
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap
+  port: apiserver
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: tap
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    {{ include "partials.annotations.created-by" . }}
+spec:
+  server:
+    name: tap-api
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
diff --git a/viz/cmd/install.go b/viz/cmd/install.go
index ea67f9f0f..a1f62cb03 100644
--- a/viz/cmd/install.go
+++ b/viz/cmd/install.go
@@ -29,12 +29,18 @@ var (
 		"templates/tap-rbac.yaml",
 		"templates/web-rbac.yaml",
 		"templates/psp.yaml",
+		"templates/admin-policy.yaml",
+		"templates/proxy-admin-policy.yaml",
 		"templates/metrics-api.yaml",
+		"templates/metrics-api-policy.yaml",
 		"templates/grafana.yaml",
+		"templates/grafana-policy.yaml",
 		"templates/prometheus.yaml",
 		"templates/tap.yaml",
+		"templates/tap-policy.yaml",
 		"templates/tap-injector-rbac.yaml",
 		"templates/tap-injector.yaml",
+		"templates/tap-injector-policy.yaml",
 		"templates/web.yaml",
 		"templates/service-profiles.yaml",
 	}


Test patch:
diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml
index 8f0051fb1..2c31ef659 100644
--- a/.github/workflows/integration_tests.yml
+++ b/.github/workflows/integration_tests.yml
@@ -60,7 +60,10 @@ jobs:
         - uninstall
         - upgrade-edge
         - upgrade-stable
-        - cni-calico-deep
+          # temporarily disabled; 
+          # image used in manifests for calico-operator
+          # does not exist in image repository yet
+          #- cni-calico-deep
     needs: [docker_build]
     name: Integration tests (${{ matrix.integration_test }})
     runs-on: ubuntu-20.04
diff --git a/cli/cmd/testdata/install_controlplane_tracing_output.golden b/cli/cmd/testdata/install_controlplane_tracing_output.golden
index 30a1def3d..b0e9e13b6 100644
--- a/cli/cmd/testdata/install_controlplane_tracing_output.golden
+++ b/cli/cmd/testdata/install_controlplane_tracing_output.golden
@@ -1573,7 +1573,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_custom_domain.golden b/cli/cmd/testdata/install_custom_domain.golden
index d4a285c94..15e9dc507 100644
--- a/cli/cmd/testdata/install_custom_domain.golden
+++ b/cli/cmd/testdata/install_custom_domain.golden
@@ -1572,7 +1572,6 @@ metadata:
     linkerd.io/control-plane-ns: l5d
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_custom_registry.golden b/cli/cmd/testdata/install_custom_registry.golden
index f7aa36d5f..f887cfbc2 100644
--- a/cli/cmd/testdata/install_custom_registry.golden
+++ b/cli/cmd/testdata/install_custom_registry.golden
@@ -1572,7 +1572,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_default.golden b/cli/cmd/testdata/install_default.golden
index 5641d24e0..0bdebdde0 100644
--- a/cli/cmd/testdata/install_default.golden
+++ b/cli/cmd/testdata/install_default.golden
@@ -1572,7 +1572,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_default_override_dst_get_nets.golden b/cli/cmd/testdata/install_default_override_dst_get_nets.golden
index 508f866e5..b06979d36 100644
--- a/cli/cmd/testdata/install_default_override_dst_get_nets.golden
+++ b/cli/cmd/testdata/install_default_override_dst_get_nets.golden
@@ -1572,7 +1572,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_ha_output.golden b/cli/cmd/testdata/install_ha_output.golden
index 89b34708c..e32c6c3f1 100644
--- a/cli/cmd/testdata/install_ha_output.golden
+++ b/cli/cmd/testdata/install_ha_output.golden
@@ -1646,7 +1646,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_ha_with_overrides_output.golden b/cli/cmd/testdata/install_ha_with_overrides_output.golden
index f5be412f0..ed0bb1334 100644
--- a/cli/cmd/testdata/install_ha_with_overrides_output.golden
+++ b/cli/cmd/testdata/install_ha_with_overrides_output.golden
@@ -1646,7 +1646,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_heartbeat_disabled_output.golden b/cli/cmd/testdata/install_heartbeat_disabled_output.golden
index 5605e36eb..a35fe149c 100644
--- a/cli/cmd/testdata/install_heartbeat_disabled_output.golden
+++ b/cli/cmd/testdata/install_heartbeat_disabled_output.golden
@@ -1503,7 +1503,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_helm_output.golden b/cli/cmd/testdata/install_helm_output.golden
index 620775bf9..043d6d916 100644
--- a/cli/cmd/testdata/install_helm_output.golden
+++ b/cli/cmd/testdata/install_helm_output.golden
@@ -1565,7 +1565,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/helm linkerd-version
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_helm_output_ha.golden b/cli/cmd/testdata/install_helm_output_ha.golden
index 703df8a5b..710ada695 100644
--- a/cli/cmd/testdata/install_helm_output_ha.golden
+++ b/cli/cmd/testdata/install_helm_output_ha.golden
@@ -1639,7 +1639,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/helm linkerd-version
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_helm_output_ha_labels.golden b/cli/cmd/testdata/install_helm_output_ha_labels.golden
index 8b3439ad0..621d92ece 100644
--- a/cli/cmd/testdata/install_helm_output_ha_labels.golden
+++ b/cli/cmd/testdata/install_helm_output_ha_labels.golden
@@ -1647,7 +1647,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/helm linkerd-version
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden b/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden
index c1bcccdb6..7d9648994 100644
--- a/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden
+++ b/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden
@@ -1639,7 +1639,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/helm linkerd-version
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_no_init_container.golden b/cli/cmd/testdata/install_no_init_container.golden
index eafd18773..9af4d5a31 100644
--- a/cli/cmd/testdata/install_no_init_container.golden
+++ b/cli/cmd/testdata/install_no_init_container.golden
@@ -1534,7 +1534,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_output.golden b/cli/cmd/testdata/install_output.golden
index 3e975c2b1..b1d212420 100644
--- a/cli/cmd/testdata/install_output.golden
+++ b/cli/cmd/testdata/install_output.golden
@@ -1574,7 +1574,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: CliVersion
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_proxy_ignores.golden b/cli/cmd/testdata/install_proxy_ignores.golden
index 224497843..f68db4694 100644
--- a/cli/cmd/testdata/install_proxy_ignores.golden
+++ b/cli/cmd/testdata/install_proxy_ignores.golden
@@ -1572,7 +1572,6 @@ metadata:
     linkerd.io/control-plane-ns: linkerd
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/cli/cmd/testdata/install_values_file.golden b/cli/cmd/testdata/install_values_file.golden
index bf4de1edf..74b80aa0c 100644
--- a/cli/cmd/testdata/install_values_file.golden
+++ b/cli/cmd/testdata/install_values_file.golden
@@ -1558,7 +1558,6 @@ metadata:
     linkerd.io/control-plane-ns: l5d
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
-    config.linkerd.io/opaque-ports: "443"
 spec:
   type: ClusterIP
   selector:
diff --git a/jaeger/cmd/testdata/install_collector_disabled.golden b/jaeger/cmd/testdata/install_collector_disabled.golden
index 8ee21f00c..6f0d37e57 100644
--- a/jaeger/cmd/testdata/install_collector_disabled.golden
+++ b/jaeger/cmd/testdata/install_collector_disabled.golden
@@ -9,6 +9,39 @@ metadata:
     linkerd.io/inject: enabled
     config.linkerd.io/proxy-await: "enabled"
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
+---
 ###
 ### Jaeger Injector
 ###
@@ -90,6 +123,62 @@ spec:
     port: 443
     targetPort: jaeger-injector
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-injector-webhook
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+      component: jaeger-injector
+  port: jaeger-injector
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-injector-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+      component: jaeger-injector
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-injector
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    selector:
+      matchLabels:
+        linkerd.io/extension: jaeger
+        component: jaeger-injector
+  client:
+    # traffic coming from the kubelet and from kube-api
+    unauthenticated: true
+---
 ###
 ### Jaeger Injector RBAC
 ###
@@ -178,6 +267,7 @@ metadata:
   name: jaeger
   namespace: linkerd-jaeger
   labels:
+    linkerd.io/extension: jaeger
     component: jaeger
 spec:
   type: ClusterIP
@@ -195,6 +285,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
+    linkerd.io/extension: jaeger
     app.kubernetes.io/name: jaeger
     app.kubernetes.io/part-of: Linkerd
     component: jaeger
@@ -213,6 +304,7 @@ spec:
         prometheus.io/port: "14269"
         prometheus.io/scrape: "true"
       labels:
+        linkerd.io/extension: jaeger
         component: jaeger
     spec:
       nodeSelector:
@@ -234,3 +326,112 @@ spec:
           name: ui
       dnsPolicy: ClusterFirst
       serviceAccountName: jaeger
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-grpc
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: jaeger
+  port: grpc
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-grpc
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: jaeger-grpc
+  client:
+    meshTLS:
+      serviceAccounts:
+      - name: collector
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: jaeger
+  port: admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: jaeger-admin
+  client:
+    meshTLS:
+      serviceAccounts:
+      # if not using linkerd-viz' prometheus, replace its SA here
+      - name: prometheus
+        namespace: linkerd-viz
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-ui
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: jaeger
+  port: ui
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-ui
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: jaeger-ui
+  client:
+    meshTLS:
+      serviceAccounts:
+      # for the optional dashboard integration
+      - name: web
+        namespace: linkerd-viz
diff --git a/jaeger/cmd/testdata/install_default.golden b/jaeger/cmd/testdata/install_default.golden
index a3c178878..ea28c7e33 100644
--- a/jaeger/cmd/testdata/install_default.golden
+++ b/jaeger/cmd/testdata/install_default.golden
@@ -9,6 +9,39 @@ metadata:
     linkerd.io/inject: enabled
     config.linkerd.io/proxy-await: "enabled"
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
+---
 ###
 ### Jaeger Injector
 ###
@@ -90,6 +123,62 @@ spec:
     port: 443
     targetPort: jaeger-injector
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-injector-webhook
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+      component: jaeger-injector
+  port: jaeger-injector
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-injector-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+      component: jaeger-injector
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-injector
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    selector:
+      matchLabels:
+        linkerd.io/extension: jaeger
+        component: jaeger-injector
+  client:
+    # traffic coming from the kubelet and from kube-api
+    unauthenticated: true
+---
 ###
 ### collector RBAC
 ###
@@ -187,6 +276,7 @@ metadata:
   name: collector-config
   namespace: linkerd-jaeger
   labels:
+    linkerd.io/extension: jaeger
     component: collector
 data:
   collector-config: |
@@ -225,6 +315,7 @@ metadata:
   name: collector
   namespace: linkerd-jaeger
   labels:
+    linkerd.io/extension: jaeger
     component: collector
 spec:
   type: ClusterIP
@@ -256,6 +347,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
+    linkerd.io/extension: jaeger
     app.kubernetes.io/name: collector
     app.kubernetes.io/part-of: Linkerd
     component: collector
@@ -275,6 +367,7 @@ spec:
         prometheus.io/port: "8888"
         prometheus.io/scrape: "true"
       labels:
+        linkerd.io/extension: jaeger
         component: collector
     spec:
       nodeSelector:
@@ -299,6 +392,7 @@ spec:
             port: 13133
         name: ot-collector
         ports:
+        - containerPort: 13133
         - containerPort: 4317
         - containerPort: 55678
         - containerPort: 9411
@@ -330,6 +424,7 @@ metadata:
   name: jaeger
   namespace: linkerd-jaeger
   labels:
+    linkerd.io/extension: jaeger
     component: jaeger
 spec:
   type: ClusterIP
@@ -347,6 +442,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
+    linkerd.io/extension: jaeger
     app.kubernetes.io/name: jaeger
     app.kubernetes.io/part-of: Linkerd
     component: jaeger
@@ -365,6 +461,7 @@ spec:
         prometheus.io/port: "14269"
         prometheus.io/scrape: "true"
       labels:
+        linkerd.io/extension: jaeger
         component: jaeger
     spec:
       nodeSelector:
@@ -386,3 +483,231 @@ spec:
           name: ui
       dnsPolicy: ClusterFirst
       serviceAccountName: jaeger
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-otlp
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 4317
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-opencensus
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 55678
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-zipkin
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 9411
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-jaeger-thrift
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 14268
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-jaeger-grpc
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 14250
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 13133
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: collector
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    selector:
+      matchLabels:
+        linkerd.io/extension: jaeger
+        component: collector
+  client:
+    # allow connections from any pod (meshed or not) sending trace data
+    unauthenticated: true
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-grpc
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: jaeger
+  port: grpc
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-grpc
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: jaeger-grpc
+  client:
+    meshTLS:
+      serviceAccounts:
+      - name: collector
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: jaeger
+  port: admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: jaeger-admin
+  client:
+    meshTLS:
+      serviceAccounts:
+      # if not using linkerd-viz' prometheus, replace its SA here
+      - name: prometheus
+        namespace: linkerd-viz
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-ui
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: jaeger
+  port: ui
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-ui
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: jaeger-ui
+  client:
+    meshTLS:
+      serviceAccounts:
+      # for the optional dashboard integration
+      - name: web
+        namespace: linkerd-viz
diff --git a/jaeger/cmd/testdata/install_jaeger_disabled.golden b/jaeger/cmd/testdata/install_jaeger_disabled.golden
index 922ef38ea..29df97d17 100644
--- a/jaeger/cmd/testdata/install_jaeger_disabled.golden
+++ b/jaeger/cmd/testdata/install_jaeger_disabled.golden
@@ -9,6 +9,39 @@ metadata:
     linkerd.io/inject: enabled
     config.linkerd.io/proxy-await: "enabled"
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: jaeger
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
+---
 ###
 ### Jaeger Injector
 ###
@@ -90,6 +123,62 @@ spec:
     port: 443
     targetPort: jaeger-injector
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-injector-webhook
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+      component: jaeger-injector
+  port: jaeger-injector
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-injector-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: jaeger
+      component: jaeger-injector
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: jaeger-injector
+  labels:
+    linkerd.io/extension: jaeger
+    component: jaeger-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    selector:
+      matchLabels:
+        linkerd.io/extension: jaeger
+        component: jaeger-injector
+  client:
+    # traffic coming from the kubelet and from kube-api
+    unauthenticated: true
+---
 ###
 ### collector RBAC
 ###
@@ -178,6 +267,7 @@ metadata:
   name: collector-config
   namespace: linkerd-jaeger
   labels:
+    linkerd.io/extension: jaeger
     component: collector
 data:
   collector-config: |
@@ -216,6 +306,7 @@ metadata:
   name: collector
   namespace: linkerd-jaeger
   labels:
+    linkerd.io/extension: jaeger
     component: collector
 spec:
   type: ClusterIP
@@ -247,6 +338,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
+    linkerd.io/extension: jaeger
     app.kubernetes.io/name: collector
     app.kubernetes.io/part-of: Linkerd
     component: collector
@@ -266,6 +358,7 @@ spec:
         prometheus.io/port: "8888"
         prometheus.io/scrape: "true"
       labels:
+        linkerd.io/extension: jaeger
         component: collector
     spec:
       nodeSelector:
@@ -290,6 +383,7 @@ spec:
             port: 13133
         name: ot-collector
         ports:
+        - containerPort: 13133
         - containerPort: 4317
         - containerPort: 55678
         - containerPort: 9411
@@ -311,3 +405,122 @@ spec:
             path: collector-config.yaml
           name: collector-config
         name: collector-config-val
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-otlp
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 4317
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-opencensus
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 55678
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-zipkin
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 9411
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-jaeger-thrift
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 14268
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-jaeger-grpc
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 14250
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-jaeger
+  name: collector-admin
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      component: collector
+  port: 13133
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-jaeger
+  name: collector
+  labels:
+    linkerd.io/extension: jaeger
+    component: collector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    selector:
+      matchLabels:
+        linkerd.io/extension: jaeger
+        component: collector
+  client:
+    # allow connections from any pod (meshed or not) sending trace data
+    unauthenticated: true
diff --git a/pkg/healthcheck/healthcheck_test.go b/pkg/healthcheck/healthcheck_test.go
index 936df5139..f63acd032 100644
--- a/pkg/healthcheck/healthcheck_test.go
+++ b/pkg/healthcheck/healthcheck_test.go
@@ -3418,7 +3418,7 @@ subsets:
     protocol: TCP
 `,
 			},
-			expected: fmt.Errorf("\t* service svc expects 9200 to be opaque; add it to pod pod's config.linkerd.io/opaque-ports annotation"),
+			expected: fmt.Errorf("\t* service svc expects target port 9200 to be opaque; add it to pod pod config.linkerd.io/opaque-ports annotation"),
 		},
 		{
 			resources: []string{`
diff --git a/test/integration/localhost/localhost_test.go b/test/integration/localhost/localhost_test.go
index 780729dc8..e870805e6 100644
--- a/test/integration/localhost/localhost_test.go
+++ b/test/integration/localhost/localhost_test.go
@@ -86,14 +86,13 @@ func TestLocalhostServer(t *testing.T) {
 				return fmt.Errorf("expected non-zero RPS from slowcooker to nginx: %s", out)
 			}
 
-			// TODO: Update this test to expect these requests to fail once
-			// https://github.com/linkerd/linkerd2/issues/6495 is fixed.  Requests
-			// sent to a port which is only bound to localhost should fail.
-			if *stats[0].Success != 1.0 {
-				return fmt.Errorf("expected perfect success-rate from slowcooker to nginx: %s", out)
+			// Requests sent to a port which is only bound to localhost should
+			// fail.
+			if *stats[0].Success >= 1.0 {
+				return fmt.Errorf("expected zero success-rate from slowcooker to nginx: %s", out)
 			}
-			if *stats[0].TCPOpenConnections == 0 {
-				return fmt.Errorf("expected tcp connection from slowcooker to nginx: %s", out)
+			if *stats[0].TCPOpenConnections > 0 {
+				return fmt.Errorf("expected no tcp connection from slowcooker to nginx: %s", out)
 			}
 
 			return nil
diff --git a/test/integration/policy/policy_test.go b/test/integration/policy/policy_test.go
new file mode 100644
index 000000000..72d3e0b85
--- /dev/null
+++ b/test/integration/policy/policy_test.go
@@ -0,0 +1,244 @@
+package policy
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/linkerd/linkerd2/testutil"
+)
+
+var TestHelper *testutil.TestHelper
+
+func TestMain(m *testing.M) {
+	TestHelper = testutil.NewTestHelper()
+	os.Exit(m.Run())
+}
+
+//////////////////////
+/// TEST EXECUTION ///
+//////////////////////
+
+func TestPolicy(t *testing.T) {
+	ctx := context.Background()
+
+	// Test authorization stats
+	TestHelper.WithDataPlaneNamespace(ctx, "stat-authz-test", map[string]string{}, t, func(t *testing.T, prefixedNs string) {
+		emojivotoYaml, err := testutil.ReadFile("testdata/emojivoto.yaml")
+		if err != nil {
+			testutil.AnnotatedFatalf(t, "failed to read emojivoto yaml",
+				"failed to read emojivoto yaml\n%s\n", err)
+		}
+		emojivotoYaml = strings.ReplaceAll(emojivotoYaml, "___NS___", prefixedNs)
+		out, stderr, err := TestHelper.PipeToLinkerdRun(emojivotoYaml, "inject", "-")
+		if err != nil {
+			testutil.AnnotatedFatalf(t, "'linkerd inject' command failed",
+				"'linkerd inject' command failed\n%s\n%s", out, stderr)
+		}
+
+		out, err = TestHelper.KubectlApply(out, prefixedNs)
+		if err != nil {
+			testutil.AnnotatedFatalf(t, "failed to apply emojivoto resources",
+				"failed to apply emojivoto resources: %s\n %s", err, out)
+		}
+
+		emojivotoPolicy, err := testutil.ReadFile("testdata/emoji-policy.yaml")
+		if err != nil {
+			testutil.AnnotatedFatalf(t, "failed to read emoji-policy yaml",
+				"failed to read emoji-policy yaml\n%s\n", err)
+		}
+
+		out, err = TestHelper.KubectlApply(emojivotoPolicy, prefixedNs)
+		if err != nil {
+			testutil.AnnotatedFatalf(t, "failed to apply emojivoto policy resources",
+				"failed to apply emojivoto policy resources: %s\n %s", err, out)
+		}
+
+		// wait for deployments to start
+		for _, deploy := range []string{"web", "emoji", "vote-bot", "voting"} {
+			if err := TestHelper.CheckPods(ctx, prefixedNs, deploy, 1); err != nil {
+				if rce, ok := err.(*testutil.RestartCountError); ok {
+					testutil.AnnotatedWarn(t, "CheckPods timed-out", rce)
+				} else {
+					testutil.AnnotatedError(t, "CheckPods timed-out", err)
+				}
+			}
+		}
+
+		testCases := []struct {
+			args         []string
+			expectedRows []string
+			isServer     bool
+		}{
+			{
+				args: []string{"viz", "stat", "srv", "-n", prefixedNs},
+				expectedRows: []string{
+					"emoji-grpc",
+					"voting-grpc",
+					"web-http",
+				},
+				isServer: true,
+			},
+			{
+				args: []string{"viz", "stat", "srv/emoji-grpc", "-n", prefixedNs},
+				expectedRows: []string{
+					"emoji-grpc",
+				},
+				isServer: true,
+			},
+			{
+				args: []string{"viz", "stat", "saz", "-n", prefixedNs},
+				expectedRows: []string{
+					"emoji-grpc",
+					"voting-grpc",
+					"web-public",
+				},
+				isServer: false,
+			},
+			{
+				args: []string{"viz", "stat", "saz/emoji-grpc", "-n", prefixedNs},
+				expectedRows: []string{
+					"emoji-grpc",
+				},
+				isServer: false,
+			},
+		}
+
+		for _, tt := range testCases {
+			tt := tt // pin
+			timeout := 3 * time.Minute
+			t.Run("linkerd "+strings.Join(tt.args, " "), func(t *testing.T) {
+				err := TestHelper.RetryFor(timeout, func() error {
+					// Use a short time window so that transient errors at startup
+					// fall out of the window.
+					tt.args = append(tt.args, "-t", "30s")
+					out, err := TestHelper.LinkerdRun(tt.args...)
+					if err != nil {
+						testutil.AnnotatedFatalf(t, "unexpected stat error",
+							"unexpected stat error: %s\n%s", err, out)
+					}
+
+					var expectedColumnCount int
+					if tt.isServer {
+						expectedColumnCount = 8
+					} else {
+						expectedColumnCount = 6
+					}
+
+					rowStats, err := ParseAuthzRows(out, len(tt.expectedRows), expectedColumnCount, tt.isServer)
+					if err != nil {
+						return err
+					}
+
+					for _, name := range tt.expectedRows {
+						if err := validateAuthzRows(name, rowStats, tt.isServer); err != nil {
+							return err
+						}
+					}
+
+					return nil
+				})
+				if err != nil {
+					testutil.AnnotatedFatal(t, fmt.Sprintf("timed-out checking stats (%s)", timeout), err)
+				}
+			})
+		}
+	})
+}
+
+func validateAuthzRows(name string, rowStats map[string]*testutil.RowStat, isServer bool) error {
+	stat, ok := rowStats[name]
+	if !ok {
+		return fmt.Errorf("No stats found for [%s]", name)
+	}
+
+	// Check for suffix only, as the value will not be 100% always with
+	// the normal emojivoto sample
+	if !strings.HasSuffix(stat.Success, "%") {
+		return fmt.Errorf("Unexpected success rate for [%s], got [%s]",
+			name, stat.Success)
+	}
+
+	if isServer {
+		if !strings.HasSuffix(stat.UnauthorizedRPS, "rps") {
+			return fmt.Errorf("Unexpected Unauthorized RPS for [%s], got [%s]",
+				name, stat.UnauthorizedRPS)
+		}
+	}
+
+	if !strings.HasSuffix(stat.Rps, "rps") {
+		return fmt.Errorf("Unexpected rps for [%s], got [%s]",
+			name, stat.Rps)
+	}
+
+	if !strings.HasSuffix(stat.P50Latency, "ms") {
+		return fmt.Errorf("Unexpected p50 latency for [%s], got [%s]",
+			name, stat.P50Latency)
+	}
+
+	if !strings.HasSuffix(stat.P95Latency, "ms") {
+		return fmt.Errorf("Unexpected p95 latency for [%s], got [%s]",
+			name, stat.P95Latency)
+	}
+
+	if !strings.HasSuffix(stat.P99Latency, "ms") {
+		return fmt.Errorf("Unexpected p99 latency for [%s], got [%s]",
+			name, stat.P99Latency)
+	}
+
+	if isServer {
+		_, err := strconv.Atoi(stat.TCPOpenConnections)
+		if err != nil {
+			return fmt.Errorf("Error parsing number of TCP connections [%s]: %s", stat.TCPOpenConnections, err.Error())
+		}
+	}
+
+	return nil
+}
+
+// ParseRows parses the output of linkerd stat on a policy resource
+func ParseAuthzRows(out string, expectedRowCount, expectedColumnCount int, isServer bool) (map[string]*testutil.RowStat, error) {
+	rows, err := testutil.CheckRowCount(out, expectedRowCount)
+	if err != nil {
+		return nil, err
+	}
+
+	rowStats := make(map[string]*testutil.RowStat)
+	for _, row := range rows {
+		fields := strings.Fields(row)
+
+		if len(fields) != expectedColumnCount {
+			return nil, fmt.Errorf(
+				"Expected [%d] columns in stat output, got [%d]; full output:\n%s",
+				expectedColumnCount, len(fields), row)
+		}
+
+		i := 0
+		rowStats[fields[0]] = &testutil.RowStat{
+			Name: fields[0],
+		}
+
+		if isServer {
+			rowStats[fields[0]].UnauthorizedRPS = fields[1+i]
+			rowStats[fields[0]].Success = fields[2+i]
+			rowStats[fields[0]].Rps = fields[3+i]
+			rowStats[fields[0]].P50Latency = fields[4+i]
+			rowStats[fields[0]].P95Latency = fields[5+i]
+			rowStats[fields[0]].P99Latency = fields[6+i]
+			rowStats[fields[0]].TCPOpenConnections = fields[7+i]
+		} else {
+			rowStats[fields[0]].Success = fields[1+i]
+			rowStats[fields[0]].Rps = fields[2+i]
+			rowStats[fields[0]].P50Latency = fields[3+i]
+			rowStats[fields[0]].P95Latency = fields[4+i]
+			rowStats[fields[0]].P99Latency = fields[5+i]
+		}
+
+	}
+
+	return rowStats, nil
+}
diff --git a/test/integration/policy/testdata/emoji-policy.yaml b/test/integration/policy/testdata/emoji-policy.yaml
new file mode 100644
index 000000000..a7ef577f1
--- /dev/null
+++ b/test/integration/policy/testdata/emoji-policy.yaml
@@ -0,0 +1,97 @@
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  name: emoji-grpc
+  labels:
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/name: emoji
+    app.kubernetes.io/version: v11
+spec:
+  podSelector:
+    matchLabels:
+      app: emoji-svc
+  port: grpc
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  name: emoji-grpc
+  labels:
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/name: emoji
+    app.kubernetes.io/version: v11
+spec:
+  # Allow all authenticated clients to access the (read-only) emoji service.
+  server:
+    name: emoji-grpc
+  client:
+    meshTLS:
+      identities:
+        - "*.linkerd-stat-authz-test.serviceaccount.identity.linkerd.cluster.local"
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  name: voting-grpc
+  labels:
+    app: voting-svc
+spec:
+  podSelector:
+    matchLabels:
+      app: voting-svc
+  port: grpc
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  name: voting-grpc
+  labels:
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/name: voting
+    app.kubernetes.io/version: v11
+spec:
+  server:
+    name: voting-grpc
+  # The voting service only allows requests from the web service.
+  client:
+    meshTLS:
+      serviceAccounts:
+        - name: web
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  name: web-http
+  labels:
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/name: web
+    app.kubernetes.io/version: v11
+spec:
+  podSelector:
+    matchLabels:
+      app: web-svc
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  name: web-public
+  labels:
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/name: web
+    app.kubernetes.io/version: v11
+spec:
+  server:
+    name: web-http
+  # Allow all clients to access the web HTTP port without regard for
+  # authentication. If unauthenticated connections are permitted, there is no
+  # need to describe authenticated clients.
+  client:
+    unauthenticated: true
+    networks:
+      - cidr: 0.0.0.0/0
+      - cidr: ::/0
diff --git a/test/integration/policy/testdata/emojivoto.yaml b/test/integration/policy/testdata/emojivoto.yaml
new file mode 100644
index 000000000..2a05e0132
--- /dev/null
+++ b/test/integration/policy/testdata/emojivoto.yaml
@@ -0,0 +1,205 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: emoji
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: voting
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: web
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: emoji-svc
+spec:
+  ports:
+  - name: grpc
+    port: 8080
+    targetPort: 8080
+  - name: prom
+    port: 8801
+    targetPort: 8801
+  selector:
+    app: emoji-svc
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: voting-svc
+spec:
+  ports:
+  - name: grpc
+    port: 8080
+    targetPort: 8080
+  - name: prom
+    port: 8801
+    targetPort: 8801
+  selector:
+    app: voting-svc
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: web-svc
+spec:
+  ports:
+  - name: http
+    port: 80
+    targetPort: 8080
+  selector:
+    app: web-svc
+  type: ClusterIP
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    app.kubernetes.io/name: emoji
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/version: v11
+  name: emoji
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: emoji-svc
+      version: v11
+  template:
+    metadata:
+      labels:
+        app: emoji-svc
+        version: v11
+    spec:
+      containers:
+      - env:
+        - name: GRPC_PORT
+          value: "8080"
+        - name: PROM_PORT
+          value: "8801"
+        image: docker.l5d.io/buoyantio/emojivoto-emoji-svc:v11
+        name: emoji-svc
+        ports:
+        - containerPort: 8080
+          name: grpc
+        - containerPort: 8801
+          name: prom
+        resources:
+          requests:
+            cpu: 100m
+      serviceAccountName: emoji
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    app.kubernetes.io/name: vote-bot
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/version: v11
+  name: vote-bot
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: vote-bot
+      version: v11
+  template:
+    metadata:
+      labels:
+        app: vote-bot
+        version: v11
+    spec:
+      containers:
+      - command:
+        - emojivoto-vote-bot
+        env:
+        - name: WEB_HOST
+          value: web-svc.___NS___:80
+        image: docker.l5d.io/buoyantio/emojivoto-web:v11
+        name: vote-bot
+        resources:
+          requests:
+            cpu: 10m
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    app.kubernetes.io/name: voting
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/version: v11
+  name: voting
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: voting-svc
+      version: v11
+  template:
+    metadata:
+      labels:
+        app: voting-svc
+        version: v11
+    spec:
+      containers:
+      - env:
+        - name: GRPC_PORT
+          value: "8080"
+        - name: PROM_PORT
+          value: "8801"
+        image: docker.l5d.io/buoyantio/emojivoto-voting-svc:v11
+        name: voting-svc
+        ports:
+        - containerPort: 8080
+          name: grpc
+        - containerPort: 8801
+          name: prom
+        resources:
+          requests:
+            cpu: 100m
+      serviceAccountName: voting
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    app.kubernetes.io/name: web
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/version: v11
+  name: web
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: web-svc
+      version: v11
+  template:
+    metadata:
+      labels:
+        app: web-svc
+        version: v11
+    spec:
+      containers:
+      - env:
+        - name: WEB_PORT
+          value: "8080"
+        - name: EMOJISVC_HOST
+          value: emoji-svc.___NS___:8080
+        - name: VOTINGSVC_HOST
+          value: voting-svc.___NS___:8080
+        - name: INDEX_BUNDLE
+          value: dist/index_bundle.js
+        image: docker.l5d.io/buoyantio/emojivoto-web:v11
+        name: web-svc
+        ports:
+        - containerPort: 8080
+          name: http
+        resources:
+          requests:
+            cpu: 100m
+      serviceAccountName: web
diff --git a/test/integration/testdata/inject.report.golden b/test/integration/testdata/inject.report.golden
index c7c5928fd..d1b4570b5 100644
--- a/test/integration/testdata/inject.report.golden
+++ b/test/integration/testdata/inject.report.golden
@@ -1,6 +1,10 @@
 
 deployment "smoke-test-terminus" injected
 service "smoke-test-terminus-svc" skipped
+server "smoke-test-terminus" skipped
+serverauthorization "smoke-test-terminus" skipped
 deployment "smoke-test-gateway" injected
 service "smoke-test-gateway-svc" skipped
+server "smoke-test-proxy-admin" skipped
+serverauthorization "smoke-test-proxy-admin" skipped
 
diff --git a/test/integration/testdata/smoke_test.yaml b/test/integration/testdata/smoke_test.yaml
index fd9e1d9ea..14bce1adc 100644
--- a/test/integration/testdata/smoke_test.yaml
+++ b/test/integration/testdata/smoke_test.yaml
@@ -32,6 +32,34 @@ spec:
     port: 9090
     targetPort: 9090
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  name: smoke-test-terminus
+spec:
+  podSelector:
+    matchLabels:
+      app: smoke-test-terminus
+  port: 9090
+  proxyProtocol: gRPC
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  name: smoke-test-terminus
+spec:
+  server:
+    name: smoke-test-terminus
+  client:
+    meshTLS:
+      serviceAccounts:
+      - name: default
+        namespace: linkerd-smoke-test
+      - name: default
+        namespace: linkerd-smoke-test-manual
+      - name: default
+        namespace: linkerd-smoke-test-ann
+---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
@@ -64,3 +92,29 @@ spec:
   - name: http
     port: 8080
     targetPort: 8080
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  name: smoke-test-proxy-admin
+spec:
+  podSelector:
+    matchExpressions:
+    - key: app
+      operator: In
+      values:
+      - smoke-test-terminus
+      - smoke-test-gateway
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  name: smoke-test-proxy-admin
+spec:
+  server:
+    name: smoke-test-proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
diff --git a/testutil/test_helper.go b/testutil/test_helper.go
index dea3c19c4..771ba536b 100644
--- a/testutil/test_helper.go
+++ b/testutil/test_helper.go
@@ -672,6 +672,7 @@ type RowStat struct {
 	P95Latency         string
 	P99Latency         string
 	TCPOpenConnections string
+	UnauthorizedRPS    string
 }
 
 // CheckRowCount checks that expectedRowCount rows have been returned
diff --git a/viz/cmd/testdata/install_default.golden b/viz/cmd/testdata/install_default.golden
index 3c83fe4ad..c07ee6a2b 100644
--- a/viz/cmd/testdata/install_default.golden
+++ b/viz/cmd/testdata/install_default.golden
@@ -392,6 +392,72 @@ metadata:
     component: web
     namespace: linkerd-viz
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: admin
+  client:
+    # for kubelet probes and prometheus scraping
+    unauthenticated: true
+
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
+---
 ###
 ### Metrics API
 ###
@@ -474,6 +540,43 @@ spec:
           runAsUser: 2103
       serviceAccountName: metrics-api
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: metrics-api
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: metrics-api
+  client:
+    meshTLS:
+      serviceAccounts:
+      - name: web
+      - name: prometheus
+---
 ###
 ### Grafana
 ###
@@ -631,6 +734,41 @@ spec:
           name: grafana-config
         name: grafana-config
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: grafana
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: grafana
+  client:
+    # web, prometheus and the kubelet probes
+    unauthenticated: true
+---
 ###
 ### Prometheus
 ###
@@ -977,6 +1115,41 @@ spec:
         secret:
           secretName: tap-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-api
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap
+  port: apiserver
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-api
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Tap Injector RBAC
 ###
@@ -1137,6 +1310,41 @@ spec:
         secret:
           secretName: tap-injector-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector-webhook
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap-injector
+  port: tap-injector
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-injector-webhook
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Web
 ###
diff --git a/viz/cmd/testdata/install_default_overrides.golden b/viz/cmd/testdata/install_default_overrides.golden
index 82abf79ab..cf73caa2c 100644
--- a/viz/cmd/testdata/install_default_overrides.golden
+++ b/viz/cmd/testdata/install_default_overrides.golden
@@ -392,6 +392,72 @@ metadata:
     component: web
     namespace: linkerd-viz
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: admin
+  client:
+    # for kubelet probes and prometheus scraping
+    unauthenticated: true
+
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
+---
 ###
 ### Metrics API
 ###
@@ -474,6 +540,43 @@ spec:
           runAsUser: 1234
       serviceAccountName: metrics-api
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: metrics-api
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: metrics-api
+  client:
+    meshTLS:
+      serviceAccounts:
+      - name: web
+      - name: prometheus
+---
 ###
 ### Grafana
 ###
@@ -631,6 +734,41 @@ spec:
           name: grafana-config
         name: grafana-config
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: grafana
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: grafana
+  client:
+    # web, prometheus and the kubelet probes
+    unauthenticated: true
+---
 ###
 ### Prometheus
 ###
@@ -977,6 +1115,41 @@ spec:
         secret:
           secretName: tap-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-api
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap
+  port: apiserver
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-api
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Tap Injector RBAC
 ###
@@ -1137,6 +1310,41 @@ spec:
         secret:
           secretName: tap-injector-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector-webhook
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap-injector
+  port: tap-injector
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-injector-webhook
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Web
 ###
diff --git a/viz/cmd/testdata/install_grafana_disabled.golden b/viz/cmd/testdata/install_grafana_disabled.golden
index da80d2534..102b91a5b 100644
--- a/viz/cmd/testdata/install_grafana_disabled.golden
+++ b/viz/cmd/testdata/install_grafana_disabled.golden
@@ -379,6 +379,72 @@ metadata:
     component: web
     namespace: linkerd-viz
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: admin
+  client:
+    # for kubelet probes and prometheus scraping
+    unauthenticated: true
+
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
+---
 ###
 ### Metrics API
 ###
@@ -461,6 +527,43 @@ spec:
           runAsUser: 2103
       serviceAccountName: metrics-api
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: metrics-api
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: metrics-api
+  client:
+    meshTLS:
+      serviceAccounts:
+      - name: web
+      - name: prometheus
+---
 ###
 ### Prometheus
 ###
@@ -798,6 +901,41 @@ spec:
         secret:
           secretName: tap-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-api
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap
+  port: apiserver
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-api
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Tap Injector RBAC
 ###
@@ -958,6 +1096,41 @@ spec:
         secret:
           secretName: tap-injector-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector-webhook
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap-injector
+  port: tap-injector
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-injector-webhook
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Web
 ###
diff --git a/viz/cmd/testdata/install_prometheus_disabled.golden b/viz/cmd/testdata/install_prometheus_disabled.golden
index 14d1242b4..094f3bff4 100644
--- a/viz/cmd/testdata/install_prometheus_disabled.golden
+++ b/viz/cmd/testdata/install_prometheus_disabled.golden
@@ -352,6 +352,72 @@ metadata:
     component: web
     namespace: linkerd-viz
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: admin
+  client:
+    # for kubelet probes and prometheus scraping
+    unauthenticated: true
+
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
+---
 ###
 ### Metrics API
 ###
@@ -434,6 +500,43 @@ spec:
           runAsUser: 2103
       serviceAccountName: metrics-api
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: metrics-api
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: metrics-api
+  client:
+    meshTLS:
+      serviceAccounts:
+      - name: web
+      - name: prometheus
+---
 ###
 ### Grafana
 ###
@@ -591,6 +694,41 @@ spec:
           name: grafana-config
         name: grafana-config
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: grafana
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: grafana
+  client:
+    # web, prometheus and the kubelet probes
+    unauthenticated: true
+---
 ###
 ### Tap
 ###
@@ -690,6 +828,41 @@ spec:
         secret:
           secretName: tap-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-api
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap
+  port: apiserver
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-api
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Tap Injector RBAC
 ###
@@ -850,6 +1023,41 @@ spec:
         secret:
           secretName: tap-injector-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector-webhook
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap-injector
+  port: tap-injector
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-injector-webhook
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Web
 ###
diff --git a/viz/cmd/testdata/install_prometheus_loglevel_from_args.golden b/viz/cmd/testdata/install_prometheus_loglevel_from_args.golden
index 63b9c4ed8..f5f693ce5 100644
--- a/viz/cmd/testdata/install_prometheus_loglevel_from_args.golden
+++ b/viz/cmd/testdata/install_prometheus_loglevel_from_args.golden
@@ -392,6 +392,72 @@ metadata:
     component: web
     namespace: linkerd-viz
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: admin
+  client:
+    # for kubelet probes and prometheus scraping
+    unauthenticated: true
+
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
+---
 ###
 ### Metrics API
 ###
@@ -474,6 +540,43 @@ spec:
           runAsUser: 2103
       serviceAccountName: metrics-api
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: metrics-api
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: metrics-api
+  client:
+    meshTLS:
+      serviceAccounts:
+      - name: web
+      - name: prometheus
+---
 ###
 ### Grafana
 ###
@@ -631,6 +734,41 @@ spec:
           name: grafana-config
         name: grafana-config
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: grafana
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: grafana
+  client:
+    # web, prometheus and the kubelet probes
+    unauthenticated: true
+---
 ###
 ### Prometheus
 ###
@@ -977,6 +1115,41 @@ spec:
         secret:
           secretName: tap-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-api
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap
+  port: apiserver
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-api
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Tap Injector RBAC
 ###
@@ -1137,6 +1310,41 @@ spec:
         secret:
           secretName: tap-injector-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector-webhook
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap-injector
+  port: tap-injector
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-injector-webhook
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Web
 ###
diff --git a/viz/cmd/testdata/install_proxy_resources.golden b/viz/cmd/testdata/install_proxy_resources.golden
index 2270cf83e..d6de02232 100644
--- a/viz/cmd/testdata/install_proxy_resources.golden
+++ b/viz/cmd/testdata/install_proxy_resources.golden
@@ -392,6 +392,72 @@ metadata:
     component: web
     namespace: linkerd-viz
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: admin-http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: admin
+  client:
+    # for kubelet probes and prometheus scraping
+    unauthenticated: true
+
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: proxy-admin
+  labels:
+    linkerd.io/extension: viz
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
+---
 ###
 ### Metrics API
 ###
@@ -474,6 +540,43 @@ spec:
           runAsUser: 2103
       serviceAccountName: metrics-api
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: metrics-api
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: metrics-api
+  labels:
+    linkerd.io/extension: viz
+    component: metrics-api
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: metrics-api
+  client:
+    meshTLS:
+      serviceAccounts:
+      - name: web
+      - name: prometheus
+---
 ###
 ### Grafana
 ###
@@ -635,6 +738,41 @@ spec:
           name: grafana-config
         name: grafana-config
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: grafana
+  port: http
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: grafana
+  labels:
+    linkerd.io/extension: viz
+    component: grafana
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: grafana
+  client:
+    # web, prometheus and the kubelet probes
+    unauthenticated: true
+---
 ###
 ### Prometheus
 ###
@@ -989,6 +1127,41 @@ spec:
         secret:
           secretName: tap-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-api
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap
+  port: apiserver
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap
+  labels:
+    linkerd.io/extension: viz
+    component: tap
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-api
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Tap Injector RBAC
 ###
@@ -1149,6 +1322,41 @@ spec:
         secret:
           secretName: tap-injector-k8s-tls
 ---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: Server
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector-webhook
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/extension: viz
+      component: tap-injector
+  port: tap-injector
+  proxyProtocol: TLS
+---
+apiVersion: policy.linkerd.io/v1alpha1
+kind: ServerAuthorization
+metadata:
+  namespace: linkerd-viz
+  name: tap-injector
+  labels:
+    linkerd.io/extension: viz
+    component: tap-injector
+  annotations:
+    linkerd.io/created-by: linkerd/helm dev-undefined
+spec:
+  server:
+    name: tap-injector-webhook
+  client:
+    # traffic coming from kube-api
+    unauthenticated: true
+---
 ###
 ### Web
 ###