diff --git a/arkindex/ponos/api.py b/arkindex/ponos/api.py
index 5f6e1833f4800f7c7301fb9a8e3fc2fb136bba91..8f6176a8c13cd8adcef47342f0fc44d5331216ce 100644
--- a/arkindex/ponos/api.py
+++ b/arkindex/ponos/api.py
@@ -321,7 +321,11 @@ class TaskArtifacts(ListCreateAPIView):
     pagination_class = None
 
     def get_task(self):
-        task = get_object_or_404(Task, pk=self.kwargs["pk"])
+        task = get_object_or_404(
+            # Select the required tables for permissions checking
+            Task.objects.select_related('workflow__process__corpus', 'workflow__process__revision'),
+            pk=self.kwargs["pk"],
+        )
         self.check_object_permissions(self.request, task)
         return task
 
diff --git a/arkindex/ponos/permissions.py b/arkindex/ponos/permissions.py
index d059cd2d37a640010a9f2587b6b78c88746fbbc6..4fdb86dbf18908ae78f5a7f3ab1fd8a383bd8513 100644
--- a/arkindex/ponos/permissions.py
+++ b/arkindex/ponos/permissions.py
@@ -1,7 +1,8 @@
 from rest_framework.permissions import SAFE_METHODS
 
 from arkindex.ponos.models import Task
-from arkindex.project.mixins import CorpusACLMixin
+from arkindex.process.models import Process
+from arkindex.project.mixins import CorpusACLMixin, ProcessACLMixin
 from arkindex.project.permissions import IsAuthenticated
 from arkindex.users.models import Role
 
@@ -75,7 +76,7 @@ class IsAgentOrTaskAdmin(CorpusACLMixin, IsAuthenticated):
         )
 
 
-class IsAgentOrTaskAdminOrReadOnly(CorpusACLMixin, IsAuthenticated):
+class IsAgentOrTaskAdminOrReadOnly(ProcessACLMixin, IsAuthenticated):
     """
     Instance admins, agents, process admins, and the task itself are always allowed.
     For GET/HEAD, only a Guest level on the process is required for regular users.
@@ -92,7 +93,11 @@ class IsAgentOrTaskAdminOrReadOnly(CorpusACLMixin, IsAuthenticated):
 
         # Add request to attributes for the ACL mixin to work with self.user
         self.request = request
-        level = self.process_access_level(task.workflow.process)
+        try:
+            level = self.process_access_level(task.workflow.process)
+        except Process.DoesNotExist:
+            # Reject if the task has no process
+            return False
 
         # Require *some* access to the process
         if level is None:
diff --git a/arkindex/ponos/tests/test_api.py b/arkindex/ponos/tests/test_api.py
index cc69589586b62d0d1a1300cb2d4a853d01f1728e..71ab20e305ce45ee99d644661e3656682dceb3b0 100644
--- a/arkindex/ponos/tests/test_api.py
+++ b/arkindex/ponos/tests/test_api.py
@@ -16,15 +16,14 @@ from django.test import override_settings
 from django.urls import reverse
 from django.utils import timezone
 from rest_framework import status
-from rest_framework.test import APITestCase
 
 from arkindex.documents.models import Corpus
 from arkindex.ponos.api import timezone as api_tz
 from arkindex.ponos.authentication import AgentUser
 from arkindex.ponos.models import FINAL_STATES, GPU, Agent, Farm, Secret, State, Task, Workflow, encrypt
 from arkindex.process.models import Process, ProcessMode
+from arkindex.project.tests import FixtureAPITestCase
 from arkindex.project.tools import build_public_key
-from arkindex.users.models import User
 from rest_framework_simplejwt.tokens import AccessToken, RefreshToken
 
 RECIPE = """
@@ -51,11 +50,12 @@ def str_date(d):
 
 
 @override_settings(PONOS_LOG_TAIL=42)
-class TestAPI(APITestCase):
+class TestAPI(FixtureAPITestCase):
+
     @classmethod
     def setUpTestData(cls):
         super().setUpTestData()
-        cls.farm = Farm.objects.create(name="Wheat farm")
+        cls.farm = Farm.objects.get()
         pubkey = build_public_key()
         cls.agent = AgentUser.objects.create(
             id=uuid.UUID(hashlib.md5(pubkey.encode("utf-8")).hexdigest()),
@@ -82,8 +82,6 @@ class TestAPI(APITestCase):
             index=1,
             ram_total=8 * 1024 * 1024 * 1024,
         )
-        cls.superuser = User.objects.create_superuser('root@root.root', 'root')
-        cls.user = User.objects.create_user('user@user.lol', 'hunter2')
 
     def _build_workflow_response(self, response, **kwargs):
         """
@@ -1213,8 +1211,7 @@ class TestAPI(APITestCase):
         self.assertEqual(resp.status_code, status.HTTP_401_UNAUTHORIZED)
 
     def test_agent_actions_no_user(self):
-        user = User.objects.create_superuser("root@root.fr", "hunter2", display_name='root')
-        self.client.force_login(user)
+        self.client.force_login(self.superuser)
         try:
             resp = self.client.get(reverse("api:agent-actions"))
             self.assertEqual(resp.status_code, status.HTTP_401_UNAUTHORIZED)
@@ -1387,6 +1384,37 @@ class TestAPI(APITestCase):
             ],
         )
 
+    def test_list_artifacts_process_creator(self):
+        Process.objects.create(
+            creator=self.user,
+            corpus=self.corpus,
+            mode=ProcessMode.Workers,
+            workflow=self.workflow,
+        )
+        artifact = self.task1.artifacts.create(
+            path="demo.txt",
+            content_type="text/plain",
+            size=12,
+        )
+        self.client.force_login(self.user)
+
+        with self.assertNumQueries(7):
+            response = self.client.get(reverse('api:task-artifacts', kwargs={'pk': self.task1.id}))
+            self.assertEqual(response.status_code, status.HTTP_200_OK)
+
+        self.assertListEqual(response.json(), [
+            {
+                'id': str(artifact.id),
+                'created': artifact.created.isoformat().replace('+00:00', 'Z'),
+                'updated': artifact.updated.isoformat().replace('+00:00', 'Z'),
+                'content_type': 'text/plain',
+                'path': 'demo.txt',
+                'size': 12,
+                's3_put_url': None,
+                'url': f'http://testserver/api/v1/task/{self.task1.id}/artifact/demo.txt',
+            }
+        ])
+
     @override_settings(PONOS_ARTIFACT_MAX_SIZE=99999)
     def test_artifact_creation(self):