@@ -96,7 +96,8 @@ tags, and then generate with `hack/update-toc.sh`.
96
96
- [ Background: <code >PortForward</code > Subprotocol] ( #background-portforward-subprotocol )
97
97
- [ Proposal: New <code >PortForward</code > Tunneling Subprotocol Version - <code >v2.portforward.k8s.io</code >] ( #proposal-new-portforward-tunneling-subprotocol-version---v2portforwardk8sio )
98
98
- [ Proposal: API Server PortForward -- Stream Tunnel Proxy] ( #proposal-api-server-portforward----stream-tunnel-proxy )
99
- - [ Pre-GA: Kubelet <code >StreamTranslatorProxy</code >] ( #pre-ga-kubelet-streamtranslatorproxy )
99
+ - [ Proposal: Synthetic RBAC CREATE Authorization Check] ( #proposal-synthetic-rbac-create-authorization-check )
100
+ - [ Proposal: Transitioning the API Server-to-Kubelet Connection] ( #proposal-transitioning-the-api-server-to-kubelet-connection )
100
101
- [ Test Plan] ( #test-plan )
101
102
- [ Prerequisite testing updates] ( #prerequisite-testing-updates )
102
103
- [ Unit tests] ( #unit-tests )
@@ -109,6 +110,7 @@ tags, and then generate with `hack/update-toc.sh`.
109
110
- [ Beta] ( #beta )
110
111
- [ v1.30 RemoteCommand Subprotocol (exec, cp, and attach)] ( #v130-remotecommand-subprotocol-exec-cp-and-attach )
111
112
- [ v1.31 PortForward Subprotocol (port-forward)] ( #v131-portforward-subprotocol-port-forward )
113
+ - [ v1.35 Synthetic RBAC CREATE Authorization Check] ( #v135-synthetic-rbac-create-authorization-check )
112
114
- [ GA] ( #ga )
113
115
- [ Upgrade / Downgrade Strategy] ( #upgrade--downgrade-strategy )
114
116
- [ Version Skew Strategy] ( #version-skew-strategy )
@@ -236,7 +238,7 @@ communication leg between `kubectl` and the API Server.
236
238
237
239
2 . Extend the WebSockets communication leg from the API Server to Kubelet. After this
238
240
extension, WebSockets streaming will occur between ` kubectl ` and Kubelet (proxied
239
- through the API Server). This plan is described at [ Pre-GA: Kubelet ] ( #pre-ga-kubelet- ) .
241
+ through the API Server).
240
242
241
243
### Non-Goals
242
244
@@ -247,6 +249,10 @@ and make progress.
247
249
248
250
1 . We will not make * any* changes to current WebSocket based browser/javascript clients.
249
251
252
+ 2 . We will not transition the streaming protocol for the communication leg on the
253
+ Node between the Kubelet and the container runtime. This leg will continue to stream
254
+ the SPDY protocol.
255
+
250
256
## Proposal
251
257
252
258
<!--
@@ -510,22 +516,36 @@ as the downstream connection within the dual concurrent `io.Copy` proxying gorou
510
516
The upstream connection is the same SPDY connection to the container (through the
511
517
Kubelet and CRI).
512
518
513
- ### Pre-GA: Kubelet ` StreamTranslatorProxy `
514
-
515
- The eventual plan is to incrementally transition all SPDY communication legs to WebSockets.
516
- After the WebSocket communication leg from ` kubectl ` to the API Server is proven
517
- to work, the next communication leg to transition is the one from the API Server to
518
- the Kubelet. Both the API Server and the Kubelet stream data messages using the
519
- ` UpgradeAwareProxy ` . Since the initial plan is to modify the ` UpgradeAwareProxy `
520
- in the API Server to delegate to the ` StreamTranslatorProxy ` , it will be straightforward
521
- to transition this next communication leg by moving the integrated ` StreamTranslatorProxy `
522
- from the API Server to the Kubelet.
523
-
524
- The final communication leg to transition from SPDY to WebSockets will be the one
525
- from Kubelet to the Container Runtimes. Since this communication happens within a
526
- node (using Unix domain sockets), this path is not as critical. But this effort
527
- will be more work, since it will require modifying not just Kubelet, but ** all**
528
- Container Runtimes.
519
+ ### Proposal: Synthetic RBAC CREATE Authorization Check
520
+
521
+ The transition to WebSockets requires changing the initial streaming upgrade request
522
+ from a POST to a GET, as the WebSocket protocol specification
523
+ ([ RFC 6455] ( https://www.rfc-editor.org/rfc/rfc6455#section-4.1 ) ) mandates that the
524
+ opening handshake must be an HTTP GET request. This has an unintended security
525
+ consequence: RBAC policies that only grant the get verb, such as a typical read-only
526
+ "viewer" role, now unexpectedly allow users to run kubectl exec, attach, and port-forward.
527
+ To close this privilege escalation vector and restore the principle of least privilege,
528
+ this proposal introduces a secondary, synthetic authorization check performed within the
529
+ API Server. When a WebSocket upgrade request is received for the pods/exec, pods/attach,
530
+ or pods/portforward subresources, the handler will perform an additional check to ensure
531
+ the user also has the create verb permission for that specific subresource. This new
532
+ authorization check will be controlled by a feature gate,
533
+ ` AuthorizePodWebsocketUpgradeCreatePermission ` , which will be enabled by default to
534
+ ensure clusters are secure while allowing operators to temporarily disable it as
535
+ they update their RBAC policies.
536
+
537
+ ### Proposal: Transitioning the API Server-to-Kubelet Connection
538
+
539
+ The long-term goal of this KEP is to replace SPDY with WebSockets for the entire
540
+ communication path from the client to the Kubelet. After the initial
541
+ kubectl-to-API-Server leg is stable, this proposal outlines the next phase:
542
+ transitioning the communication between the API Server and the Kubelet. This is
543
+ achieved by replicating the translation logic currently in the API Server—specifically
544
+ the ` StreamTranslatorProxy ` (for exec/attach) and the ` StreamTunnelingProxy `
545
+ (for port-forward)—into the Kubelet's ` UpgradeAwareProxy ` . Once implemented, WebSocket
546
+ streaming will extend end-to-end from the client to the Node, with the Kubelet then
547
+ translating the stream to SPDY for the final, intra-node communication leg to the
548
+ container runtime.
529
549
530
550
### Test Plan
531
551
@@ -735,6 +755,8 @@ in back-to-back releases.
735
755
736
756
##### v1.30 RemoteCommand Subprotocol (exec, cp, and attach)
737
757
758
+ - ` kubectl ` environment variable KUBECTL_REMOTE_COMMAND_WEBSOCKETS is ** ON** by default.
759
+ - API Server feature flag ` TranslateStreamCloseWebsocketRequests ` is ** ON** by default.
738
760
- Additional ` exec ` , ` cp ` , and ` attach ` unit tests completed and enabled.
739
761
- Additional ` exec ` , ` cp ` , and ` attach ` integration tests completed and enabled.
740
762
- Additional ` exec ` , ` cp ` , and ` attach ` e2e tests completed and enabled.
@@ -752,8 +774,17 @@ in back-to-back releases.
752
774
- Additional ` port-forward ` integration tests completed and enabled.
753
775
- Additional ` port-forward ` e2e tests completed and enabled.
754
776
777
+ ##### v1.35 Synthetic RBAC CREATE Authorization Check
778
+
779
+ - Force synthetic RBAC ` CREATE ` authorization check for WebSocket upgrades on the following
780
+ subresources: ` pods/exec ` , ` pods/attach ` , and ` pods/portforward ` . This additional check
781
+ will be gated by the API Server ` AuthorizePodWebsocketUpgradeCreatePermission ` feature flag,
782
+ which defaults to ** TRUE** .
783
+
755
784
#### GA
756
785
786
+ - ` kubectl ` environment variables and API Server feature gates are locked to on by default.
787
+ - Deprecate ` kubectl ` environment variables and API Server feature gates for future removal.
757
788
- Add WebSocket support for HTTPS proxies.
758
789
- See (https://github.com/kubernetes/kubernetes/issues/126134 )
759
790
- Conformance tests for ` RemoteCommand ` completed and enabled.
@@ -892,6 +923,8 @@ well as the [existing list] of feature gates.
892
923
KUBECTL_REMOTE_COMMAND_WEBSOCKETS, TranslateStreamCloseWebsocketRequests
893
924
- Feature gate name(s) for PortForward Subprotocol:
894
925
KUBECTL_PORT_FORWARD_WEBSOCKETS, PortForwardWebsockets
926
+ - Feature gate name(s) for subresource endpoints ` pods/exec ` , ` pods/attach ` ,
927
+ and ` pods/portforward ` : AuthorizePodWebsocketUpgradeCreatePermission
895
928
- Components depending on the feature gate: kubectl, API Server
896
929
897
930
###### Does enabling the feature change any default behavior?
@@ -910,7 +943,11 @@ variable set to **ON** for `exec`, `cp`, and `attach` commands. While the
910
943
KUBECTL_PORT_FORWARD_WEBSOCKETS environment variable must be set to ** ON** for
911
944
` port-forward ` command. These modifications, however, will be transparent to the
912
945
user unless the ` kubectl ` /API Server communication is communicating through an
913
- intermediary such as a proxy (which is the whole reason for the feature).
946
+ intermediary such as a proxy (which is the whole reason for the feature). The API Server
947
+ feature flag ` AuthorizePodWebsocketUpgradeCreatePermission ` forces a synthetic, secondary
948
+ RBAC check for the ` CREATE ` verb permission on WebSocket upgrade requests. When this
949
+ feature gate is ** TRUE** , the additional permission check will apply to endpoints
950
+ ` pods/exec ` , ` pods/attach ` , and ` pods/portforward ` .
914
951
915
952
###### Can the feature be disabled once it has been enabled (i.e. can we roll back the enablement)?
916
953
@@ -928,7 +965,9 @@ NOTE: Also set `disable-supported` to `true` or `false` in `kep.yaml`.
928
965
The features can be disabled for a single user by setting the ` kubectl ` environment
929
966
variable associated with the feature to ** OFF** . Or the features can be turned off
930
967
for all ` kubectl ` users communicating with a cluster by turning off the feature flags
931
- for the API Server.
968
+ for the API Server. A cluster operator can temporarily disable the more stringent permissions for
969
+ subresources ` pods/exec ` , ` pods/attach ` , and ` pods/portforward ` by setting the
970
+ ` AuthorizePodWebsocketUpgradeCreatePermission ` feature flag to ** FALSE** .
932
971
933
972
###### What happens if we reenable the feature if it was previously rolled back?
934
973
@@ -957,6 +996,9 @@ https://github.com/kubernetes/kubernetes/pull/97058/files#diff-7826f7adbc1996a05
957
996
- There are unit tests in the API Server which exercise the feature gate within
958
997
the ` UpgradeAwareProxy ` , which conditionally delegates to the ` StreamTunneling `
959
998
proxy for the PortForward subprotocol.
999
+ - There will be unit tests in the API Server to verify the feature gate
1000
+ forcing more stringent RBAC checks for ` pods/exec ` , ` pods/attach ` , and
1001
+ ` pods/portforward ` .
960
1002
961
1003
### Rollout, Upgrade and Rollback Planning
962
1004
@@ -1455,6 +1497,8 @@ Major milestones might include:
1455
1497
- First Kubernetes release where PortForward over WebSockets described in KEP: v1.30
1456
1498
- PortForward over WebSockets shipped as alpha: v1.30
1457
1499
- PortForward over WebSockets shipped as beta: v1.31
1500
+ - WebSocket HTTPS Proxy functionality shipped: v1.33
1501
+ - Synthetic RBAC ` CREATE ` authz check for WebSocket upgrade requests: v1.35
1458
1502
1459
1503
## Drawbacks
1460
1504
0 commit comments