diff --git a/project_key/controllers/__init__.py b/project_key/controllers/__init__.py
index 4e80e131bf..2a64fcee17 100644
--- a/project_key/controllers/__init__.py
+++ b/project_key/controllers/__init__.py
@@ -1,3 +1,4 @@
# License LGPLv3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html).
from . import main
+from . import portal
diff --git a/project_key/controllers/portal.py b/project_key/controllers/portal.py
new file mode 100644
index 0000000000..9839365cb8
--- /dev/null
+++ b/project_key/controllers/portal.py
@@ -0,0 +1,24 @@
+# Copyright 2026 Noviat
+# License LGPLv3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html).
+
+from odoo.http import request
+
+from odoo.addons.project.controllers.portal import ProjectCustomerPortal
+
+
+class ProjectKeyCustomerPortal(ProjectCustomerPortal):
+ def _task_get_searchbar_inputs(self, milestones_allowed, project=False):
+ values = super()._task_get_searchbar_inputs(milestones_allowed, project)
+ values["key"] = {
+ "input": "key",
+ "label": request.env._("Search in Key"),
+ "sequence": 15,
+ }
+ return values
+
+ def _task_get_search_domain(self, search_in, search, milestones_allowed, project):
+ if search_in == "key":
+ return [("key", "ilike", search)]
+ return super()._task_get_search_domain(
+ search_in, search, milestones_allowed, project
+ )
diff --git a/project_key/models/project_task.py b/project_key/models/project_task.py
index 7f9be70dc0..624ede3a06 100644
--- a/project_key/models/project_task.py
+++ b/project_key/models/project_task.py
@@ -14,6 +14,14 @@ class Task(models.Model):
url = fields.Char(string="URL", compute="_compute_task_url")
+ @property
+ def TASK_PORTAL_READABLE_FIELDS(self):
+ # Expose `key` so it's readable in portal & project sharing views
+ # (otherwise the JS kanban arch parser crashes when reading
+ # record.fields.key.type because the field is filtered out by
+ # the server response spec).
+ return super().TASK_PORTAL_READABLE_FIELDS | {"key"}
+
_task_key_unique = models.Constraint(
"UNIQUE(key)",
"Task key must be unique!",
diff --git a/project_key/views/project_key_views.xml b/project_key/views/project_key_views.xml
index b849b79a5b..38517ca94a 100644
--- a/project_key/views/project_key_views.xml
+++ b/project_key/views/project_key_views.xml
@@ -60,7 +60,7 @@
project.task.list
project.task
-
+
@@ -71,7 +71,7 @@
project.task.search.key
project.task
-
+
project.task
-
-
+
-
+
-
-
-
+
+
+
@@ -106,4 +105,61 @@
+
+ project.sharing.project.task.kanban.key
+ project.task
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ project.sharing.project.task.form.key
+ project.task
+
+
+
+
+ :
+
+
+
+
+
+ not task.key
+
+
+
+
+ |
+
+
+
+
+
+
+