@@ -96,7 +96,8 @@ tags, and then generate with `hack/update-toc.sh`.
9696 - [ Background: <code >PortForward</code > Subprotocol] ( #background-portforward-subprotocol )
9797 - [ Proposal: New <code >PortForward</code > Tunneling Subprotocol Version - <code >v2.portforward.k8s.io</code >] ( #proposal-new-portforward-tunneling-subprotocol-version---v2portforwardk8sio )
9898 - [ 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 )
100101 - [ Test Plan] ( #test-plan )
101102 - [ Prerequisite testing updates] ( #prerequisite-testing-updates )
102103 - [ Unit tests] ( #unit-tests )
@@ -109,6 +110,7 @@ tags, and then generate with `hack/update-toc.sh`.
109110 - [ Beta] ( #beta )
110111 - [ v1.30 RemoteCommand Subprotocol (exec, cp, and attach)] ( #v130-remotecommand-subprotocol-exec-cp-and-attach )
111112 - [ 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 )
112114 - [ GA] ( #ga )
113115 - [ Upgrade / Downgrade Strategy] ( #upgrade--downgrade-strategy )
114116 - [ Version Skew Strategy] ( #version-skew-strategy )
@@ -236,7 +238,7 @@ communication leg between `kubectl` and the API Server.
236238
2372392 . Extend the WebSockets communication leg from the API Server to Kubelet. After this
238240extension, 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).
240242
241243### Non-Goals
242244
@@ -247,6 +249,10 @@ and make progress.
247249
2482501 . We will not make * any* changes to current WebSocket based browser/javascript clients.
249251
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+
250256## Proposal
251257
252258<!--
@@ -510,22 +516,36 @@ as the downstream connection within the dual concurrent `io.Copy` proxying gorou
510516The upstream connection is the same SPDY connection to the container (through the
511517Kubelet and CRI).
512518
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.
529549
530550### Test Plan
531551
@@ -735,6 +755,8 @@ in back-to-back releases.
735755
736756##### v1.30 RemoteCommand Subprotocol (exec, cp, and attach)
737757
758+ - ` kubectl ` environment variable KUBECTL_REMOTE_COMMAND_WEBSOCKETS is ** ON** by default.
759+ - API Server feature flag ` TranslateStreamCloseWebsocketRequests ` is ** ON** by default.
738760- Additional ` exec ` , ` cp ` , and ` attach ` unit tests completed and enabled.
739761- Additional ` exec ` , ` cp ` , and ` attach ` integration tests completed and enabled.
740762- Additional ` exec ` , ` cp ` , and ` attach ` e2e tests completed and enabled.
@@ -752,8 +774,17 @@ in back-to-back releases.
752774- Additional ` port-forward ` integration tests completed and enabled.
753775- Additional ` port-forward ` e2e tests completed and enabled.
754776
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+
755784#### GA
756785
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.
757788- Add WebSocket support for HTTPS proxies.
758789 - See (https://github.com/kubernetes/kubernetes/issues/126134 )
759790- Conformance tests for ` RemoteCommand ` completed and enabled.
@@ -892,6 +923,8 @@ well as the [existing list] of feature gates.
892923 KUBECTL_REMOTE_COMMAND_WEBSOCKETS, TranslateStreamCloseWebsocketRequests
893924 - Feature gate name(s) for PortForward Subprotocol:
894925 KUBECTL_PORT_FORWARD_WEBSOCKETS, PortForwardWebsockets
926+ - Feature gate name(s) for subresource endpoints ` pods/exec ` , ` pods/attach ` ,
927+ and ` pods/portforward ` : AuthorizePodWebsocketUpgradeCreatePermission
895928- Components depending on the feature gate: kubectl, API Server
896929
897930###### Does enabling the feature change any default behavior?
@@ -910,7 +943,11 @@ variable set to **ON** for `exec`, `cp`, and `attach` commands. While the
910943KUBECTL_PORT_FORWARD_WEBSOCKETS environment variable must be set to ** ON** for
911944` port-forward ` command. These modifications, however, will be transparent to the
912945user 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 ` .
914951
915952###### Can the feature be disabled once it has been enabled (i.e. can we roll back the enablement)?
916953
@@ -928,7 +965,9 @@ NOTE: Also set `disable-supported` to `true` or `false` in `kep.yaml`.
928965The features can be disabled for a single user by setting the ` kubectl ` environment
929966variable associated with the feature to ** OFF** . Or the features can be turned off
930967for 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** .
932971
933972###### What happens if we reenable the feature if it was previously rolled back?
934973
@@ -957,6 +996,9 @@ https://github.com/kubernetes/kubernetes/pull/97058/files#diff-7826f7adbc1996a05
957996- There are unit tests in the API Server which exercise the feature gate within
958997 the ` UpgradeAwareProxy ` , which conditionally delegates to the ` StreamTunneling `
959998 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 ` .
9601002
9611003### Rollout, Upgrade and Rollback Planning
9621004
@@ -1455,6 +1497,8 @@ Major milestones might include:
14551497- First Kubernetes release where PortForward over WebSockets described in KEP: v1.30
14561498- PortForward over WebSockets shipped as alpha: v1.30
14571499- 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
14581502
14591503## Drawbacks
14601504
0 commit comments