diff --git a/src/core/js/ext_entity_acl.js b/src/core/js/ext_entity_acl.js
new file mode 100644
index 0000000000000000000000000000000000000000..ce6d4160afefffa11a346804a565f832a0aca84e
--- /dev/null
+++ b/src/core/js/ext_entity_acl.js
@@ -0,0 +1,104 @@
+/*
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
+ * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+"use strict";
+
+/**
+ * Adds button to each entity which links to the entity's ACL.
+ *
+ * Please enable via build property:
+ *
+ *   BUILD_MODULE_EXT_ENTITY_ACL=ENABLED
+ *
+ * Set the base uri of the EntityACL view (optional, defaults to
+ * `${connection.getBasePath()}webinterface/acm/entityacl/`):
+ *
+ *   BUILD_MODULE_EXT_ENTITY_ACL_URI_ROOT=[scheme://host:port]/what/evs
+ *
+ *
+ * @author Timm Fitschen
+ */
+var ext_entity_acl = function ($, connection, getEntityVersion, getEntityID, logger) {
+
+    const BUILD_MODULE_EXT_ENTITY_ACL_URI_ROOT = connection.getBasePath() + "webinterface/acm/entityacl/";
+    const _buttons_list_class = "caosdb-v-entity-header-buttons-list";
+    const _entity_acl_link_class = "caosdb-f-entity-entity_acl-button";
+    const _entity_acl_canvas_container = "caosdb-f-entity-entity_acl";
+    const _entity_acl_link_container = "caosdb-f-entity-entity_acl-link";
+    const _entity_acl_icon = `<i class="bi bi-key"></i>`;
+
+    /**
+     * Create a link to the Entity ACL.
+     *
+     * @param {string} entity_id
+     * @return {HTMLElement} the newly created link.
+     */
+    var create_entity_acl_link = function (entity_id) {
+        const button = $(`<a href="${BUILD_MODULE_EXT_ENTITY_ACL_URI_ROOT}${entity_id}" title="Open Entity ACL" class="${_entity_acl_link_class} caosdb-v-entity-entity_acl-button btn">${_entity_acl_icon}</a>`);
+        return button[0];
+    }
+
+    /**
+     * Add a entity_acl button to a given entity.
+     * @param {HTMLElement} entity
+     */
+    var add_entity_acl_to_entity = function (entity) {
+        const entity_id = getEntityID(entity);
+
+        $(entity).find(`.${_buttons_list_class}`).append(create_entity_acl_link(entity_id));
+    }
+
+    var remove_entity_acl_link = function (entity) {
+        $(entity).find(`.${_buttons_list_class} .${_entity_acl_link_class}`).remove();
+    }
+
+    var _init = function () {
+        for (let entity of $(".caosdb-entity-panel")) {
+            remove_entity_acl_link(entity);
+            add_entity_acl_to_entity(entity);
+        }
+    }
+
+    /**
+     * Initialize this module and append a QR Code button to all entities panels on the page.
+     *
+     * Removes all respective buttons if present before adding a new one.
+     */
+    var init = function () {
+        _init();
+
+        // edit-mode-listener
+        document.body.addEventListener(edit_mode.end_edit.type, _init, true);
+    };
+
+    return {
+        add_entity_acl_to_entity: add_entity_acl_to_entity,
+        remove_entity_acl_link: remove_entity_acl_link,
+        create_entity_acl_link: create_entity_acl_link,
+        init: init
+    };
+
+}($, connection, getEntityVersion, getEntityID, log.getLogger("ext_entity_acl"));
+
+$(document).ready(function () {
+    if ("${BUILD_MODULE_EXT_ENTITY_ACL}" == "ENABLED") {
+        caosdb_modules.register(ext_entity_acl);
+    }
+});