diff --git a/catalog-rest-service/pom.xml b/catalog-rest-service/pom.xml index 920ee44ab86..92094719a27 100644 --- a/catalog-rest-service/pom.xml +++ b/catalog-rest-service/pom.xml @@ -390,6 +390,21 @@ org.jeasy easy-rules-core + + io.socket + socket.io-server + 4.0.1 + + + io.socket + engine.io-server-jetty + 6.2.1 + + + org.eclipse.jetty.websocket + websocket-server + 9.4.46.v20220331 + diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java index 131617be50c..a80b48ae193 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java @@ -32,6 +32,8 @@ import io.federecio.dropwizard.swagger.SwaggerBundleConfiguration; import io.github.maksymdolgykh.dropwizard.micrometer.MicrometerBundle; import io.github.maksymdolgykh.dropwizard.micrometer.MicrometerHttpFilter; import io.github.maksymdolgykh.dropwizard.micrometer.MicrometerJdbiTimingCollector; +import io.socket.engineio.server.EngineIoServerOptions; +import io.socket.engineio.server.JettyWebSocketHandler; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.time.temporal.ChronoUnit; @@ -39,13 +41,18 @@ import java.util.EnumSet; import java.util.Optional; import javax.servlet.DispatcherType; import javax.servlet.FilterRegistration; +import javax.servlet.ServletException; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.core.Response; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.eclipse.jetty.http.pathmap.ServletPathSpec; import org.eclipse.jetty.servlet.ErrorPageErrorHandler; +import org.eclipse.jetty.servlet.FilterHolder; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter; import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.server.ServerProperties; import org.jdbi.v3.core.Jdbi; @@ -74,12 +81,17 @@ import org.openmetadata.catalog.security.policyevaluator.PolicyEvaluator; import org.openmetadata.catalog.security.policyevaluator.RoleEvaluator; import org.openmetadata.catalog.slack.SlackPublisherConfiguration; import org.openmetadata.catalog.slack.SlackWebhookEventPublisher; +import org.openmetadata.catalog.socket.FeedServlet; +import org.openmetadata.catalog.socket.SocketAddressFilter; +import org.openmetadata.catalog.socket.WebSocketManager; /** Main catalog application */ @Slf4j public class CatalogApplication extends Application { private Authorizer authorizer; + private SocketAddressFilter socketAddressFilter = null; + @Override public void run(CatalogApplicationConfig catalogConfig, Environment environment) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, @@ -151,6 +163,7 @@ public class CatalogApplication extends Application { FilterRegistration.Dynamic micrometerFilter = environment.servlets().addFilter("MicrometerHttpFilter", new MicrometerHttpFilter()); micrometerFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*"); + intializeWebsockets(environment); } @SneakyThrows @@ -201,7 +214,11 @@ public class CatalogApplication extends Application { InstantiationException { AuthorizerConfiguration authorizerConf = catalogConfig.getAuthorizerConfiguration(); AuthenticationConfiguration authenticationConfiguration = catalogConfig.getAuthenticationConfiguration(); + // to authenticate request while opening websocket connections if (authorizerConf != null) { + if (authorizerConf.getEnableSecureSocketConnection()) { + socketAddressFilter = new SocketAddressFilter(authenticationConfiguration, authorizerConf); + } authorizer = Class.forName(authorizerConf.getClassName()).asSubclass(Authorizer.class).getConstructor().newInstance(); String filterClazzName = authorizerConf.getContainerRequestFilter(); @@ -261,6 +278,29 @@ public class CatalogApplication extends Application { environment.getApplicationContext().setErrorHandler(eph); } + private void intializeWebsockets(Environment environment) { + EngineIoServerOptions eioOptions = EngineIoServerOptions.newFromDefault(); + eioOptions.setAllowedCorsOrigins(null); + WebSocketManager.WebSocketManagerBuilder.build(eioOptions); + environment.getApplicationContext().setContextPath("/"); + if (socketAddressFilter != null) + environment + .getApplicationContext() + .addFilter(new FilterHolder(socketAddressFilter), "/api/v1/push/feed/*", EnumSet.of(DispatcherType.REQUEST)); + environment.getApplicationContext().addServlet(new ServletHolder(new FeedServlet()), "/api/v1/push/feed/*"); + // Upgrade connection to websocket from Http + try { + WebSocketUpgradeFilter webSocketUpgradeFilter = + WebSocketUpgradeFilter.configureContext(environment.getApplicationContext()); + webSocketUpgradeFilter.addMapping( + new ServletPathSpec("/api/v1/push/feed/*"), + (servletUpgradeRequest, servletUpgradeResponse) -> + new JettyWebSocketHandler(WebSocketManager.getInstance().getEngineIoServer())); + } catch (ServletException ex) { + LOG.error("Websocket Upgrade Filter error : ", ex.getMessage()); + } + } + public static void main(String[] args) throws Exception { CatalogApplication catalogApplication = new CatalogApplication(); catalogApplication.run(args); diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/events/ChangeEventHandler.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/events/ChangeEventHandler.java index 6831db26314..328f0b1c72b 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/events/ChangeEventHandler.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/events/ChangeEventHandler.java @@ -18,6 +18,7 @@ import static org.openmetadata.catalog.type.EventType.ENTITY_SOFT_DELETED; import static org.openmetadata.catalog.type.EventType.ENTITY_UPDATED; import static org.openmetadata.common.utils.CommonUtil.listOrEmpty; +import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -36,6 +37,7 @@ import org.openmetadata.catalog.entity.feed.Thread; import org.openmetadata.catalog.jdbi3.CollectionDAO; import org.openmetadata.catalog.jdbi3.FeedRepository; import org.openmetadata.catalog.resources.feeds.MessageParser.EntityLink; +import org.openmetadata.catalog.socket.WebSocketManager; import org.openmetadata.catalog.type.ChangeDescription; import org.openmetadata.catalog.type.ChangeEvent; import org.openmetadata.catalog.type.EntityReference; @@ -48,10 +50,12 @@ import org.openmetadata.catalog.util.RestUtil; public class ChangeEventHandler implements EventHandler { private CollectionDAO dao; private FeedRepository feedDao; + private ObjectMapper mapper; public void init(CatalogApplicationConfig config, Jdbi jdbi) { this.dao = jdbi.onDemand(CollectionDAO.class); this.feedDao = new FeedRepository(dao); + this.mapper = new ObjectMapper(); } public Void process(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { @@ -100,6 +104,8 @@ public class ChangeEventHandler implements EventHandler { } EntityLink about = EntityLink.parse(thread.getAbout()); feedDao.create(thread, entity.getId(), owner, about); + String json = mapper.writeValueAsString(thread); + WebSocketManager.getInstance().broadCastMessageToClients(json); } } } diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthorizerConfiguration.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthorizerConfiguration.java index 25b61b73c4f..0492f72924d 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthorizerConfiguration.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthorizerConfiguration.java @@ -25,6 +25,7 @@ public class AuthorizerConfiguration { @NotEmpty @Getter @Setter private Set botPrincipals; @NotEmpty @Getter @Setter private String principalDomain; @NotEmpty @Getter @Setter private Boolean enforcePrincipalDomain; + @NotEmpty @Getter @Setter private Boolean enableSecureSocketConnection; @Override public String toString() { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/JwtFilter.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/JwtFilter.java index 9f1918023f3..80b828adb1b 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/JwtFilter.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/JwtFilter.java @@ -56,7 +56,6 @@ public class JwtFilter implements ContainerRequestFilter { public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String TOKEN_PREFIX = "Bearer"; public static final String BOT_CLAIM = "isBot"; - private List jwtPrincipalClaims; private JwkProvider jwkProvider; private String principalDomain; @@ -104,10 +103,33 @@ public class JwtFilter implements ContainerRequestFilter { String tokenFromHeader = extractToken(headers); LOG.debug("Token from header:{}", tokenFromHeader); + DecodedJWT jwt = validateAndReturnDecodedJwtToken(tokenFromHeader); + + Map claims = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + claims.putAll(jwt.getClaims()); + + String userName = validateAndReturnUsername(claims); + + // validate bot token + if (claims.containsKey(BOT_CLAIM) && claims.get(BOT_CLAIM).asBoolean()) { + validateBotToken(tokenFromHeader, userName); + } + + // Setting Security Context + CatalogPrincipal catalogPrincipal = new CatalogPrincipal(userName); + String scheme = requestContext.getUriInfo().getRequestUri().getScheme(); + CatalogSecurityContext catalogSecurityContext = + new CatalogSecurityContext(catalogPrincipal, scheme, SecurityContext.DIGEST_AUTH); + LOG.debug("SecurityContext {}", catalogSecurityContext); + requestContext.setSecurityContext(catalogSecurityContext); + } + + @SneakyThrows + public DecodedJWT validateAndReturnDecodedJwtToken(String token) { // Decode JWT Token DecodedJWT jwt; try { - jwt = JWT.decode(tokenFromHeader); + jwt = JWT.decode(token); } catch (JWTDecodeException e) { throw new AuthenticationException("Invalid token", e); } @@ -127,10 +149,12 @@ public class JwtFilter implements ContainerRequestFilter { } catch (RuntimeException runtimeException) { throw new AuthenticationException("Invalid token"); } + return jwt; + } + @SneakyThrows + public String validateAndReturnUsername(Map claims) { // Get username from JWT token - Map claims = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - claims.putAll(jwt.getClaims()); String jwtClaim = jwtPrincipalClaims.stream() .filter(claims::containsKey) @@ -141,6 +165,7 @@ public class JwtFilter implements ContainerRequestFilter { () -> new AuthenticationException( "Invalid JWT token, none of the following claims are present " + jwtPrincipalClaims)); + String userName; String domain; if (jwtClaim.contains("@")) { @@ -158,18 +183,7 @@ public class JwtFilter implements ContainerRequestFilter { String.format("Not Authorized! Email does not match the principal domain %s", principalDomain)); } } - - // validate bot token - if (claims.containsKey(BOT_CLAIM) && claims.get(BOT_CLAIM).asBoolean()) { - validateBotToken(tokenFromHeader, userName); - } - // Setting Security Context - CatalogPrincipal catalogPrincipal = new CatalogPrincipal(userName); - String scheme = requestContext.getUriInfo().getRequestUri().getScheme(); - CatalogSecurityContext catalogSecurityContext = - new CatalogSecurityContext(catalogPrincipal, scheme, SecurityContext.DIGEST_AUTH); - LOG.debug("SecurityContext {}", catalogSecurityContext); - requestContext.setSecurityContext(catalogSecurityContext); + return userName; } protected static String extractToken(MultivaluedMap headers) { @@ -185,6 +199,18 @@ public class JwtFilter implements ContainerRequestFilter { throw new AuthenticationException("Not Authorized! Token not present"); } + public static String extractToken(String tokenFromHeader) { + LOG.debug("Request Token:{}", tokenFromHeader); + if (Strings.isNullOrEmpty(tokenFromHeader)) { + throw new AuthenticationException("Not Authorized! Token not present"); + } + // Extract the bearer token + if (tokenFromHeader.startsWith(TOKEN_PREFIX)) { + return tokenFromHeader.substring(TOKEN_PREFIX.length() + 1); + } + throw new AuthenticationException("Not Authorized! Token not present"); + } + private void validateBotToken(String tokenFromHeader, String userName) throws IOException { EntityRepository userRepository = Entity.getEntityRepository(Entity.USER); User user = userRepository.getByName(null, userName, new EntityUtil.Fields(List.of("authenticationMechanism"))); diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/FeedServlet.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/FeedServlet.java new file mode 100644 index 00000000000..3428abbc201 --- /dev/null +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/FeedServlet.java @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Collate + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openmetadata.catalog.socket; + +import java.io.IOException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/api/v1/push/feed/*") +public class FeedServlet extends HttpServlet { + public FeedServlet() {} + + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { + WebSocketManager.getInstance() + .getEngineIoServer() + .handleRequest( + new HttpServletRequestWrapper(request) { + @Override + public boolean isAsyncSupported() { + return true; + } + }, + response); + } +} diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/HeaderRequestWrapper.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/HeaderRequestWrapper.java new file mode 100644 index 00000000000..62f1e217392 --- /dev/null +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/HeaderRequestWrapper.java @@ -0,0 +1,60 @@ +/* + * Copyright 2021 Collate + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openmetadata.catalog.socket; + +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +public class HeaderRequestWrapper extends HttpServletRequestWrapper { + + public HeaderRequestWrapper(HttpServletRequest request) { + super(request); + } + + private Map headerMap = new HashMap<>(); + + public void addHeader(String name, String value) { + headerMap.put(name, value); + } + + @Override + public String getHeader(String name) { + String headerValue = super.getHeader(name); + if (headerMap.containsKey(name)) { + headerValue = headerMap.get(name); + } + return headerValue; + } + + @Override + public Enumeration getHeaderNames() { + List names = Collections.list(super.getHeaderNames()); + names.addAll(headerMap.keySet()); + return Collections.enumeration(names); + } + + @Override + public Enumeration getHeaders(String name) { + List values = Collections.list(super.getHeaders(name)); + if (headerMap.containsKey(name)) { + values.add(headerMap.get(name)); + } + return Collections.enumeration(values); + } +} diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/SocketAddressFilter.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/SocketAddressFilter.java new file mode 100644 index 00000000000..352d4dfe2d1 --- /dev/null +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/SocketAddressFilter.java @@ -0,0 +1,69 @@ +/* + * Copyright 2021 Collate + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openmetadata.catalog.socket; + +import com.auth0.jwt.interfaces.Claim; +import com.auth0.jwt.interfaces.DecodedJWT; +import java.io.IOException; +import java.util.Map; +import java.util.TreeMap; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import org.openmetadata.catalog.security.AuthenticationConfiguration; +import org.openmetadata.catalog.security.AuthorizerConfiguration; +import org.openmetadata.catalog.security.JwtFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SocketAddressFilter implements Filter { + private static final Logger LOG = LoggerFactory.getLogger(SocketAddressFilter.class); + private JwtFilter jwtFilter; + + public SocketAddressFilter( + AuthenticationConfiguration authenticationConfiguration, AuthorizerConfiguration authorizerConf) { + jwtFilter = new JwtFilter(authenticationConfiguration, authorizerConf); + } + + @Override + public void destroy() {} + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + String tokenWithType = httpServletRequest.getHeader("Authorization"); + + HeaderRequestWrapper requestWrapper = new HeaderRequestWrapper(httpServletRequest); + requestWrapper.addHeader("RemoteAddress", request.getRemoteAddr()); + requestWrapper.addHeader("Authorization", tokenWithType); + + String token = JwtFilter.extractToken(tokenWithType); + // validate token + DecodedJWT jwt = jwtFilter.validateAndReturnDecodedJwtToken(token); + // validate Domain and Username + Map claims = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + claims.putAll(jwt.getClaims()); + jwtFilter.validateAndReturnUsername(claims); + // Goes to default servlet. + chain.doFilter(requestWrapper, response); + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException {} +} diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/WebSocketManager.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/WebSocketManager.java new file mode 100644 index 00000000000..4dd260e6e9d --- /dev/null +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/socket/WebSocketManager.java @@ -0,0 +1,71 @@ +package org.openmetadata.catalog.socket; + +import io.socket.engineio.server.EngineIoServer; +import io.socket.engineio.server.EngineIoServerOptions; +import io.socket.socketio.server.SocketIoNamespace; +import io.socket.socketio.server.SocketIoServer; +import io.socket.socketio.server.SocketIoSocket; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WebSocketManager { + private static final Logger LOG = LoggerFactory.getLogger(WebSocketManager.class); + private static WebSocketManager INSTANCE; + private final EngineIoServer mEngineIoServer; + private final SocketIoServer mSocketIoServer; + private final String feedBroadcastChannel = "activityFeed"; + private final Map activityFeedEndpoints = new ConcurrentHashMap<>(); + + private WebSocketManager(EngineIoServerOptions eiOptions) { + mEngineIoServer = new EngineIoServer(eiOptions); + mSocketIoServer = new SocketIoServer(mEngineIoServer); + intilizateHandlers(); + } + + private void intilizateHandlers() { + SocketIoNamespace ns = mSocketIoServer.namespace("/"); + // On Connection + ns.on( + "connection", + args -> { + SocketIoSocket socket = (SocketIoSocket) args[0]; + LOG.info( + "Client :" + + socket.getId() + + "with Remote Address :" + + socket.getInitialHeaders().get("RemoteAddress") + + "connected."); + activityFeedEndpoints.put(socket.getId(), socket); + }); + } + + public static WebSocketManager getInstance() { + return INSTANCE; + } + + public SocketIoServer getSocketIoServer() { + return mSocketIoServer; + } + + public EngineIoServer getEngineIoServer() { + return mEngineIoServer; + } + + public Map getActivityFeedEndpoints() { + return activityFeedEndpoints; + } + + public void broadCastMessageToClients(String message) { + for (Map.Entry endpoints : activityFeedEndpoints.entrySet()) { + endpoints.getValue().send(feedBroadcastChannel, message); + } + } + + public static class WebSocketManagerBuilder { + public static void build(EngineIoServerOptions eiOptions) { + INSTANCE = new WebSocketManager(eiOptions); + } + } +} diff --git a/catalog-rest-service/src/test/resources/openmetadata-secure-test.yaml b/catalog-rest-service/src/test/resources/openmetadata-secure-test.yaml index 5038292a1d8..b6284da3633 100644 --- a/catalog-rest-service/src/test/resources/openmetadata-secure-test.yaml +++ b/catalog-rest-service/src/test/resources/openmetadata-secure-test.yaml @@ -129,6 +129,8 @@ authorizerConfiguration: botPrincipals: - "ingestion-bot" principalDomain: "open-metadata.org" + enforcePrincipalDomain: false + enableSecureSocketConnection: false authenticationConfiguration: provider: "openID" diff --git a/conf/openmetadata.yaml b/conf/openmetadata.yaml index 906973ead23..91de4a51df3 100644 --- a/conf/openmetadata.yaml +++ b/conf/openmetadata.yaml @@ -133,6 +133,7 @@ authorizerConfiguration: botPrincipals: ${AUTHORIZER_INGESTION_PRINCIPALS:-[ingestion-bot]} principalDomain: ${AUTHORIZER_PRINCIPAL_DOMAIN:-"openmetadata.org"} enforcePrincipalDomain: ${AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN:-false} + enableSecureSocketConnection : ${AUTHORIZER_ENABLE_SECURE_SOCKET:-false} authenticationConfiguration: provider: ${AUTHENTICATION_PROVIDER:-no-auth} diff --git a/docker/local-metadata/docker-compose.yml b/docker/local-metadata/docker-compose.yml index 93539736364..4527fc39422 100644 --- a/docker/local-metadata/docker-compose.yml +++ b/docker/local-metadata/docker-compose.yml @@ -65,6 +65,7 @@ services: AUTHORIZER_INGESTION_PRINCIPALS: ${AUTHORIZER_INGESTION_PRINCIPALS:-[ingestion-bot]} AUTHORIZER_PRINCIPAL_DOMAIN: ${AUTHORIZER_PRINCIPAL_DOMAIN:-""} AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN: ${AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN:-false} + AUTHORIZER_ENABLE_SECURE_SOCKET: ${AUTHORIZER_ENABLE_SECURE_SOCKET:-false} AUTHENTICATION_PROVIDER: ${AUTHENTICATION_PROVIDER:-no-auth} CUSTOM_OIDC_AUTHENTICATION_PROVIDER_NAME: ${CUSTOM_OIDC_AUTHENTICATION_PROVIDER_NAME:-""} AUTHENTICATION_PUBLIC_KEYS: ${AUTHENTICATION_PUBLIC_KEY:-[https://www.googleapis.com/oauth2/v3/certs]} diff --git a/docker/metadata/docker-compose.yml b/docker/metadata/docker-compose.yml index 4e16de01798..e4e0432cd16 100644 --- a/docker/metadata/docker-compose.yml +++ b/docker/metadata/docker-compose.yml @@ -54,6 +54,7 @@ services: AUTHORIZER_INGESTION_PRINCIPALS: ${AUTHORIZER_INGESTION_PRINCIPAL:-[ingestion-bot]} AUTHORIZER_PRINCIPAL_DOMAIN: ${AUTHORIZER_PRINCIPAL_DOMAIN:-""} AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN: ${AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN:-false} + AUTHORIZER_ENABLE_SECURE_SOCKET: ${AUTHORIZER_ENABLE_SECURE_SOCKET:-false} AUTHENTICATION_PROVIDER: ${AUTHENTICATION_PROVIDER:-no-auth} CUSTOM_OIDC_AUTHENTICATION_PROVIDER_NAME: ${CUSTOM_OIDC_AUTHENTICATION_PROVIDER_NAME:-""} AUTHENTICATION_PUBLIC_KEYS: ${AUTHENTICATION_PUBLIC_KEY:-[https://www.googleapis.com/oauth2/v3/certs]}