Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package linkerd-cli-edge for 
openSUSE:Factory checked in at 2026-03-06 18:20:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/linkerd-cli-edge (Old)
 and      /work/SRC/openSUSE:Factory/.linkerd-cli-edge.new.561 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "linkerd-cli-edge"

Fri Mar  6 18:20:43 2026 rev:67 rq:1337296 version:26.3.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/linkerd-cli-edge/linkerd-cli-edge.changes        
2026-02-18 17:13:18.149390459 +0100
+++ 
/work/SRC/openSUSE:Factory/.linkerd-cli-edge.new.561/linkerd-cli-edge.changes   
    2026-03-06 18:21:46.800092714 +0100
@@ -1,0 +2,60 @@
+Fri Mar 06 06:15:23 UTC 2026 - Johannes Kastl 
<[email protected]>
+
+- Update to version 26.3.1:
+  * build(deps): bump linkerd-validator from 0.1.6 to 0.1.7
+    (#15000)
+  * build(deps): bump quote from 1.0.42 to 1.0.45 (#14993)
+  * build(deps): bump syn from 2.0.114 to 2.0.117 (#14994)
+  * build(deps): bump ipnet from 2.11.0 to 2.12.0 (#14995)
+  * build(deps): bump tokio-macros from 2.6.0 to 2.6.1 (#14996)
+  * build(deps): bump docker/login-action from 3.7.0 to 4.0.0
+    (#14997)
+  * build(deps): bump docker/setup-qemu-action (#14998)
+  * build(deps): bump tokio from 1.49.0 to 1.50.0 (#14987)
+  * build(deps): bump itoa from 1.0.15 to 1.0.17 (#14988)
+  * build(deps): bump zmij from 1.0.17 to 1.0.21 (#14989)
+  * build(deps): bump iana-time-zone from 0.1.64 to 0.1.65 (#14990)
+  * build(deps): bump github.com/go-openapi/spec from 0.22.3 to
+    0.22.4 (#14979)
+  * build(deps): bump axum-core from 0.5.5 to 0.5.6 (#14980)
+  * build(deps): bump tonic-prost from 0.14.2 to 0.14.5 (#14982)
+  * build(deps): bump security-framework-sys from 2.15.0 to 2.17.0
+    (#14983)
+  * build(deps): bump tj-actions/changed-files from 47.0.4 to
+    47.0.5 (#14984)
+  * build(deps): bump crazy-max/ghaction-github-runtime (#14985)
+  * build(deps): bump github.com/mattn/go-runewidth from 0.0.19 to
+    0.0.20 (#14942)
+  * build(deps): bump actions/setup-go from 6.2.0 to 6.3.0 (#14963)
+  * build(deps-dev): bump css-loader from 7.1.3 to 7.1.4 in
+    /web/app (#14951)
+  * build(deps): bump extractions/setup-just from 3.0.0 to 3.1.0
+    (#14952)
+  * build(deps): bump the kube group with 7 updates (#14978)
+  * build(deps-dev): bump webpack from 5.105.2 to 5.105.3 in
+    /web/app (#14976)
+  * build(deps): bump actions/download-artifact (#14972)
+  * build(deps): bump actions/download-artifact from 7.0.0 to 8.0.0
+    (#14971)
+  * build(deps): bump actions/upload-artifact from 6.0.0 to 7.0.0
+    (#14970)
+  * build(deps): bump axum from 0.8.7 to 0.8.8 (#14969)
+  * build(deps): bump bumpalo from 3.19.0 to 3.20.2 (#14968)
+  * build(deps): bump tower from 0.5.2 to 0.5.3 (#14967)
+  * build(deps): bump regex-automata from 0.4.13 to 0.4.14 (#14966)
+  * chore(deps): upgrade linkerd-await (#14950)
+  * chore(deps): bump rand from 0.9.2 to 0.10.0 (#14965)
+  * build(deps): bump log from 0.4.28 to 0.4.29 (#14962)
+  * build(deps): bump regex-syntax from 0.8.8 to 0.8.10 (#14961)
+  * build(deps): bump aws-lc-rs from 1.15.0 to 1.16.0 (#14960)
+  * build(deps): bump tower-http from 0.6.6 to 0.6.8 (#14958)
+  * build(deps): bump tonic from 0.14.4 to 0.14.5 in the grpc group
+    (#14956)
+  * build(deps): bump the clap group with 2 updates (#14955)
+  * build(deps): bump the clap group with 2 updates (#14943)
+  * build(deps): bump tokio from 1.48.0 to 1.49.0 (#14946)
+  * build(deps): bump rustls-pki-types from 1.13.1 to 1.14.0
+    (#14945)
+  * build(deps): bump hyper-util from 0.1.17 to 0.1.20 (#14944)
+
+-------------------------------------------------------------------

Old:
----
  linkerd-cli-edge-26.2.1.obscpio

New:
----
  linkerd-cli-edge-26.3.1.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ linkerd-cli-edge.spec ++++++
--- /var/tmp/diff_new_pack.KVpgLa/_old  2026-03-06 18:21:48.332156656 +0100
+++ /var/tmp/diff_new_pack.KVpgLa/_new  2026-03-06 18:21:48.340156989 +0100
@@ -19,7 +19,7 @@
 %define linkerd_executable_name linkerd
 
 Name:           linkerd-cli-edge
-Version:        26.2.1
+Version:        26.3.1
 Release:        0
 Summary:        CLI for the linkerd service mesh for Kubernetes
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.KVpgLa/_old  2026-03-06 18:21:48.440161163 +0100
+++ /var/tmp/diff_new_pack.KVpgLa/_new  2026-03-06 18:21:48.452161664 +0100
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/linkerd/linkerd2</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">edge-26.2.1</param>
+    <param name="revision">edge-26.3.1</param>
     <param name="match-tag">edge-*.*.*</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">edge-(.*)</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.KVpgLa/_old  2026-03-06 18:21:48.472162499 +0100
+++ /var/tmp/diff_new_pack.KVpgLa/_new  2026-03-06 18:21:48.492163333 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/linkerd/linkerd2</param>
-              <param 
name="changesrevision">b5621f5c07d8ae36cb7393923dda871e90ece588</param></service></servicedata>
+              <param 
name="changesrevision">2534d7d3702ecedd134149a156afd20e7efdf049</param></service></servicedata>
 (No newline at EOF)
 

++++++ linkerd-cli-edge-26.2.1.obscpio -> linkerd-cli-edge-26.3.1.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/.proxy-version 
new/linkerd-cli-edge-26.3.1/.proxy-version
--- old/linkerd-cli-edge-26.2.1/.proxy-version  2026-02-17 20:17:36.000000000 
+0100
+++ new/linkerd-cli-edge-26.3.1/.proxy-version  2026-03-06 00:57:02.000000000 
+0100
@@ -1 +1 @@
-v2.338.0
+v2.341.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/Cargo.lock 
new/linkerd-cli-edge-26.3.1/Cargo.lock
--- old/linkerd-cli-edge-26.2.1/Cargo.lock      2026-02-17 20:17:36.000000000 
+0100
+++ new/linkerd-cli-edge-26.3.1/Cargo.lock      2026-03-06 00:57:02.000000000 
+0100
@@ -110,9 +110,9 @@
 
 [[package]]
 name = "aws-lc-rs"
-version = "1.15.0"
+version = "1.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5932a7d9d28b0d2ea34c6b3779d35e3dd6f6345317c34e73438c4f1f29144151"
+checksum = "d9a7b350e3bb1767102698302bc37256cbd48422809984b98d292c40e2579aa9"
 dependencies = [
  "aws-lc-sys",
  "zeroize",
@@ -120,11 +120,10 @@
 
 [[package]]
 name = "aws-lc-sys"
-version = "0.33.0"
+version = "0.37.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "1826f2e4cfc2cd19ee53c42fbf68e2f81ec21108e0b7ecf6a71cf062137360fc"
+checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549"
 dependencies = [
- "bindgen",
  "cc",
  "cmake",
  "dunce",
@@ -133,9 +132,9 @@
 
 [[package]]
 name = "axum"
-version = "0.8.7"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5b098575ebe77cb6d14fc7f32749631a6e44edbef6b796f89b020e99ba20d425"
+checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8"
 dependencies = [
  "axum-core",
  "bytes",
@@ -158,9 +157,9 @@
 
 [[package]]
 name = "axum-core"
-version = "0.5.5"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22"
+checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
 dependencies = [
  "bytes",
  "futures-core",
@@ -192,26 +191,6 @@
 checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
 
 [[package]]
-name = "bindgen"
-version = "0.72.1"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
-dependencies = [
- "bitflags",
- "cexpr",
- "clang-sys",
- "itertools 0.13.0",
- "log",
- "prettyplease",
- "proc-macro2",
- "quote",
- "regex",
- "rustc-hash",
- "shlex",
- "syn",
-]
-
-[[package]]
 name = "bitflags"
 version = "2.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -228,9 +207,9 @@
 
 [[package]]
 name = "bumpalo"
-version = "3.19.0"
+version = "3.20.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
+checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
 
 [[package]]
 name = "bytes"
@@ -251,21 +230,23 @@
 ]
 
 [[package]]
-name = "cexpr"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
-dependencies = [
- "nom",
-]
-
-[[package]]
 name = "cfg-if"
 version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
 
 [[package]]
+name = "chacha20"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
+dependencies = [
+ "cfg-if",
+ "cpufeatures 0.3.0",
+ "rand_core 0.10.0",
+]
+
+[[package]]
 name = "chrono"
 version = "0.4.43"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -278,21 +259,10 @@
 ]
 
 [[package]]
-name = "clang-sys"
-version = "1.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
-dependencies = [
- "glob",
- "libc",
- "libloading",
-]
-
-[[package]]
 name = "clap"
-version = "4.5.58"
+version = "4.5.60"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "63be97961acde393029492ce0be7a1af7e323e6bae9511ebfac33751be5e6806"
+checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -300,9 +270,9 @@
 
 [[package]]
 name = "clap_builder"
-version = "4.5.58"
+version = "4.5.60"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "7f13174bda5dfd69d7e947827e5af4b0f2f94a4a3ee92912fba07a66150f21e2"
+checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876"
 dependencies = [
  "anstyle",
  "clap_lex",
@@ -380,6 +350,15 @@
 ]
 
 [[package]]
+name = "cpufeatures"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
+dependencies = [
+ "libc",
+]
+
+[[package]]
 name = "crossbeam-utils"
 version = "0.8.21"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -556,7 +535,7 @@
 checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
 dependencies = [
  "libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.61.0",
 ]
 
 [[package]]
@@ -761,10 +740,18 @@
 ]
 
 [[package]]
-name = "glob"
-version = "0.3.3"
+name = "getrandom"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
+checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "rand_core 0.10.0",
+ "wasip2",
+ "wasip3",
+]
 
 [[package]]
 name = "gloo-timers"
@@ -992,13 +979,12 @@
 
 [[package]]
 name = "hyper-util"
-version = "0.1.17"
+version = "0.1.20"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8"
+checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
 dependencies = [
  "bytes",
  "futures-channel",
- "futures-core",
  "futures-util",
  "http",
  "http-body",
@@ -1013,9 +999,9 @@
 
 [[package]]
 name = "iana-time-zone"
-version = "0.1.64"
+version = "0.1.65"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
+checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
 dependencies = [
  "android_system_properties",
  "core-foundation-sys",
@@ -1036,6 +1022,12 @@
 ]
 
 [[package]]
+name = "id-arena"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
+
+[[package]]
 name = "ident_case"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1049,13 +1041,15 @@
 dependencies = [
  "equivalent",
  "hashbrown 0.16.1",
+ "serde",
+ "serde_core",
 ]
 
 [[package]]
 name = "ipnet"
-version = "2.11.0"
+version = "2.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
+checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
 dependencies = [
  "schemars",
  "serde",
@@ -1063,15 +1057,6 @@
 
 [[package]]
 name = "itertools"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
-dependencies = [
- "either",
-]
-
-[[package]]
-name = "itertools"
 version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
@@ -1081,9 +1066,9 @@
 
 [[package]]
 name = "itoa"
-version = "1.0.15"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
 
 [[package]]
 name = "jemalloc-sys"
@@ -1351,20 +1336,16 @@
 checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
-name = "libc"
-version = "0.2.180"
+name = "leb128fmt"
+version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
+checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
 
 [[package]]
-name = "libloading"
-version = "0.8.9"
+name = "libc"
+version = "0.2.180"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
-dependencies = [
- "cfg-if",
- "windows-link",
-]
+checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
 
 [[package]]
 name = "linkerd-policy-controller"
@@ -1527,7 +1508,7 @@
  "linkerd-policy-controller-k8s-api",
  "linkerd2-proxy-api",
  "maplit",
- "rand",
+ "rand 0.10.0",
  "regex",
  "schemars",
  "serde",
@@ -1572,9 +1553,9 @@
 
 [[package]]
 name = "log"
-version = "0.4.28"
+version = "0.4.29"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
+checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
 
 [[package]]
 name = "maplit"
@@ -1610,12 +1591,6 @@
 checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
 
 [[package]]
-name = "minimal-lexical"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
-
-[[package]]
 name = "mio"
 version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1627,16 +1602,6 @@
 ]
 
 [[package]]
-name = "nom"
-version = "7.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
-dependencies = [
- "memchr",
- "minimal-lexical",
-]
-
-[[package]]
 name = "nu-ansi-term"
 version = "0.50.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1929,7 +1894,7 @@
 checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
 dependencies = [
  "anyhow",
- "itertools 0.14.0",
+ "itertools",
  "proc-macro2",
  "quote",
  "syn",
@@ -1946,21 +1911,38 @@
 
 [[package]]
 name = "quote"
-version = "1.0.42"
+version = "1.0.45"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
 dependencies = [
  "proc-macro2",
 ]
 
 [[package]]
+name = "r-efi"
+version = "5.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
+
+[[package]]
 name = "rand"
 version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
 dependencies = [
  "rand_chacha",
- "rand_core",
+ "rand_core 0.9.3",
+]
+
+[[package]]
+name = "rand"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8"
+dependencies = [
+ "chacha20",
+ "getrandom 0.4.1",
+ "rand_core 0.10.0",
 ]
 
 [[package]]
@@ -1970,7 +1952,7 @@
 checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
 dependencies = [
  "ppv-lite86",
- "rand_core",
+ "rand_core 0.9.3",
 ]
 
 [[package]]
@@ -1983,6 +1965,12 @@
 ]
 
 [[package]]
+name = "rand_core"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
+
+[[package]]
 name = "redox_syscall"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -2005,9 +1993,9 @@
 
 [[package]]
 name = "regex-automata"
-version = "0.4.13"
+version = "0.4.14"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
+checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -2022,9 +2010,9 @@
 
 [[package]]
 name = "regex-syntax"
-version = "0.8.8"
+version = "0.8.10"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
+checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
 
 [[package]]
 name = "ring"
@@ -2041,12 +2029,6 @@
 ]
 
 [[package]]
-name = "rustc-hash"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
-
-[[package]]
 name = "rustc_version"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -2120,9 +2102,9 @@
 
 [[package]]
 name = "rustls-pki-types"
-version = "1.13.1"
+version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c"
+checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
 dependencies = [
  "zeroize",
 ]
@@ -2221,9 +2203,9 @@
 
 [[package]]
 name = "security-framework-sys"
-version = "2.15.0"
+version = "2.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
+checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3"
 dependencies = [
  "core-foundation-sys",
  "libc",
@@ -2319,7 +2301,7 @@
 checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
 dependencies = [
  "cfg-if",
- "cpufeatures",
+ "cpufeatures 0.2.17",
  "digest",
 ]
 
@@ -2330,7 +2312,7 @@
 checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
 dependencies = [
  "cfg-if",
- "cpufeatures",
+ "cpufeatures 0.2.17",
  "digest",
 ]
 
@@ -2395,9 +2377,9 @@
 
 [[package]]
 name = "syn"
-version = "2.0.114"
+version = "2.0.117"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
+checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2461,9 +2443,9 @@
 
 [[package]]
 name = "tokio"
-version = "1.48.0"
+version = "1.50.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
+checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
 dependencies = [
  "bytes",
  "libc",
@@ -2478,9 +2460,9 @@
 
 [[package]]
 name = "tokio-macros"
-version = "2.6.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
+checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2560,9 +2542,9 @@
 
 [[package]]
 name = "tonic"
-version = "0.14.4"
+version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "7f32a6f80051a4111560201420c7885d0082ba9efe2ab61875c587bb6b18b9a0"
+checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec"
 dependencies = [
  "async-trait",
  "axum",
@@ -2589,9 +2571,9 @@
 
 [[package]]
 name = "tonic-prost"
-version = "0.14.2"
+version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67"
+checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309"
 dependencies = [
  "bytes",
  "prost",
@@ -2600,9 +2582,9 @@
 
 [[package]]
 name = "tower"
-version = "0.5.2"
+version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
+checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
 dependencies = [
  "futures-core",
  "futures-util",
@@ -2619,9 +2601,9 @@
 
 [[package]]
 name = "tower-http"
-version = "0.6.6"
+version = "0.6.8"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
+checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
 dependencies = [
  "base64",
  "bitflags",
@@ -2739,7 +2721,7 @@
  "http",
  "httparse",
  "log",
- "rand",
+ "rand 0.9.2",
  "sha1",
  "thiserror 2.0.18",
  "utf-8",
@@ -2764,6 +2746,12 @@
 checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e"
 
 [[package]]
+name = "unicode-xid"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
+
+[[package]]
 name = "unsafe-libyaml"
 version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -2824,6 +2812,24 @@
 ]
 
 [[package]]
+name = "wasip2"
+version = "1.0.2+wasi-0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
+dependencies = [
+ "wit-bindgen",
+]
+
+[[package]]
+name = "wasip3"
+version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
+dependencies = [
+ "wit-bindgen",
+]
+
+[[package]]
 name = "wasm-bindgen"
 version = "0.2.92"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -2878,6 +2884,40 @@
 checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
 
 [[package]]
+name = "wasm-encoder"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
+dependencies = [
+ "leb128fmt",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasm-metadata"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
+dependencies = [
+ "anyhow",
+ "indexmap",
+ "wasm-encoder",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasmparser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
+dependencies = [
+ "bitflags",
+ "hashbrown 0.15.5",
+ "indexmap",
+ "semver",
+]
+
+[[package]]
 name = "windows-core"
 version = "0.62.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -3093,6 +3133,26 @@
 checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
 
 [[package]]
+name = "wit-bindgen"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
+dependencies = [
+ "wit-bindgen-rust-macro",
+]
+
+[[package]]
+name = "wit-bindgen-core"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
+dependencies = [
+ "anyhow",
+ "heck",
+ "wit-parser",
+]
+
+[[package]]
 name = "wit-bindgen-rt"
 version = "0.33.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -3102,6 +3162,74 @@
 ]
 
 [[package]]
+name = "wit-bindgen-rust"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
+dependencies = [
+ "anyhow",
+ "heck",
+ "indexmap",
+ "prettyplease",
+ "syn",
+ "wasm-metadata",
+ "wit-bindgen-core",
+ "wit-component",
+]
+
+[[package]]
+name = "wit-bindgen-rust-macro"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
+dependencies = [
+ "anyhow",
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wit-bindgen-core",
+ "wit-bindgen-rust",
+]
+
+[[package]]
+name = "wit-component"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
+dependencies = [
+ "anyhow",
+ "bitflags",
+ "indexmap",
+ "log",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "wasm-encoder",
+ "wasm-metadata",
+ "wasmparser",
+ "wit-parser",
+]
+
+[[package]]
+name = "wit-parser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
+dependencies = [
+ "anyhow",
+ "id-arena",
+ "indexmap",
+ "log",
+ "semver",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "unicode-xid",
+ "wasmparser",
+]
+
+[[package]]
 name = "zerocopy"
 version = "0.8.39"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -3129,6 +3257,6 @@
 
 [[package]]
 name = "zmij"
-version = "1.0.17"
+version = "1.0.21"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "02aae0f83f69aafc94776e879363e9771d7ecbffe2c7fbb6c14c5e00dfe88439"
+checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/Dockerfile.proxy 
new/linkerd-cli-edge-26.3.1/Dockerfile.proxy
--- old/linkerd-cli-edge-26.2.1/Dockerfile.proxy        2026-02-17 
20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/Dockerfile.proxy        2026-03-06 
00:57:02.000000000 +0100
@@ -26,9 +26,9 @@
     proxy=$(bin/fetch-proxy "$LINKERD2_PROXY_VERSION" "$TARGETARCH"); \
     mv "$proxy" linkerd2-proxy
 RUN echo "$LINKERD2_PROXY_VERSION" > proxy-version
-ARG LINKERD_AWAIT_VERSION=v0.3.1
+ARG LINKERD_AWAIT_VERSION=v0.3.2
 RUN bin/scurl -o linkerd-await 
https://github.com/linkerd/linkerd-await/releases/download/release%2F${LINKERD_AWAIT_VERSION}/linkerd-await-${LINKERD_AWAIT_VERSION}-${TARGETARCH}
 && chmod +x linkerd-await
-ARG LINKERD_VALIDATOR_VERSION=v0.1.6
+ARG LINKERD_VALIDATOR_VERSION=v0.1.7
 RUN bin/scurl -O 
https://github.com/linkerd/linkerd2-proxy-init/releases/download/validator%2F${LINKERD_VALIDATOR_VERSION}/linkerd-network-validator-${LINKERD_VALIDATOR_VERSION}-${TARGETARCH}-linux.tgz
 RUN tar -zxvf 
linkerd-network-validator-${LINKERD_VALIDATOR_VERSION}-${TARGETARCH}-linux.tgz 
&& mv 
linkerd-network-validator-${LINKERD_VALIDATOR_VERSION}-${TARGETARCH}-linux/linkerd-network-validator
 .
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/deny.toml 
new/linkerd-cli-edge-26.3.1/deny.toml
--- old/linkerd-cli-edge-26.2.1/deny.toml       2026-02-17 20:17:36.000000000 
+0100
+++ new/linkerd-cli-edge-26.3.1/deny.toml       2026-03-06 00:57:02.000000000 
+0100
@@ -59,6 +59,10 @@
     { name = "thiserror", version = "1" },
     # getrandom v0.3 is still making its way through the ecosystem
     { name = "getrandom", version = "0.2" },
+    # rand v0.10 is still making its way through the ecosystem. it uses a
+    # newer version of `cpufeatures` as well.
+    { name = "rand", version = "0.9" },
+    { name = "cpufeatures", version = "0.2" },
 ]
 
 [sources]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/go.mod 
new/linkerd-cli-edge-26.3.1/go.mod
--- old/linkerd-cli-edge-26.2.1/go.mod  2026-02-17 20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/go.mod  2026-03-06 00:57:02.000000000 +0100
@@ -13,7 +13,7 @@
        github.com/evanphx/json-patch v5.9.11+incompatible
        github.com/fatih/color v1.18.0
        github.com/fsnotify/fsnotify v1.9.0
-       github.com/go-openapi/spec v0.22.3
+       github.com/go-openapi/spec v0.22.4
        github.com/go-test/deep v1.1.1
        github.com/golang/protobuf v1.5.4
        github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674
@@ -22,7 +22,7 @@
        github.com/julienschmidt/httprouter v1.3.0
        github.com/linkerd/linkerd2-proxy-api v0.18.0
        github.com/mattn/go-isatty v0.0.20
-       github.com/mattn/go-runewidth v0.0.19
+       github.com/mattn/go-runewidth v0.0.20
        github.com/nsf/termbox-go v1.1.1
        github.com/patrickmn/go-cache v2.1.0+incompatible
        github.com/pkg/browser v0.0.0-20170505125900-c90ca0c84f15
@@ -41,14 +41,14 @@
        google.golang.org/protobuf v1.36.11
        gopkg.in/yaml.v2 v2.4.0
        helm.sh/helm/v3 v3.20.0
-       k8s.io/api v0.35.1
-       k8s.io/apiextensions-apiserver v0.35.1
-       k8s.io/apimachinery v0.35.1
-       k8s.io/client-go v0.35.1
-       k8s.io/code-generator v0.35.1
-       k8s.io/endpointslice v0.35.1
+       k8s.io/api v0.35.2
+       k8s.io/apiextensions-apiserver v0.35.2
+       k8s.io/apimachinery v0.35.2
+       k8s.io/client-go v0.35.2
+       k8s.io/code-generator v0.35.2
+       k8s.io/endpointslice v0.35.2
        k8s.io/klog/v2 v2.130.1
-       k8s.io/kube-aggregator v0.35.1
+       k8s.io/kube-aggregator v0.35.2
        k8s.io/utils v0.0.0-20251002143259-bc988d571ff4
        sigs.k8s.io/gateway-api v0.8.1
        sigs.k8s.io/yaml v1.6.0
@@ -84,16 +84,16 @@
        github.com/fxamacker/cbor/v2 v2.9.0 // indirect
        github.com/go-errors/errors v1.4.2 // indirect
        github.com/go-logr/logr v1.4.3 // indirect
-       github.com/go-openapi/jsonpointer v0.22.4 // indirect
-       github.com/go-openapi/jsonreference v0.21.4 // indirect
+       github.com/go-openapi/jsonpointer v0.22.5 // indirect
+       github.com/go-openapi/jsonreference v0.21.5 // indirect
        github.com/go-openapi/swag v0.23.0 // indirect
-       github.com/go-openapi/swag/conv v0.25.4 // indirect
-       github.com/go-openapi/swag/jsonname v0.25.4 // indirect
-       github.com/go-openapi/swag/jsonutils v0.25.4 // indirect
-       github.com/go-openapi/swag/loading v0.25.4 // indirect
-       github.com/go-openapi/swag/stringutils v0.25.4 // indirect
-       github.com/go-openapi/swag/typeutils v0.25.4 // indirect
-       github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
+       github.com/go-openapi/swag/conv v0.25.5 // indirect
+       github.com/go-openapi/swag/jsonname v0.25.5 // indirect
+       github.com/go-openapi/swag/jsonutils v0.25.5 // indirect
+       github.com/go-openapi/swag/loading v0.25.5 // indirect
+       github.com/go-openapi/swag/stringutils v0.25.5 // indirect
+       github.com/go-openapi/swag/typeutils v0.25.5 // indirect
+       github.com/go-openapi/swag/yamlutils v0.25.5 // indirect
        github.com/gobwas/glob v0.2.3 // indirect
        github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // 
indirect
        github.com/google/btree v1.1.3 // indirect
@@ -158,7 +158,7 @@
        gopkg.in/inf.v0 v0.9.1 // indirect
        gopkg.in/yaml.v3 v3.0.1 // indirect
        k8s.io/cli-runtime v0.35.0 // indirect
-       k8s.io/component-base v0.35.1 // indirect
+       k8s.io/component-base v0.35.2 // indirect
        k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b // indirect
        k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
        k8s.io/kubectl v0.35.0 // indirect
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/go.sum 
new/linkerd-cli-edge-26.3.1/go.sum
--- old/linkerd-cli-edge-26.2.1/go.sum  2026-02-17 20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/go.sum  2026-03-06 00:57:02.000000000 +0100
@@ -140,34 +140,34 @@
 github.com/go-logr/logr v1.4.3/go.mod 
h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod 
h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
-github.com/go-openapi/jsonpointer v0.22.4 
h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4=
-github.com/go-openapi/jsonpointer v0.22.4/go.mod 
h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80=
-github.com/go-openapi/jsonreference v0.21.4 
h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=
-github.com/go-openapi/jsonreference v0.21.4/go.mod 
h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=
-github.com/go-openapi/spec v0.22.3 
h1:qRSmj6Smz2rEBxMnLRBMeBWxbbOvuOoElvSvObIgwQc=
-github.com/go-openapi/spec v0.22.3/go.mod 
h1:iIImLODL2loCh3Vnox8TY2YWYJZjMAKYyLH2Mu8lOZs=
+github.com/go-openapi/jsonpointer v0.22.5 
h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA=
+github.com/go-openapi/jsonpointer v0.22.5/go.mod 
h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0=
+github.com/go-openapi/jsonreference v0.21.5 
h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE=
+github.com/go-openapi/jsonreference v0.21.5/go.mod 
h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw=
+github.com/go-openapi/spec v0.22.4 
h1:4pxGjipMKu0FzFiu/DPwN3CTBRlVM2yLf/YTWorYfDQ=
+github.com/go-openapi/spec v0.22.4/go.mod 
h1:WQ6Ai0VPWMZgMT4XySjlRIE6GP1bGQOtEThn3gcWLtQ=
 github.com/go-openapi/swag v0.23.0 
h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
 github.com/go-openapi/swag v0.23.0/go.mod 
h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
-github.com/go-openapi/swag/conv v0.25.4 
h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4=
-github.com/go-openapi/swag/conv v0.25.4/go.mod 
h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=
-github.com/go-openapi/swag/jsonname v0.25.4 
h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=
-github.com/go-openapi/swag/jsonname v0.25.4/go.mod 
h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
-github.com/go-openapi/swag/jsonutils v0.25.4 
h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=
-github.com/go-openapi/swag/jsonutils v0.25.4/go.mod 
h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=
-github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 
h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo=
-github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod 
h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM=
-github.com/go-openapi/swag/loading v0.25.4 
h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=
-github.com/go-openapi/swag/loading v0.25.4/go.mod 
h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE=
-github.com/go-openapi/swag/stringutils v0.25.4 
h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8=
-github.com/go-openapi/swag/stringutils v0.25.4/go.mod 
h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=
-github.com/go-openapi/swag/typeutils v0.25.4 
h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw=
-github.com/go-openapi/swag/typeutils v0.25.4/go.mod 
h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
-github.com/go-openapi/swag/yamlutils v0.25.4 
h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=
-github.com/go-openapi/swag/yamlutils v0.25.4/go.mod 
h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=
-github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 
h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4=
-github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod 
h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg=
-github.com/go-openapi/testify/v2 v2.0.2 
h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls=
-github.com/go-openapi/testify/v2 v2.0.2/go.mod 
h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
+github.com/go-openapi/swag/conv v0.25.5 
h1:wAXBYEXJjoKwE5+vc9YHhpQOFj2JYBMF2DUi+tGu97g=
+github.com/go-openapi/swag/conv v0.25.5/go.mod 
h1:CuJ1eWvh1c4ORKx7unQnFGyvBbNlRKbnRyAvDvzWA4k=
+github.com/go-openapi/swag/jsonname v0.25.5 
h1:8p150i44rv/Drip4vWI3kGi9+4W9TdI3US3uUYSFhSo=
+github.com/go-openapi/swag/jsonname v0.25.5/go.mod 
h1:jNqqikyiAK56uS7n8sLkdaNY/uq6+D2m2LANat09pKU=
+github.com/go-openapi/swag/jsonutils v0.25.5 
h1:XUZF8awQr75MXeC+/iaw5usY/iM7nXPDwdG3Jbl9vYo=
+github.com/go-openapi/swag/jsonutils v0.25.5/go.mod 
h1:48FXUaz8YsDAA9s5AnaUvAmry1UcLcNVWUjY42XkrN4=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5 
h1:SX6sE4FrGb4sEnnxbFL/25yZBb5Hcg1inLeErd86Y1U=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5/go.mod 
h1:/2KvOTrKWjVA5Xli3DZWdMCZDzz3uV/T7bXwrKWPquo=
+github.com/go-openapi/swag/loading v0.25.5 
h1:odQ/umlIZ1ZVRteI6ckSrvP6e2w9UTF5qgNdemJHjuU=
+github.com/go-openapi/swag/loading v0.25.5/go.mod 
h1:I8A8RaaQ4DApxhPSWLNYWh9NvmX2YKMoB9nwvv6oW6g=
+github.com/go-openapi/swag/stringutils v0.25.5 
h1:NVkoDOA8YBgtAR/zvCx5rhJKtZF3IzXcDdwOsYzrB6M=
+github.com/go-openapi/swag/stringutils v0.25.5/go.mod 
h1:PKK8EZdu4QJq8iezt17HM8RXnLAzY7gW0O1KKarrZII=
+github.com/go-openapi/swag/typeutils v0.25.5 
h1:EFJ+PCga2HfHGdo8s8VJXEVbeXRCYwzzr9u4rJk7L7E=
+github.com/go-openapi/swag/typeutils v0.25.5/go.mod 
h1:itmFmScAYE1bSD8C4rS0W+0InZUBrB2xSPbWt6DLGuc=
+github.com/go-openapi/swag/yamlutils v0.25.5 
h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT6G0iq2SSbVQ=
+github.com/go-openapi/swag/yamlutils v0.25.5/go.mod 
h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ=
+github.com/go-openapi/testify/enable/yaml/v2 v2.4.0 
h1:7SgOMTvJkM8yWrQlU8Jm18VeDPuAvB/xWrdxFJkoFag=
+github.com/go-openapi/testify/enable/yaml/v2 v2.4.0/go.mod 
h1:14iV8jyyQlinc9StD7w1xVPW3CO3q1Gj04Jy//Kw4VM=
+github.com/go-openapi/testify/v2 v2.4.0 
h1:8nsPrHVCWkQ4p8h1EsRVymA2XABB4OT40gcvAu+voFM=
+github.com/go-openapi/testify/v2 v2.4.0/go.mod 
h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
 github.com/go-task/slim-sprig/v3 v3.0.0 
h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
 github.com/go-task/slim-sprig/v3 v3.0.0/go.mod 
h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
 github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
@@ -297,8 +297,8 @@
 github.com/mattn/go-isatty v0.0.20 
h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
 github.com/mattn/go-isatty v0.0.20/go.mod 
h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-runewidth v0.0.9/go.mod 
h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
-github.com/mattn/go-runewidth v0.0.19 
h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
-github.com/mattn/go-runewidth v0.0.19/go.mod 
h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
+github.com/mattn/go-runewidth v0.0.20 
h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ=
+github.com/mattn/go-runewidth v0.0.20/go.mod 
h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
 github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
 github.com/miekg/dns v1.1.57/go.mod 
h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
 github.com/mitchellh/copystructure v1.2.0 
h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
@@ -721,28 +721,28 @@
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod 
h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod 
h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
 honnef.co/go/tools v0.0.1-2020.1.3/go.mod 
h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/api v0.35.1 h1:0PO/1FhlK/EQNVK5+txc4FuhQibV25VLSdLMmGpDE/Q=
-k8s.io/api v0.35.1/go.mod h1:28uR9xlXWml9eT0uaGo6y71xK86JBELShLy4wR1XtxM=
-k8s.io/apiextensions-apiserver v0.35.1 
h1:p5vvALkknlOcAqARwjS20kJffgzHqwyQRM8vHLwgU7w=
-k8s.io/apiextensions-apiserver v0.35.1/go.mod 
h1:2CN4fe1GZ3HMe4wBr25qXyJnJyZaquy4nNlNmb3R7AQ=
-k8s.io/apimachinery v0.35.1 h1:yxO6gV555P1YV0SANtnTjXYfiivaTPvCTKX6w6qdDsU=
-k8s.io/apimachinery v0.35.1/go.mod 
h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
+k8s.io/api v0.35.2 h1:tW7mWc2RpxW7HS4CoRXhtYHSzme1PN1UjGHJ1bdrtdw=
+k8s.io/api v0.35.2/go.mod h1:7AJfqGoAZcwSFhOjcGM7WV05QxMMgUaChNfLTXDRE60=
+k8s.io/apiextensions-apiserver v0.35.2 
h1:iyStXHoJZsUXPh/nFAsjC29rjJWdSgUmG1XpApE29c0=
+k8s.io/apiextensions-apiserver v0.35.2/go.mod 
h1:OdyGvcO1FtMDWQ+rRh/Ei3b6X3g2+ZDHd0MSRGeS8rU=
+k8s.io/apimachinery v0.35.2 h1:NqsM/mmZA7sHW02JZ9RTtk3wInRgbVxL8MPfzSANAK8=
+k8s.io/apimachinery v0.35.2/go.mod 
h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
 k8s.io/cli-runtime v0.35.0 h1:PEJtYS/Zr4p20PfZSLCbY6YvaoLrfByd6THQzPworUE=
 k8s.io/cli-runtime v0.35.0/go.mod 
h1:VBRvHzosVAoVdP3XwUQn1Oqkvaa8facnokNkD7jOTMY=
-k8s.io/client-go v0.35.1 h1:+eSfZHwuo/I19PaSxqumjqZ9l5XiTEKbIaJ+j1wLcLM=
-k8s.io/client-go v0.35.1/go.mod h1:1p1KxDt3a0ruRfc/pG4qT/3oHmUj1AhSHEcxNSGg+OA=
-k8s.io/code-generator v0.35.1 h1:yLKR2la7Z9cWT5qmk67ayx8xXLM4RRKQMnC8YPvTWRI=
-k8s.io/code-generator v0.35.1/go.mod 
h1:F2Fhm7aA69tC/VkMXLDokdovltXEF026Tb9yfQXQWKg=
-k8s.io/component-base v0.35.1 h1:XgvpRf4srp037QWfGBLFsYMUQJkE5yMa94UsJU7pmcE=
-k8s.io/component-base v0.35.1/go.mod 
h1:HI/6jXlwkiOL5zL9bqA3en1Ygv60F03oEpnuU1G56Bs=
-k8s.io/endpointslice v0.35.1 h1:k7S6uT7uIL8ZgVhZ01YLLYtHTQw6wyvQ+iascAcL+wE=
-k8s.io/endpointslice v0.35.1/go.mod 
h1:Kozp94h3FTbhq99FjBVRMy2ieqSDlJWrNf07AQUXCl4=
+k8s.io/client-go v0.35.2 h1:YUfPefdGJA4aljDdayAXkc98DnPkIetMl4PrKX97W9o=
+k8s.io/client-go v0.35.2/go.mod h1:4QqEwh4oQpeK8AaefZ0jwTFJw/9kIjdQi0jpKeYvz7g=
+k8s.io/code-generator v0.35.2 h1:3874swbO2c26VWTf6lKD4NWGyHIfyBeTCk7caCG3TuU=
+k8s.io/code-generator v0.35.2/go.mod 
h1:id4XLCm0yAQq5nlvyfAKibMOKnMjzlesAwGw6kM3Adc=
+k8s.io/component-base v0.35.2 h1:btgR+qNrpWuRSuvWSnQYsZy88yf5gVwemvz0yw79pGc=
+k8s.io/component-base v0.35.2/go.mod 
h1:B1iBJjooe6xIJYUucAxb26RwhAjzx0gHnqO9htWIX+0=
+k8s.io/endpointslice v0.35.2 h1:66K6G3b+tMuyPipy2qcojYJkCmotaEa9HTLxBxhWEiE=
+k8s.io/endpointslice v0.35.2/go.mod 
h1:Nsm3oZlMUa5kI+QbtCcwG7sWwrDqaXq50IoGC36YymY=
 k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b 
h1:gMplByicHV/TJBizHd9aVEsTYoJBnnUAT5MHlTkbjhQ=
 k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b/go.mod 
h1:CgujABENc3KuTrcsdpGmrrASjtQsWCT7R99mEV4U/fM=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
 k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
-k8s.io/kube-aggregator v0.35.1 h1:LN+btMJ3yp7biqVgT/0LF6SKIKLyfPU0R+JJ1mycs2I=
-k8s.io/kube-aggregator v0.35.1/go.mod 
h1:HQSjPQfOFRzcv7biQ7jV3cEfKHG+bczpLCfh4QfvxZU=
+k8s.io/kube-aggregator v0.35.2 h1:bnF7E238wUOVaPpTyKrqGCAEXOAJ6HRTARvJTZ0UIC0=
+k8s.io/kube-aggregator v0.35.2/go.mod 
h1:7Xl9zFJFsFIrPnwBfu7hve+G5QgLsDZRIedc8gA1mq4=
 k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 
h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE=
 k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod 
h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
 k8s.io/kubectl v0.35.0 h1:cL/wJKHDe8E8+rP3G7avnymcMg6bH6JEcR5w5uo06wc=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/pkg/k8s/authz.go 
new/linkerd-cli-edge-26.3.1/pkg/k8s/authz.go
--- old/linkerd-cli-edge-26.2.1/pkg/k8s/authz.go        2026-02-17 
20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/pkg/k8s/authz.go        2026-03-06 
00:57:02.000000000 +0100
@@ -48,11 +48,15 @@
 func ResourceAuthzForUser(
        ctx context.Context,
        client kubernetes.Interface,
-       namespace, verb, group, version, resource, subresource, name, user 
string, userGroups []string) error {
+       namespace, verb, group, version, resource, subresource, name, user 
string,
+       userGroups []string,
+       extra map[string]authV1.ExtraValue,
+) error {
        sar := &authV1.SubjectAccessReview{
                Spec: authV1.SubjectAccessReviewSpec{
                        User:   user,
                        Groups: userGroups,
+                       Extra:  extra,
                        ResourceAttributes: &authV1.ResourceAttributes{
                                Namespace:   namespace,
                                Verb:        verb,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/linkerd-cli-edge-26.2.1/policy-controller/k8s/api/Cargo.toml 
new/linkerd-cli-edge-26.3.1/policy-controller/k8s/api/Cargo.toml
--- old/linkerd-cli-edge-26.2.1/policy-controller/k8s/api/Cargo.toml    
2026-02-17 20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/policy-controller/k8s/api/Cargo.toml    
2026-03-06 00:57:02.000000000 +0100
@@ -7,7 +7,7 @@
 
 [dependencies]
 gateway-api = { workspace = true }
-ipnet = { version = "2.11", features = ["json"] }
+ipnet = { version = "2.12", features = ["json"] }
 k8s-openapi = { workspace = true }
 schemars = "0.8"
 serde = { version = "1", features = ["derive"] }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/policy-test/Cargo.toml 
new/linkerd-cli-edge-26.3.1/policy-test/Cargo.toml
--- old/linkerd-cli-edge-26.2.1/policy-test/Cargo.toml  2026-02-17 
20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/policy-test/Cargo.toml  2026-03-06 
00:57:02.000000000 +0100
@@ -19,7 +19,7 @@
 ipnet = "2"
 k8s-openapi = { workspace = true }
 maplit = "1"
-rand = "0.9"
+rand = "0.10"
 serde = "1"
 serde_json = "1"
 schemars = "0.8"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/policy-test/src/lib.rs 
new/linkerd-cli-edge-26.3.1/policy-test/src/lib.rs
--- old/linkerd-cli-edge-26.2.1/policy-test/src/lib.rs  2026-02-17 
20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/policy-test/src/lib.rs  2026-03-06 
00:57:02.000000000 +0100
@@ -812,7 +812,7 @@
 }
 
 pub fn random_suffix(len: usize) -> String {
-    use rand::Rng;
+    use rand::RngExt;
 
     rand::rng()
         .sample_iter(&LowercaseAlphanumeric)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/viz/tap/api/handlers.go 
new/linkerd-cli-edge-26.3.1/viz/tap/api/handlers.go
--- old/linkerd-cli-edge-26.2.1/viz/tap/api/handlers.go 2026-02-17 
20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/viz/tap/api/handlers.go 2026-03-06 
00:57:02.000000000 +0100
@@ -5,6 +5,7 @@
        "encoding/json"
        "fmt"
        "net/http"
+       "net/url"
        "strings"
 
        "github.com/go-openapi/spec"
@@ -17,17 +18,19 @@
        "github.com/prometheus/client_golang/prometheus/promhttp"
        "github.com/sirupsen/logrus"
        "google.golang.org/grpc/metadata"
+       authV1 "k8s.io/api/authorization/v1"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/apimachinery/pkg/runtime/schema"
        "k8s.io/apimachinery/pkg/version"
 )
 
 type handler struct {
-       k8sAPI         *k8s.API
-       usernameHeader string
-       groupHeader    string
-       grpcTapServer  pb.TapServer
-       log            *logrus.Entry
+       k8sAPI            *k8s.API
+       usernameHeader    string
+       groupHeader       string
+       extraHeaderPrefix string
+       grpcTapServer     pb.TapServer
+       log               *logrus.Entry
 }
 
 // TODO: share with api_handlers.go
@@ -123,6 +126,8 @@
                namespace, resource, name, h.usernameHeader, h.groupHeader,
        )
 
+       extra := extractExtraHeaders(req.Header, h.extraHeaderPrefix)
+
        // TODO: it's possible this SubjectAccessReview is redundant, consider
        // removing, more info at 
https://github.com/linkerd/linkerd2/issues/3182
        err := pkgK8s.ResourceAuthzForUser(
@@ -137,6 +142,7 @@
                name,
                req.Header.Get(h.usernameHeader),
                req.Header.Values(h.groupHeader),
+               extra,
        )
        if err != nil {
                err = fmt.Errorf("tap authorization failed (%w), visit %s for 
more information", err, pkg.TapRbacURL)
@@ -180,6 +186,29 @@
        }
 }
 
+func extractExtraHeaders(header http.Header, extraHeaderPrefix string) 
map[string]authV1.ExtraValue {
+       if extraHeaderPrefix == "" {
+               return nil
+       }
+
+       extraHeaderPrefixLower := strings.ToLower(extraHeaderPrefix)
+       extraHeaderPrefixLen := len(extraHeaderPrefix)
+       extra := make(map[string]authV1.ExtraValue)
+
+       for key, values := range header {
+               if !strings.HasPrefix(strings.ToLower(key), 
extraHeaderPrefixLower) {
+                       continue
+               }
+
+               extraKey, err := url.QueryUnescape(key[extraHeaderPrefixLen:])
+               if err == nil {
+                       extra[extraKey] = authV1.ExtraValue(values)
+               }
+       }
+
+       return extra
+}
+
 // GET (not found)
 func handleNotFound() http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/viz/tap/api/handlers_test.go 
new/linkerd-cli-edge-26.3.1/viz/tap/api/handlers_test.go
--- old/linkerd-cli-edge-26.2.1/viz/tap/api/handlers_test.go    2026-02-17 
20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/viz/tap/api/handlers_test.go    2026-03-06 
00:57:02.000000000 +0100
@@ -11,6 +11,9 @@
        "github.com/julienschmidt/httprouter"
        "github.com/linkerd/linkerd2/controller/k8s"
        "github.com/sirupsen/logrus"
+       authV1 "k8s.io/api/authorization/v1"
+       k8sFake "k8s.io/client-go/kubernetes/fake"
+       k8sTesting "k8s.io/client-go/testing"
 )
 
 func TestHandleTap(t *testing.T) {
@@ -71,3 +74,115 @@
                })
        }
 }
+
+func TestHandleTap_ExtraHeaders(t *testing.T) {
+       k8sAPI, err := k8s.NewFakeAPI()
+       if err != nil {
+               t.Fatalf("NewFakeAPI returned an error: %s", err)
+       }
+
+       h := &handler{
+               k8sAPI:            k8sAPI,
+               log:               logrus.WithField("test", t.Name()),
+               extraHeaderPrefix: "X-Remote-Extra-",
+       }
+
+       recorder := httptest.NewRecorder()
+       req := httptest.NewRequest("POST", 
"/apis/tap.linkerd.io/v1alpha1/watch/namespaces/foo/tap", nil)
+       req.Header.Set("X-Remote-Extra-Foo", "bar")
+       req.Header.Set("X-Remote-Extra-Baz", "qux")
+
+       params := httprouter.Params{
+               {Key: "namespace", Value: "foo"},
+       }
+
+       h.handleTap(recorder, req, params)
+
+       sar := getSubjectAccessReview(t, k8sAPI)
+
+       if len(sar.Spec.Extra) != 2 {
+               t.Errorf("Expected 2 extra headers, got %d", 
len(sar.Spec.Extra))
+       }
+
+       if v, ok := sar.Spec.Extra["Foo"]; !ok || v[0] != "bar" {
+               t.Errorf("Expected Extra['Foo'] to be ['bar'], got %v", v)
+       }
+       if v, ok := sar.Spec.Extra["Baz"]; !ok || v[0] != "qux" {
+               t.Errorf("Expected Extra['Baz'] to be ['qux'], got %v", v)
+       }
+}
+
+func TestHandleTap_ExtraHeadersPrefixCaseInsensitive(t *testing.T) {
+       k8sAPI, err := k8s.NewFakeAPI()
+       if err != nil {
+               t.Fatalf("NewFakeAPI returned an error: %s", err)
+       }
+
+       h := &handler{
+               k8sAPI:            k8sAPI,
+               log:               logrus.WithField("test", t.Name()),
+               extraHeaderPrefix: "x-remote-extra-",
+       }
+
+       recorder := httptest.NewRecorder()
+       req := httptest.NewRequest("POST", 
"/apis/tap.linkerd.io/v1alpha1/watch/namespaces/foo/tap", nil)
+       req.Header.Set("X-Remote-Extra-Foo", "bar")
+
+       params := httprouter.Params{
+               {Key: "namespace", Value: "foo"},
+       }
+
+       h.handleTap(recorder, req, params)
+       sar := getSubjectAccessReview(t, k8sAPI)
+
+       if v, ok := sar.Spec.Extra["Foo"]; !ok || v[0] != "bar" {
+               t.Errorf("Expected Extra['Foo'] to be ['bar'], got %v", v)
+       }
+}
+
+func TestHandleTap_ExtraHeadersEmptyPrefix(t *testing.T) {
+       k8sAPI, err := k8s.NewFakeAPI()
+       if err != nil {
+               t.Fatalf("NewFakeAPI returned an error: %s", err)
+       }
+
+       h := &handler{
+               k8sAPI: k8sAPI,
+               log:    logrus.WithField("test", t.Name()),
+       }
+
+       recorder := httptest.NewRecorder()
+       req := httptest.NewRequest("POST", 
"/apis/tap.linkerd.io/v1alpha1/watch/namespaces/foo/tap", nil)
+       req.Header.Set("X-Remote-Extra-Foo", "bar")
+       req.Header.Set("X-Remote-User", "alice")
+       req.Header.Set("Content-Type", "application/json")
+
+       params := httprouter.Params{
+               {Key: "namespace", Value: "foo"},
+       }
+
+       h.handleTap(recorder, req, params)
+       sar := getSubjectAccessReview(t, k8sAPI)
+
+       if len(sar.Spec.Extra) != 0 {
+               t.Errorf("Expected 0 extra headers, got %d", 
len(sar.Spec.Extra))
+       }
+}
+
+func getSubjectAccessReview(t *testing.T, k8sAPI *k8s.API) 
*authV1.SubjectAccessReview {
+       t.Helper()
+
+       client := k8sAPI.Client.(*k8sFake.Clientset)
+       actions := client.Actions()
+
+       for _, action := range actions {
+               if action.GetVerb() == "create" && 
action.GetResource().Resource == "subjectaccessreviews" {
+                       createAction := action.(k8sTesting.CreateAction)
+                       obj := createAction.GetObject()
+                       return obj.(*authV1.SubjectAccessReview)
+               }
+       }
+
+       t.Fatal("Expected SubjectAccessReview to be created")
+       return nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/viz/tap/api/server.go 
new/linkerd-cli-edge-26.3.1/viz/tap/api/server.go
--- old/linkerd-cli-edge-26.2.1/viz/tap/api/server.go   2026-02-17 
20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/viz/tap/api/server.go   2026-03-06 
00:57:02.000000000 +0100
@@ -22,6 +22,8 @@
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
+const defaultExtraHeaderPrefix = "X-Remote-Extra-"
+
 // Server holds the underlying http server and its config
 type Server struct {
        *http.Server
@@ -50,7 +52,7 @@
                }
        }()
 
-       clientCAPem, allowedNames, usernameHeader, groupHeader, err := 
serverAuth(ctx, k8sAPI)
+       clientCAPem, allowedNames, usernameHeader, groupHeader, 
extraHeaderPrefix, err := serverAuth(ctx, k8sAPI)
        if err != nil {
                return nil, err
        }
@@ -80,11 +82,12 @@
 
        var emptyCert atomic.Value
        h := &handler{
-               k8sAPI:         k8sAPI,
-               usernameHeader: usernameHeader,
-               groupHeader:    groupHeader,
-               grpcTapServer:  grpcTapServer,
-               log:            log,
+               k8sAPI:            k8sAPI,
+               usernameHeader:    usernameHeader,
+               groupHeader:       groupHeader,
+               extraHeaderPrefix: extraHeaderPrefix,
+               grpcTapServer:     grpcTapServer,
+               log:               log,
        }
 
        lis, err := net.Listen("tcp", addr)
@@ -164,28 +167,28 @@
 // authentication.
 // kubectl -n kube-system get cm/extension-apiserver-authentication
 // accessible via the extension-apiserver-authentication-reader role
-func serverAuth(ctx context.Context, k8sAPI *k8s.API) (string, []string, 
string, string, error) {
+func serverAuth(ctx context.Context, k8sAPI *k8s.API) (string, []string, 
string, string, string, error) {
 
        cm, err := k8sAPI.Client.CoreV1().
                ConfigMaps(metav1.NamespaceSystem).
                Get(ctx, pkgk8s.ExtensionAPIServerAuthenticationConfigMapName, 
metav1.GetOptions{})
        if err != nil {
-               return "", nil, "", "", fmt.Errorf("failed to load [%s] config: 
%w", pkgk8s.ExtensionAPIServerAuthenticationConfigMapName, err)
+               return "", nil, "", "", "", fmt.Errorf("failed to load [%s] 
config: %w", pkgk8s.ExtensionAPIServerAuthenticationConfigMapName, err)
        }
 
        clientCAPem, ok := 
cm.Data[pkgk8s.ExtensionAPIServerAuthenticationRequestHeaderClientCAFileKey]
        if !ok {
-               return "", nil, "", "", fmt.Errorf("no client CA cert available 
for apiextension-server")
+               return "", nil, "", "", "", fmt.Errorf("no client CA cert 
available for apiextension-server")
        }
 
        allowedNames, err := 
deserializeStrings(cm.Data["requestheader-allowed-names"])
        if err != nil {
-               return "", nil, "", "", err
+               return "", nil, "", "", "", err
        }
 
        usernameHeaders, err := 
deserializeStrings(cm.Data["requestheader-username-headers"])
        if err != nil {
-               return "", nil, "", "", err
+               return "", nil, "", "", "", err
        }
        usernameHeader := ""
        if len(usernameHeaders) > 0 {
@@ -194,14 +197,28 @@
 
        groupHeaders, err := 
deserializeStrings(cm.Data["requestheader-group-headers"])
        if err != nil {
-               return "", nil, "", "", err
+               return "", nil, "", "", "", err
        }
        groupHeader := ""
        if len(groupHeaders) > 0 {
                groupHeader = groupHeaders[0]
        }
 
-       return clientCAPem, allowedNames, usernameHeader, groupHeader, nil
+       extraHeaderPrefixes, err := 
deserializeStrings(cm.Data["requestheader-extra-headers-prefix"])
+       if err != nil {
+               return "", nil, "", "", "", err
+       }
+       // The extra headers prefix is used to identify headers that contain 
additional
+       // user attributes for authorization (e.g., "X-Remote-Extra-"). These 
headers are
+       // forwarded by the Kubernetes API server when acting as an aggregating 
proxy.
+       // The prefix is configurable via the 
--requestheader-extra-headers-prefix flag
+       // on the API server (defaults to "X-Remote-Extra-").
+       extraHeaderPrefix := defaultExtraHeaderPrefix
+       if len(extraHeaderPrefixes) > 0 && extraHeaderPrefixes[0] != "" {
+               extraHeaderPrefix = extraHeaderPrefixes[0]
+       }
+
+       return clientCAPem, allowedNames, usernameHeader, groupHeader, 
extraHeaderPrefix, nil
 }
 
 // copied from 
https://github.com/kubernetes/apiserver/blob/781c3cd1b3dc5b6f79c68ab0d16fe544600421ef/pkg/server/options/authentication.go#L360
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/viz/tap/api/server_test.go 
new/linkerd-cli-edge-26.3.1/viz/tap/api/server_test.go
--- old/linkerd-cli-edge-26.2.1/viz/tap/api/server_test.go      2026-02-17 
20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/viz/tap/api/server_test.go      2026-03-06 
00:57:02.000000000 +0100
@@ -18,12 +18,13 @@
 
 func TestAPIServerAuth(t *testing.T) {
        expectations := []struct {
-               k8sRes         []string
-               clientCAPem    string
-               allowedNames   []string
-               usernameHeader string
-               groupHeader    string
-               err            error
+               k8sRes            []string
+               clientCAPem       string
+               allowedNames      []string
+               usernameHeader    string
+               groupHeader       string
+               extraHeaderPrefix string
+               err               error
        }{
                {
                        err: fmt.Errorf("failed to load [%s] config: configmaps 
%q not found", k8sutils.ExtensionAPIServerAuthenticationConfigMapName, 
k8sutils.ExtensionAPIServerAuthenticationConfigMapName),
@@ -44,11 +45,29 @@
   requestheader-username-headers: '["X-Remote-User"]'
 `,
                        },
-                       clientCAPem:    "requestheader-client-ca-file",
-                       allowedNames:   []string{"name1", "name2"},
-                       usernameHeader: "X-Remote-User",
-                       groupHeader:    "X-Remote-Group",
-                       err:            nil,
+                       clientCAPem:       "requestheader-client-ca-file",
+                       allowedNames:      []string{"name1", "name2"},
+                       usernameHeader:    "X-Remote-User",
+                       groupHeader:       "X-Remote-Group",
+                       extraHeaderPrefix: "X-Remote-Extra-",
+                       err:               nil,
+               },
+               {
+                       k8sRes: []string{`
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: extension-apiserver-authentication
+  namespace: kube-system
+data:
+  requestheader-client-ca-file: 'requestheader-client-ca-file'
+`},
+                       clientCAPem:       "requestheader-client-ca-file",
+                       allowedNames:      nil,
+                       usernameHeader:    "",
+                       groupHeader:       "",
+                       extraHeaderPrefix: defaultExtraHeaderPrefix,
+                       err:               nil,
                },
        }
 
@@ -62,7 +81,7 @@
                                t.Fatalf("NewFakeAPI returned an error: %s", 
err)
                        }
 
-                       clientCAPem, allowedNames, usernameHeader, groupHeader, 
err := serverAuth(ctx, k8sAPI)
+                       clientCAPem, allowedNames, usernameHeader, groupHeader, 
extraHeaderPrefix, err := serverAuth(ctx, k8sAPI)
 
                        if err != nil && exp.err != nil {
                                if err.Error() != exp.err.Error() {
@@ -86,6 +105,9 @@
                        if groupHeader != exp.groupHeader {
                                t.Errorf("apiServerAuth returned unexpected 
groupHeader: %q, expected: %q", groupHeader, exp.groupHeader)
                        }
+                       if extraHeaderPrefix != exp.extraHeaderPrefix {
+                               t.Errorf("apiServerAuth returned unexpected 
extraHeaderPrefix: %q, expected: %q", extraHeaderPrefix, exp.extraHeaderPrefix)
+                       }
                })
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/web/app/package.json 
new/linkerd-cli-edge-26.3.1/web/app/package.json
--- old/linkerd-cli-edge-26.2.1/web/app/package.json    2026-02-17 
20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/web/app/package.json    2026-03-06 
00:57:02.000000000 +0100
@@ -56,7 +56,7 @@
     "babel-plugin-transform-react-remove-prop-types": "0.4.24",
     "chai": "4.5.0",
     "clean-webpack-plugin": "4.0.0",
-    "css-loader": "^7.1.3",
+    "css-loader": "^7.1.4",
     "enzyme": "3.11.0",
     "enzyme-adapter-react-16": "^1.15.8",
     "eslint": "^8.57.1",
@@ -78,7 +78,7 @@
     "sinon-stub-promise": "4.0.0",
     "style-loader": "^4.0.0",
     "url-loader": "^4.1.1",
-    "webpack": "^5.105.2",
+    "webpack": "^5.105.3",
     "webpack-bundle-analyzer": "5.2.0",
     "webpack-cli": "6.0.1",
     "webpack-dev-server": "5.2.3"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linkerd-cli-edge-26.2.1/web/app/yarn.lock 
new/linkerd-cli-edge-26.3.1/web/app/yarn.lock
--- old/linkerd-cli-edge-26.2.1/web/app/yarn.lock       2026-02-17 
20:17:36.000000000 +0100
+++ new/linkerd-cli-edge-26.3.1/web/app/yarn.lock       2026-03-06 
00:57:02.000000000 +0100
@@ -2723,10 +2723,10 @@
   resolved 
"https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1";
   integrity 
sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
 
-acorn@^8.0.4, acorn@^8.15.0, acorn@^8.5.0, acorn@^8.8.2, acorn@^8.9.0:
-  version "8.15.0"
-  resolved 
"https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816";
-  integrity 
sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
+acorn@^8.0.4, acorn@^8.16.0, acorn@^8.5.0, acorn@^8.8.2, acorn@^8.9.0:
+  version "8.16.0"
+  resolved 
"https://registry.yarnpkg.com/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a";
+  integrity 
sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==
 
 agent-base@^7.1.0, agent-base@^7.1.2:
   version "7.1.3"
@@ -3820,10 +3820,10 @@
     shebang-command "^2.0.0"
     which "^2.0.1"
 
-css-loader@^7.1.3:
-  version "7.1.3"
-  resolved 
"https://registry.yarnpkg.com/css-loader/-/css-loader-7.1.3.tgz#c0de715ceabe39b8531a85fcaf6734a430c4d99a";
-  integrity 
sha512-frbERmjT0UC5lMheWpJmMilnt9GEhbZJN/heUb7/zaJYeIzj5St9HvDcfshzzOqbsS+rYpMk++2SD3vGETDSyA==
+css-loader@^7.1.4:
+  version "7.1.4"
+  resolved 
"https://registry.yarnpkg.com/css-loader/-/css-loader-7.1.4.tgz#8f6bf9f8fc8cbef7d2ef6e80acc6545eaefa90b1";
+  integrity 
sha512-vv3J9tlOl04WjiMvHQI/9tmIrCxVrj6PFbHemBB1iihpeRbi/I4h033eoFIhwxBBqLhI0KYFS7yvynBFhIZfTw==
   dependencies:
     icss-utils "^5.1.0"
     postcss "^8.4.40"
@@ -10296,15 +10296,15 @@
     flat "^5.0.2"
     wildcard "^2.0.1"
 
-webpack-sources@^3.3.3:
-  version "3.3.3"
-  resolved 
"https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723";
-  integrity 
sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==
-
-webpack@^5.105.2:
-  version "5.105.2"
-  resolved 
"https://registry.yarnpkg.com/webpack/-/webpack-5.105.2.tgz#f3b76f9fc36f1152e156e63ffda3bbb82e6739ea";
-  integrity 
sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw==
+webpack-sources@^3.3.4:
+  version "3.3.4"
+  resolved 
"https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.4.tgz#a338b95eb484ecc75fbb196cbe8a2890618b4891";
+  integrity 
sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==
+
+webpack@^5.105.3:
+  version "5.105.3"
+  resolved 
"https://registry.yarnpkg.com/webpack/-/webpack-5.105.3.tgz#307ad95bafffd08bc81049d6519477b16e42e7ba";
+  integrity 
sha512-LLBBA4oLmT7sZdHiYE/PeVuifOxYyE2uL/V+9VQP7YSYdJU7bSf7H8bZRRxW8kEPMkmVjnrXmoR3oejIdX0xbg==
   dependencies:
     "@types/eslint-scope" "^3.7.7"
     "@types/estree" "^1.0.8"
@@ -10312,7 +10312,7 @@
     "@webassemblyjs/ast" "^1.14.1"
     "@webassemblyjs/wasm-edit" "^1.14.1"
     "@webassemblyjs/wasm-parser" "^1.14.1"
-    acorn "^8.15.0"
+    acorn "^8.16.0"
     acorn-import-phases "^1.0.3"
     browserslist "^4.28.1"
     chrome-trace-event "^1.0.2"
@@ -10330,7 +10330,7 @@
     tapable "^2.3.0"
     terser-webpack-plugin "^5.3.16"
     watchpack "^2.5.1"
-    webpack-sources "^3.3.3"
+    webpack-sources "^3.3.4"
 
 websocket-driver@>=0.5.1, websocket-driver@^0.7.4:
   version "0.7.4"

++++++ linkerd-cli-edge.obsinfo ++++++
--- /var/tmp/diff_new_pack.KVpgLa/_old  2026-03-06 18:21:50.656253653 +0100
+++ /var/tmp/diff_new_pack.KVpgLa/_new  2026-03-06 18:21:50.664253987 +0100
@@ -1,5 +1,5 @@
 name: linkerd-cli-edge
-version: 26.2.1
-mtime: 1771355856
-commit: b5621f5c07d8ae36cb7393923dda871e90ece588
+version: 26.3.1
+mtime: 1772755022
+commit: 2534d7d3702ecedd134149a156afd20e7efdf049
 

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/linkerd-cli-edge/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.linkerd-cli-edge.new.561/vendor.tar.gz differ: char 
139, line 1

Reply via email to