diff --git a/migration/19.12/1912.sql b/migration/19.12/1912.sql
index cae5ab468b7d92487aa1f6d1289e9442cd658d2f..94b2b0095011e972daed95b5923d4ebbb96846fa 100644
--- a/migration/19.12/1912.sql
+++ b/migration/19.12/1912.sql
@@ -417,6 +417,17 @@ WHERE service_id = 'edit_recipient_outside_process' OR service_id = 'update_diff
 DELETE FROM usergroups_services WHERE service_id = 'edit_recipient_outside_process';
 DELETE FROM usergroups_services WHERE service_id = 'update_list_diff_in_details';
 DELETE FROM usergroups_services WHERE service_id = 'edit_recipient_in_process';
+
+UPDATE usergroups_services SET service_id = 'manage_own_attachments_in_details' WHERE service_id = 'edit_attachments_from_detail';
+INSERT INTO usergroups_services (group_id, service_id)
+SELECT distinct(group_id), 'manage_attachments'
+FROM usergroups_services WHERE group_id IN (
+    SELECT group_id FROM usergroups_services
+    WHERE service_id = 'modify_attachments' OR service_id = 'delete_attachments'
+);
+DELETE FROM usergroups_services WHERE service_id = 'modify_attachments';
+DELETE FROM usergroups_services WHERE service_id = 'delete_attachments';
+
 UPDATE listmodels SET title = object_id WHERE title IS NULL;
 UPDATE baskets SET basket_clause = REGEXP_REPLACE(basket_clause, 'coll_id(\s*)=(\s*)''letterbox_coll''(\s*)AND', '', 'gmi') WHERE basket_id in ('CopyMailBasket', 'DdeAvisBasket');
 UPDATE baskets SET basket_clause = REGEXP_REPLACE(basket_clause, 'coll_id(\s*)=(\s*)''letterbox_coll''(\s*)and', '', 'gmi') WHERE basket_id in ('CopyMailBasket', 'DdeAvisBasket');
diff --git a/src/app/attachment/controllers/AttachmentController.php b/src/app/attachment/controllers/AttachmentController.php
index 2ae994d021d0e2beedfde5de4181cb8975c939cf..e3121042b60738f34a8f8b60914f98fdbed100c3 100755
--- a/src/app/attachment/controllers/AttachmentController.php
+++ b/src/app/attachment/controllers/AttachmentController.php
@@ -452,25 +452,36 @@ class AttachmentController
             return $response->withStatus(400)->withJson(['errors' => 'Route id must be an integer val']);
         }
 
-        $attachment = AttachmentModel::getById(['id' => $args['id'], 'select' => ['origin_id', 'res_id_master', 'attachment_type', 'res_id', 'title']]);
+        $attachment = AttachmentModel::getById(['id' => $args['id'], 'select' => ['origin_id', 'res_id_master', 'attachment_type', 'res_id', 'title', 'typist']]);
         if (empty($attachment)) {
             return $response->withStatus(400)->withJson(['errors' => 'Attachment not found']);
         }
 
