diff --git a/pkg/console/operator/sync_v400.go b/pkg/console/operator/sync_v400.go index 0a193666c4..c40a66ffdd 100644 --- a/pkg/console/operator/sync_v400.go +++ b/pkg/console/operator/sync_v400.go @@ -119,11 +119,11 @@ func (co *consoleOperator) sync_v400(ctx context.Context, controllerContext fact } } } + } - sessionSecret, err = co.syncSessionSecret(ctx, updatedOperatorConfig, controllerContext.Recorder()) - if err != nil { - return statusHandler.FlushAndReturn(err) - } + sessionSecret, err = co.syncSessionSecret(ctx, updatedOperatorConfig, controllerContext.Recorder()) + if err != nil { + return statusHandler.FlushAndReturn(err) } customLogosErr, customLogosErrReason := co.SyncCustomLogos(updatedOperatorConfig) diff --git a/pkg/console/subresource/configmap/configmap_test.go b/pkg/console/subresource/configmap/configmap_test.go index 4e7ef3a637..a9b04f2270 100644 --- a/pkg/console/subresource/configmap/configmap_test.go +++ b/pkg/console/subresource/configmap/configmap_test.go @@ -123,7 +123,11 @@ clusterInfo: masterPublicURL: ` + mockAPIServer + ` controlPlaneTopology: HighlyAvailable releaseVersion: ` + testReleaseVersion + ` -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -189,7 +193,11 @@ clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` releaseVersion: ` + testReleaseVersion + ` -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -215,7 +223,11 @@ providers: {} managedConfig: &corev1.ConfigMap{ Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -271,7 +283,11 @@ clusterInfo: nodeArchitectures: - amd64 - arm64 -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -299,7 +315,11 @@ telemetry: managedConfig: &corev1.ConfigMap{ Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -352,7 +372,11 @@ clusterInfo: nodeOperatingSystems: - foo - bar -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -387,7 +411,11 @@ providers: {} managedConfig: &corev1.ConfigMap{ Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -436,7 +464,11 @@ clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` releaseVersion: ` + testReleaseVersion + ` -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + string(operatorv1.BrandDedicatedLegacy) + ` documentationBaseURL: ` + mockOperatorDocURL + ` @@ -477,7 +509,11 @@ providers: {} managedConfig: &corev1.ConfigMap{ Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -526,7 +562,11 @@ clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` releaseVersion: ` + testReleaseVersion + ` -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + string(operatorv1.BrandDedicatedLegacy) + ` documentationBaseURL: ` + mockOperatorDocURL + ` @@ -630,7 +670,11 @@ providers: {} managedConfig: &corev1.ConfigMap{ Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -679,7 +723,11 @@ clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` releaseVersion: ` + testReleaseVersion + ` -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + string(operatorv1.BrandDedicatedLegacy) + ` documentationBaseURL: ` + mockOperatorDocURL + ` @@ -749,7 +797,11 @@ providers: {} managedConfig: &corev1.ConfigMap{ Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -798,7 +850,11 @@ clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` releaseVersion: ` + testReleaseVersion + ` -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + string(operatorv1.BrandDedicatedLegacy) + ` documentationBaseURL: ` + mockOperatorDocURL + ` @@ -871,7 +927,11 @@ clusterInfo: consoleBaseAddress: https://` + customHostname + ` masterPublicURL: ` + mockAPIServer + ` releaseVersion: ` + testReleaseVersion + ` -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -939,7 +999,11 @@ clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` releaseVersion: ` + testReleaseVersion + ` -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -1010,7 +1074,11 @@ clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` releaseVersion: ` + testReleaseVersion + ` -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -1122,7 +1190,11 @@ clusterInfo: masterPublicURL: ` + mockAPIServer + ` controlPlaneTopology: External releaseVersion: ` + testReleaseVersion + ` -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -1192,7 +1264,11 @@ clusterInfo: controlPlaneTopology: External releaseVersion: ` + testReleaseVersion + ` copiedCSVsDisabled: true -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -1266,7 +1342,11 @@ clusterInfo: masterPublicURL: ` + mockAPIServer + ` controlPlaneTopology: HighlyAvailable releaseVersion: ` + testReleaseVersion + ` -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -1503,7 +1583,11 @@ func Test_extractYAML(t *testing.T) { }, Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -1514,7 +1598,11 @@ customization: }, want: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ diff --git a/pkg/console/subresource/consoleserver/config_builder.go b/pkg/console/subresource/consoleserver/config_builder.go index 2efa75dc41..cb4b5b9a00 100644 --- a/pkg/console/subresource/consoleserver/config_builder.go +++ b/pkg/console/subresource/consoleserver/config_builder.go @@ -21,8 +21,12 @@ const ( clientSecretFilePath = "/var/oauth-config/clientSecret" oauthServingCertFilePath = "/var/oauth-serving-cert/ca-bundle.crt" // serving info - certFilePath = "/var/serving-cert/tls.crt" - keyFilePath = "/var/serving-cert/tls.key" + certFilePath = "/var/serving-cert/tls.crt" + keyFilePath = "/var/serving-cert/tls.key" + sessionAuthKeyFilePath = "/var/session-secret/sessionAuthenticationKey" + sessionEncKeyFilePath = "/var/session-secret/sessionEncryptionKey" + previousSessionAuthKeyFilePath = "/var/session-secret/previousSessionAuthenticationKey" + previousSessionEncKeyFilePath = "/var/session-secret/previousSessionEncryptionKey" ) // SupportedLightspeedArchitectures defines the list of architectures that support Lightspeed. @@ -46,45 +50,47 @@ var SupportedLightspeedArchitectures = []string{"amd64"} // // b.Host().Brand("").Config() type ConsoleServerCLIConfigBuilder struct { - host string - logoutRedirectURL string - brand operatorv1.Brand - docURL string - apiServerURL string - controlPlaneToplogy configv1.TopologyMode - statusPageID string - customProductName string - devCatalogCustomization operatorv1.DeveloperConsoleCatalogCustomization - projectAccess operatorv1.ProjectAccess - quickStarts operatorv1.QuickStarts - addPage operatorv1.AddPage - perspectives []operatorv1.Perspective - CAFile string - monitoring map[string]string - customHostnameRedirectPort int - inactivityTimeoutSeconds int - pluginsList map[string]string - pluginsOrder []string - i18nNamespaceList []string - proxyServices []ProxyService - telemetry map[string]string - releaseVersion string - nodeArchitectures []string - nodeOperatingSystems []string - copiedCSVsDisabled bool - oauthClientID string - oidcExtraScopes []string - oidcIssuerURL string - oidcOCLoginCommand string - authType string - sessionEncryptionFile string - sessionAuthenticationFile string - capabilities []operatorv1.Capability - contentSecurityPolicyList map[v1.DirectiveType][]string - logos []operatorv1.Logo - techPreviewEnabled bool - olmLifecycleMetadataEnabled bool - additionalHosts []string + host string + logoutRedirectURL string + brand operatorv1.Brand + docURL string + apiServerURL string + controlPlaneToplogy configv1.TopologyMode + statusPageID string + customProductName string + devCatalogCustomization operatorv1.DeveloperConsoleCatalogCustomization + projectAccess operatorv1.ProjectAccess + quickStarts operatorv1.QuickStarts + addPage operatorv1.AddPage + perspectives []operatorv1.Perspective + CAFile string + monitoring map[string]string + customHostnameRedirectPort int + inactivityTimeoutSeconds int + pluginsList map[string]string + pluginsOrder []string + i18nNamespaceList []string + proxyServices []ProxyService + telemetry map[string]string + releaseVersion string + nodeArchitectures []string + nodeOperatingSystems []string + copiedCSVsDisabled bool + oauthClientID string + oidcExtraScopes []string + oidcIssuerURL string + oidcOCLoginCommand string + authType string + sessionEncryptionFile string + sessionAuthenticationFile string + previousSessionEncryptionFile string + previousSessionAuthenticationFile string + capabilities []operatorv1.Capability + contentSecurityPolicyList map[v1.DirectiveType][]string + logos []operatorv1.Logo + techPreviewEnabled bool + olmLifecycleMetadataEnabled bool + additionalHosts []string } func (b *ConsoleServerCLIConfigBuilder) Host(host string) *ConsoleServerCLIConfigBuilder { @@ -198,6 +204,10 @@ func (b *ConsoleServerCLIConfigBuilder) AuthConfig(authnConfig *configv1.Authent b.authType = "openshift" b.oauthClientID = api.OAuthClientName b.CAFile = oauthServingCertFilePath + b.sessionAuthenticationFile = sessionAuthKeyFilePath + b.sessionEncryptionFile = sessionEncKeyFilePath + b.previousSessionAuthenticationFile = previousSessionAuthKeyFilePath + b.previousSessionEncryptionFile = previousSessionEncKeyFilePath return b case configv1.AuthenticationTypeOIDC: @@ -217,8 +227,10 @@ func (b *ConsoleServerCLIConfigBuilder) AuthConfig(authnConfig *configv1.Authent b.oauthClientID = oidcConfig.ClientID b.oidcExtraScopes = oidcConfig.ExtraScopes b.oidcOCLoginCommand = authconfigsub.GetOIDCOCLoginCommand(authnConfig, apiServerURL) - b.sessionAuthenticationFile = "/var/session-secret/sessionAuthenticationKey" - b.sessionEncryptionFile = "/var/session-secret/sessionEncryptionKey" + b.sessionAuthenticationFile = sessionAuthKeyFilePath + b.sessionEncryptionFile = sessionEncKeyFilePath + b.previousSessionAuthenticationFile = previousSessionAuthKeyFilePath + b.previousSessionEncryptionFile = previousSessionEncKeyFilePath if len(oidcProvider.Issuer.CertificateAuthority.Name) > 0 { b.CAFile = path.Join(api.AuthServerCAMountDir, api.AuthServerCAFileName) @@ -452,11 +464,31 @@ func (b *ConsoleServerCLIConfigBuilder) auth() Auth { } func (b *ConsoleServerCLIConfigBuilder) session() Session { - conf := Session{ - CookieAuthenticationKeyFile: b.sessionAuthenticationFile, - CookieEncryptionKeyFile: b.sessionEncryptionFile, + if b.authType == "disabled" { + return Session{} + } + authFile := b.sessionAuthenticationFile + encFile := b.sessionEncryptionFile + if authFile == "" { + authFile = sessionAuthKeyFilePath + } + if encFile == "" { + encFile = sessionEncKeyFilePath + } + prevAuthFile := b.previousSessionAuthenticationFile + prevEncFile := b.previousSessionEncryptionFile + if prevAuthFile == "" { + prevAuthFile = previousSessionAuthKeyFilePath + } + if prevEncFile == "" { + prevEncFile = previousSessionEncKeyFilePath + } + return Session{ + CookieAuthenticationKeyFile: authFile, + CookieEncryptionKeyFile: encFile, + PreviousCookieAuthenticationKeyFile: prevAuthFile, + PreviousCookieEncryptionKeyFile: prevEncFile, } - return conf } func (b *ConsoleServerCLIConfigBuilder) customization() Customization { diff --git a/pkg/console/subresource/consoleserver/config_builder_test.go b/pkg/console/subresource/consoleserver/config_builder_test.go index 509168eac7..2bffde1628 100644 --- a/pkg/console/subresource/consoleserver/config_builder_test.go +++ b/pkg/console/subresource/consoleserver/config_builder_test.go @@ -71,6 +71,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ { @@ -103,6 +109,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ { @@ -146,6 +158,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Capabilities: []v1.Capability{ { @@ -196,6 +214,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { OAuthEndpointCAFile: "/var/oauth-serving-cert/ca-bundle.crt", LogoutRedirect: "https://foobar.com/logout", }, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ @@ -257,8 +281,10 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { LogoutRedirect: "https://foobar.com/logout", }, Session: Session{ - CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", - CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", }, Customization: Customization{ Perspectives: []Perspective{ @@ -346,6 +372,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ { @@ -381,6 +413,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ { @@ -416,7 +454,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, - Session: Session{}, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ DeveloperCatalog: &DeveloperConsoleCatalogCustomization{ Categories: &[]DeveloperConsoleCatalogCategory{}, @@ -476,7 +519,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, - Session: Session{}, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ { @@ -536,7 +584,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, - Session: Session{}, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ DeveloperCatalog: &DeveloperConsoleCatalogCustomization{ Categories: nil, @@ -576,7 +629,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, - Session: Session{}, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ DeveloperCatalog: &DeveloperConsoleCatalogCustomization{ Categories: nil, @@ -616,7 +674,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, - Session: Session{}, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ ProjectAccess: ProjectAccess{ AvailableClusterRoles: []string{"View", "Edit", "Admin"}, @@ -655,7 +718,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, - Session: Session{}, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ QuickStarts: QuickStarts{ Disabled: []string{"quick-start0", "quick-start1", "quick-start2"}, @@ -708,7 +776,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, - Session: Session{}, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ { @@ -773,7 +846,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, - Session: Session{}, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ {ID: "perspective1", @@ -837,7 +915,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, - Session: Session{}, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ {ID: "perspective1", @@ -894,7 +977,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientSecretFile: clientSecretFilePath, LogoutRedirect: "https://foobar.com/logout", }, - Session: Session{}, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Branding: "okd", DocumentationBaseURL: "https://foobar.com/docs", @@ -948,7 +1036,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, - Session: Session{}, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ { @@ -989,6 +1082,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ { @@ -1030,6 +1129,12 @@ func TestConsoleServerCLIConfigBuilder(t *testing.T) { ClientID: api.OpenShiftConsoleName, ClientSecretFile: clientSecretFilePath, }, + Session: Session{ + CookieEncryptionKeyFile: "/var/session-secret/sessionEncryptionKey", + CookieAuthenticationKeyFile: "/var/session-secret/sessionAuthenticationKey", + PreviousCookieEncryptionKeyFile: "/var/session-secret/previousSessionEncryptionKey", + PreviousCookieAuthenticationKeyFile: "/var/session-secret/previousSessionAuthenticationKey", + }, Customization: Customization{ Perspectives: []Perspective{ { @@ -1083,7 +1188,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: perspectives: - id: dev @@ -1132,6 +1241,8 @@ auth: session: cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: perspectives: - id: dev @@ -1166,7 +1277,11 @@ auth: clientSecretFile: /var/oauth-config/clientSecret oauthEndpointCAFile: /var/oauth-serving-cert/ca-bundle.crt logoutRedirect: https://foobar.com/logout -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: perspectives: - id: dev @@ -1191,7 +1306,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: perspectives: - id: dev @@ -1218,7 +1337,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: perspectives: - id: dev @@ -1246,7 +1369,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: developerCatalog: categories: [] @@ -1298,7 +1425,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: developerCatalog: categories: @@ -1342,7 +1473,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: developerCatalog: categories: null @@ -1377,7 +1512,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: developerCatalog: categories: null @@ -1413,7 +1552,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: addPage: disabledActions: @@ -1498,7 +1641,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: quickStarts: disabled: @@ -1544,7 +1691,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: perspectives: - id: perspective1 @@ -1614,7 +1765,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: perspectives: - id: perspective1 @@ -1688,7 +1843,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: perspectives: - id: perspective1 @@ -1742,7 +1901,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: perspectives: - id: dev @@ -1778,7 +1941,11 @@ clusterInfo: {} auth: clientID: console clientSecretFile: /var/oauth-config/clientSecret -session: {} +session: + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey customization: perspectives: - id: dev diff --git a/pkg/console/subresource/consoleserver/config_merger_test.go b/pkg/console/subresource/consoleserver/config_merger_test.go index 5669e8a2e7..439bf2afc4 100644 --- a/pkg/console/subresource/consoleserver/config_merger_test.go +++ b/pkg/console/subresource/consoleserver/config_merger_test.go @@ -61,7 +61,11 @@ servingInfo: bindAddress: https://[::]:8443 certFile: /var/serving-cert/tls.crt keyFile: /var/serving-cert/tls.key -session: {} +session: + cookieAuthenticationKeyFile: /var/session-secret/sessionAuthenticationKey + cookieEncryptionKeyFile: /var/session-secret/sessionEncryptionKey + previousCookieAuthenticationKeyFile: /var/session-secret/previousSessionAuthenticationKey + previousCookieEncryptionKeyFile: /var/session-secret/previousSessionEncryptionKey `, }, } diff --git a/pkg/console/subresource/consoleserver/types.go b/pkg/console/subresource/consoleserver/types.go index 52752ea708..be7f4909fd 100644 --- a/pkg/console/subresource/consoleserver/types.go +++ b/pkg/console/subresource/consoleserver/types.go @@ -100,8 +100,10 @@ type Auth struct { // Session holds configuration for web-session related configuration type Session struct { - CookieEncryptionKeyFile string `yaml:"cookieEncryptionKeyFile,omitempty"` - CookieAuthenticationKeyFile string `yaml:"cookieAuthenticationKeyFile,omitempty"` + CookieEncryptionKeyFile string `yaml:"cookieEncryptionKeyFile,omitempty"` + CookieAuthenticationKeyFile string `yaml:"cookieAuthenticationKeyFile,omitempty"` + PreviousCookieEncryptionKeyFile string `yaml:"previousCookieEncryptionKeyFile,omitempty"` + PreviousCookieAuthenticationKeyFile string `yaml:"previousCookieAuthenticationKeyFile,omitempty"` // TODO: move InactivityTimeoutSeconds here } diff --git a/pkg/console/subresource/secret/session_secret.go b/pkg/console/subresource/secret/session_secret.go index 0e941b2f97..225e910be2 100644 --- a/pkg/console/subresource/secret/session_secret.go +++ b/pkg/console/subresource/secret/session_secret.go @@ -38,11 +38,20 @@ func ResetSessionSecretKeysIfNeeded(secret *corev1.Secret) bool { } if len(secret.Data["sessionEncryptionKey"]) != aes256KeyLenBytes { + // Preserve the current key as the previous key for graceful rotation, + // so that existing sessions can still be decrypted during the transition. + if len(secret.Data["sessionEncryptionKey"]) > 0 { + secret.Data["previousSessionEncryptionKey"] = secret.Data["sessionEncryptionKey"] + } secret.Data["sessionEncryptionKey"] = []byte(randomString(aes256KeyLenBytes)) changed = true } if len(secret.Data["sessionAuthenticationKey"]) != sha256KeyLenBytes { + // Preserve the current key as the previous key for graceful rotation. + if len(secret.Data["sessionAuthenticationKey"]) > 0 { + secret.Data["previousSessionAuthenticationKey"] = secret.Data["sessionAuthenticationKey"] + } secret.Data["sessionAuthenticationKey"] = []byte(randomString(sha256KeyLenBytes)) changed = true }