diff --git a/devops/azure/chart/templates/virtual-service.yaml b/devops/azure/chart/templates/virtual-service.yaml
index 93a8d8af9b645f3db447b8c15cab1a7e149e3f22..e92dcbfecec763ad67e2a3043d802e18450c75dc 100644
--- a/devops/azure/chart/templates/virtual-service.yaml
+++ b/devops/azure/chart/templates/virtual-service.yaml
@@ -12,7 +12,75 @@ spec:
   gateways:
   - istio-gateway
   http:  
-  - match:
+  - name: "Settings specific to the Swagger page and resources"
+    match:
+    - uri:
+        prefix: "/api/indexer/v2/webjars"
+    - uri:
+        prefix: "/api/indexer/v2/swagger-resources"
+    - uri:
+        prefix: "/api/indexer/v2/v3/api-docs"
+    - uri:
+        prefix: "/api/indexer/v2/swagger-ui"
+    route:
+    - destination:
+        host: {{ .Chart.Name }}
+        port:
+          number: 80
+    headers:
+      response:
+        set:
+          cache-control: "private, max-age=300"
+    corsPolicy:
+      maxAge: "60m"
+      allowCredentials: true
+      allowHeaders:
+      - Authorization
+      - Data-Partition-Id
+      - Correlation-Id
+      - Content-Type
+      - cache-control
+      allowMethods:
+      - POST
+      - GET
+      - PUT
+      - PATCH
+      - DELETE
+      allowOrigins:
+      - prefix: "*"
+  - name: "Settings specific to the QueryAttributeApi API"
+    match:
+    - uri:
+        prefix: "/api/indexer/v2/query/attributes"
+    route:
+    - destination:
+        host: {{ .Chart.Name }}
+        port:
+          number: 80
+    headers:
+      response:
+        set:
+          cache-control: "private, max-age=300, stale-while-revalidate=600, stale-if-error=600"
+          vary: "data-partition-id,authorization"
+    corsPolicy:
+      maxAge: "60m"
+      allowCredentials: true
+      allowHeaders:
+      - Authorization
+      - Data-Partition-Id
+      - Correlation-Id
+      - Content-Type
+      - cache-control
+      allowMethods:
+      - POST
+      - GET
+      - PUT
+      - PATCH
+      - DELETE
+      allowOrigins:
+      - prefix: "*"
+  - name: "Default settings, applies to everything not matched above"
+    match:
     - uri:
         prefix: "/api/indexer/v2"
     route:
@@ -28,6 +96,7 @@ spec:
       - Data-Partition-Id
       - Correlation-Id
       - Content-Type
+      - cache-control
       allowMethods:
       - POST
       - GET
diff --git a/devops/azure/release.yaml b/devops/azure/release.yaml
index dad51b35bebd9069044ac08b8848245a29165fb7..4c05dc09debd79320954f0a22354f5bf91be8a80 100644
--- a/devops/azure/release.yaml
+++ b/devops/azure/release.yaml
@@ -74,7 +74,7 @@ spec:
         - containerPort: 80
         readinessProbe:
           httpGet:
-            path: /api/indexer/v2/swagger-ui.html
+            path: /api/indexer/v2/swagger-ui/index.html
             port: 80
         volumeMounts:
         - name: azure-keyvault
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/IndexerFilter.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/IndexerFilter.java
index 633179c426acd8ed830568b1926821b9c0e77b7d..ff03bc6b473bd4d04d13c77fc356be119ad2c110 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/IndexerFilter.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/IndexerFilter.java
@@ -2,6 +2,7 @@
 package org.opengroup.osdu.indexer.util;
 
 import java.io.IOException;
+import java.util.Map;
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -10,8 +11,10 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletResponse;
 import lombok.extern.java.Log;
+import org.opengroup.osdu.core.common.http.ResponseHeadersFactory;
 import org.opengroup.osdu.core.common.model.http.DpsHeaders;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 @Log
@@ -19,6 +22,11 @@ import org.springframework.stereotype.Component;
 public class IndexerFilter implements Filter {
 
     private final DpsHeaders dpsHeaders;
+    private ResponseHeadersFactory responseHeadersFactory = new ResponseHeadersFactory();
+
+    // defaults to * for any front-end, string must be comma-delimited if more than one domain
+    @Value("${ACCESS_CONTROL_ALLOW_ORIGIN_DOMAINS:*}")
+    String ACCESS_CONTROL_ALLOW_ORIGIN_DOMAINS;
 
     @Autowired
     public IndexerFilter(DpsHeaders dpsHeaders) {
@@ -37,11 +45,20 @@ public class IndexerFilter implements Filter {
         HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
 
         dpsHeaders.addCorrelationIdIfMissing();
-        httpResponse.addHeader(DpsHeaders.CORRELATION_ID, dpsHeaders.getCorrelationId());
+
+        setResponseHeaders(httpResponse);
 
         filterChain.doFilter(servletRequest, servletResponse);
     }
 
+    private void setResponseHeaders(HttpServletResponse httpServletResponse) {
+        Map<String, String> responseHeaders = responseHeadersFactory.getResponseHeaders(ACCESS_CONTROL_ALLOW_ORIGIN_DOMAINS);
+        for (Map.Entry<String, String> header : responseHeaders.entrySet()) {
+            httpServletResponse.addHeader(header.getKey(), header.getValue());
+        }
+        httpServletResponse.addHeader(DpsHeaders.CORRELATION_ID, this.dpsHeaders.getCorrelationId());
+    }
+
     @Override
     public void destroy() {
     }
diff --git a/provider/indexer-azure/README.md b/provider/indexer-azure/README.md
index 9f120e4504136755a842219c45d2b80138e6d007..9b8842fbbbac2f3fc449c23ef8967c28e3ad5569 100644
--- a/provider/indexer-azure/README.md
+++ b/provider/indexer-azure/README.md
@@ -118,7 +118,7 @@ $ mvn spring-boot:run
 
 ### Test the application
 
-After the service has started it should be accessible via a web browser by visiting [http://localhost:8080/swagger-ui.html](http://localhost:8080/swagger-ui.html). If the request does not fail, you can then run the integration tests.
+After the service has started it should be accessible via a web browser by visiting [http://localhost:8080/swagger-ui/index.html](http://localhost:8080/swagger-ui/index.html). If the request does not fail, you can then run the integration tests.
 
 > **Note**: the integration tests for `os-indexer-azure` work by validating that records submitted to `os-storage-azure` can eventually be queried by `os-search-azure`. This only works if the messages emitted by `os-storage-azure` can be consumed by `os-indexer-queue-azure`, which will submit the indexing request to `os-indexer-azure`.
 >
diff --git a/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/security/AADSecurityConfig.java b/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/security/AADSecurityConfig.java
index fd1150ce646395d0c0029a812fd643f056fbe2ef..a1261867617574a2ae0ea39f9648998e1db880e8 100644
--- a/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/security/AADSecurityConfig.java
+++ b/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/security/AADSecurityConfig.java
@@ -46,7 +46,7 @@ public class AADSecurityConfig extends WebSecurityConfigurerAdapter {
                         "/configuration/security",
                         "/swagger",
                         "/info",
-                        "/swagger-ui.html",
+                        "/swagger-ui/index.html",
                         "/swagger-ui/**",
                         "/webjars/**").permitAll()
                 .anyRequest().authenticated()