+        $user = UserModel::getById(['id' => $GLOBALS['id']]);
+        if ($user['user_id'] != $attachment['typist']
+            && !PrivilegeController::hasPrivilege(['privilegeId' => 'manage_attachments', 'userId' => $GLOBALS['id']])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter2']);
+        }
+
         if (!ResController::hasRightByResId(['resId' => [$attachment['res_id_master']], 'userId' => $GLOBALS['id']])) {
             return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
         }
 
         if ($attachment['attachment_type'] == 'signed_response') {
-            AttachmentModel::delete(['id' => $attachment['res_id']]);
+            AttachmentModel::delete([
+                'where' => ['res_id = ?'],
+                'data'  => [$attachment['res_id']]
+            ]);
         } else {
             if (empty($attachment['origin_id'])) {
                 $idToDelete = $attachment['res_id'];
             } else {
                 $idToDelete = $attachment['origin_id'];
             }
-
-            AttachmentModel::delete(['id' => $idToDelete]);
+            AttachmentModel::delete([
+                'where' => ['res_id = ? or origin_id = ?'],
+                'data'  => [$idToDelete, $idToDelete]
+            ]);
         }
         HistoryController::add([
             'tableName' => 'res_attachments',
diff --git a/src/app/attachment/models/AttachmentModelAbstract.php b/src/app/attachment/models/AttachmentModelAbstract.php
index 316259a7aa0938c587e4ca565248f48ea8cf87b1..f5e65821d9cce0d7667fdb9f3c1687efb73bfb5c 100755
--- a/src/app/attachment/models/AttachmentModelAbstract.php
+++ b/src/app/attachment/models/AttachmentModelAbstract.php
@@ -287,16 +287,16 @@ abstract class AttachmentModelAbstract
 
     public static function delete(array $args)
     {
-        ValidatorModel::notEmpty($args, ['id']);
-        ValidatorModel::intVal($args, ['id']);
+        ValidatorModel::notEmpty($args, ['where', 'data']);
+        ValidatorModel::arrayType($args, ['where', 'data']);
 
         DatabaseModel::update([
             'table' => 'res_attachments',
             'set'   => [
                 'status'    => 'DEL'
             ],
-            'where' => ['res_id = ? or origin_id = ?'],
-            'data'  => [$args['id'], $args['id']]
+            'where' => $args['where'],
+            'data'  => $args['data']
         ]);
 
         return true;
diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts
index f2be4195e08d332963b1397332c28d39440bc939..53e461fa8fa1dcbeec08543a6174cf540c2709d1 100755
--- a/src/frontend/lang/lang-en.ts
+++ b/src/frontend/lang/lang-en.ts
@@ -1266,4 +1266,6 @@ export const LANG_EN = {
     "diffListPrivilegeMsgProcess" : "in process page.",
     "recordMail" : "Record a mail",
     "closed" : "Closed",
+    "manageAttachments": "Update or delete attachments",
+    "manageOwnAttachmentsInDetails": "Update or delete user's own attachments in the details page",
 };
diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts
index 3d0137abb24324e6bde62bcc517530bda4c15ecf..a5fd1e4d913f5ee887dfad0e59599d381d49638a 100755
--- a/src/frontend/lang/lang-fr.ts
+++ b/src/frontend/lang/lang-fr.ts
@@ -1303,4 +1303,6 @@ export const LANG_FR = {
     "diffListPrivilegeMsgProcess" : "lors du traitement du courrier.",
     "recordMail" : "Enregistrer un courrier",
     "closed" : "Clôturé",
+    "manageAttachments": "Modifier ou supprimer des pièces jointes",
+    "manageOwnAttachmentsInDetails": "Modifier ou supprimer ses propres pièces jointes dans la fiche détaillée",
 };
diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts
index b36708e5239741ad2d7472933485940816c40e9a..6d46f46fb59f4da119a96c4de07ee153ad1f9d5a 100755
--- a/src/frontend/lang/lang-nl.ts
+++ b/src/frontend/lang/lang-nl.ts
@@ -1291,4 +1291,6 @@ export const LANG_NL = {
     "diffListPrivilegeMsgProcess" : "in process page.", //_TO_TRANSLATE
     "recordMail" : "Record a mail", //_TO_TRANSLATE
     "closed" : "Closed", //_TO_TRANSLATE
+    "manageAttachments": "Update or delete attachments", //_TO_TRANSLATE
+    "manageOwnAttachmentsInDetails": "Update or delete user's own attachments in the details page", //_TO_TRANSLATE
 };
diff --git a/src/frontend/service/privileges.service.ts b/src/frontend/service/privileges.service.ts
index 1d22f0c5beeff8fe84fd3cc0d965da268586024d..803546dfd4cb81b6c0569a7509953b77d978199a 100644
--- a/src/frontend/service/privileges.service.ts
+++ b/src/frontend/service/privileges.service.ts
@@ -401,6 +401,18 @@ export class PrivilegeService {
             "label": this.lang.printFolderDoc,
             "comment": this.lang.printFolderDoc,
             "unit": 'application'
+        },
+        {
+            "id": "manage_attachments",
+            "label": this.lang.manageAttachments,
+            "comment": this.lang.manageAttachments,
+            "unit": 'application'
+        },
+        {
+            "id": "manage_own_attachments_in_details",
+            "label": this.lang.manageOwnAttachmentsInDetails,
+            "comment": this.lang.manageOwnAttachmentsInDetails,
+            "unit": 'application'
         }
     ];