diff --git a/docs/TheBook/src/main/markdown/config-frontend.md b/docs/TheBook/src/main/markdown/config-frontend.md
index fef13cfa59b..9bb01f1c961 100644
--- a/docs/TheBook/src/main/markdown/config-frontend.md
+++ b/docs/TheBook/src/main/markdown/config-frontend.md
@@ -41,6 +41,25 @@ The service can be run out-of-the-box without changing default property
values. There are a few properties affecting the admin/monitoring components
which should, however, be noted.
+## Allowing third-party web applications to call the REST API
+
+By default, the REST API can only be called from JavaScript served by the
+same origin as the dCache Frontend. This prevents unauthorised websites from
+making requests on behalf of a logged-in user. If you run a web application
+the browser loads from a different origin — for example a data catalogue or a
+dashboard — you can allow that origin to call the REST API by listing it in
+`frontend.allowed.client.origins`.
+
+```ini
+[frontendDomain/frontend]
+frontend.allowed.client.origins = https://catalogue.example.org, https://dashboard.example.org
+```
+
+Values are a comma-separated list of website origins (scheme, host and port
+if non-default) *without* any path. If the list is empty, no website is
+authorised. Non-JavaScript clients (for example `curl`) are unaffected by
+this property.
+
## Properties controlling monitoring data collection
The number of threads which are available to collect data from
diff --git a/modules/dcache-frontend/src/main/resources/org/dcache/frontend/frontend.xml b/modules/dcache-frontend/src/main/resources/org/dcache/frontend/frontend.xml
index e4ef27a5931..99a2fc1c04d 100644
--- a/modules/dcache-frontend/src/main/resources/org/dcache/frontend/frontend.xml
+++ b/modules/dcache-frontend/src/main/resources/org/dcache/frontend/frontend.xml
@@ -409,6 +409,9 @@
+
+
+
Provide access to dcache-view
diff --git a/modules/dcache-webdav/src/main/resources/org/dcache/webdav/webdav.xml b/modules/dcache-webdav/src/main/resources/org/dcache/webdav/webdav.xml
index 48f1a4c2b52..8fb0f54cbdb 100644
--- a/modules/dcache-webdav/src/main/resources/org/dcache/webdav/webdav.xml
+++ b/modules/dcache-webdav/src/main/resources/org/dcache/webdav/webdav.xml
@@ -316,7 +316,7 @@
-
+
diff --git a/modules/dcache-webdav/src/main/java/org/dcache/webdav/CrossOriginResourceSharingHandler.java b/modules/dcache/src/main/java/org/dcache/util/jetty/CrossOriginResourceSharingHandler.java
similarity index 99%
rename from modules/dcache-webdav/src/main/java/org/dcache/webdav/CrossOriginResourceSharingHandler.java
rename to modules/dcache/src/main/java/org/dcache/util/jetty/CrossOriginResourceSharingHandler.java
index d8831e1b4cd..45938ab2a4b 100644
--- a/modules/dcache-webdav/src/main/java/org/dcache/webdav/CrossOriginResourceSharingHandler.java
+++ b/modules/dcache/src/main/java/org/dcache/util/jetty/CrossOriginResourceSharingHandler.java
@@ -1,4 +1,4 @@
-package org.dcache.webdav;
+package org.dcache.util.jetty;
import static com.google.common.base.Preconditions.checkArgument;
diff --git a/skel/share/defaults/frontend.properties b/skel/share/defaults/frontend.properties
index 8e0c756fdd6..7852e2fc52e 100644
--- a/skel/share/defaults/frontend.properties
+++ b/skel/share/defaults/frontend.properties
@@ -759,6 +759,20 @@ frontend.limits.blocked-clients.idle-time = 10
(one-of?MILLISECONDS|SECONDS|MINUTES|HOURS|DAYS)\
frontend.limits.blocked-clients.idle-time.units = SECONDS
+# ---- Cross-Origin Resource Sharing (CORS)
+#
+# The websites that may provide JavaScript to
+# a web browser that then accesses this door.
+# Values are a comma-separated list of website
+# URLs without any path; e.g.,
+# https://example.org, http://example.org:8080
+#
+# If empty then no website is authorised.
+# Non-JavaScript clients are unaffected by
+# this property.
+#
+frontend.allowed.client.origins =
+
(deprecated)frontend.wellknown!wlcg-tape-rest-api.path = Use dcache.wellknown!wlcg-tape-rest-api.path instead
(obsolete)frontend.dcache-view.endpoints.webapi = Use frontend.static!dcache-view.endpoints.webapi instead