diff --git a/src/app/user/controllers/SignatureController.php b/src/app/user/controllers/SignatureController.php
new file mode 100755
index 0000000000000000000000000000000000000000..c26d65b003595a7b36934c9b471c4fab951b6e94
--- /dev/null
+++ b/src/app/user/controllers/SignatureController.php
@@ -0,0 +1,196 @@
+<?php
+
+/**
+* Copyright Maarch since 2008 under licence GPLv3.
+* See LICENCE.txt file at the root folder for more details.
+* This file is part of Maarch software.
+*
+*/
+
+/**
+* @brief Signature Controller
+* @author dev@maarch.org
+*/
+
+namespace User\controllers;
+
+use Docserver\controllers\DocserverController;
+use Docserver\models\DocserverModel;
+use History\controllers\HistoryController;
+use Respect\Validation\Validator;
+use Slim\Http\Request;
+use Slim\Http\Response;
+use User\models\SignatureModel;
+
+class SignatureController
+{
+    public function get(Request $request, Response $response, array $args)
+    {
+        if ($GLOBALS['id'] != $args['id'] && !UserController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_users'])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Privilege forbidden']);
+        }
+
+        $data = $request->getQueryParams();
+        if (empty($data['offset']) || !is_numeric($data['offset'])) {
+            $data['offset'] = 0;
+        }
+        if (empty($data['limit']) || !is_numeric($data['limit'])) {
+            $data['limit'] = 0;
+        }
+
+        $rawSignatures = SignatureModel::get([
+            'select'    => ['id', 'path', 'filename', 'fingerprint'],
+            'where'     => ['user_id = ?'],
+            'data'      => [$args['id']],
+            'orderBy'   => ['id DESC'],
+            'offset'    => (int)$data['offset'],
+            'limit'     => (int)$data['limit']
+        ]);
+        $docserver = DocserverModel::getByType(['type' => 'SIGNATURE', 'select' => ['path']]);
+        if (empty($docserver['path']) || !file_exists($docserver['path'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Docserver does not exist']);
+        }
+
+        $signatures = [];
+        foreach ($rawSignatures as $signature) {
+            $pathToSignature = $docserver['path'] . $signature['path'] . $signature['filename'];
+            if (file_exists($pathToSignature)) {
+                $fingerprint = DocserverController::getFingerPrint(['path' => $pathToSignature]);
+                if ($signature['fingerprint'] == $fingerprint) {
+                    $signatures[] = [
+                        'id'                => $signature['id'],
+                        'encodedSignature'  => base64_encode(file_get_contents($pathToSignature))
+                    ];
+                } else {
+                    //TODO LOG
+                }
+            } else {
+                //TODO LOG
+            }
+        }
+
+        return $response->withJson(['signatures' => $signatures]);
+    }
+
+    public function create(Request $request, Response $response, array $args)
+    {
+        if ($GLOBALS['id'] != $args['id'] && !UserController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_users'])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Privilege forbidden']);
+        }
+
+        $body = $request->getParsedBody();
+
+        $check = Validator::notEmpty()->validate($body['encodedSignature']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($body['format']);
+        if (!$check) {
+            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
+        }
+
+        $storeInfos = DocserverController::storeResourceOnDocServer([
+            'encodedFile'       => $body['encodedSignature'],
+            'format'            => $body['format'],
+            'docserverType'     => 'SIGNATURE'
+        ]);
+
+        if (!empty($storeInfos['errors'])) {
+            return $response->withStatus(500)->withJson(['errors' => $storeInfos['errors']]);
+        }
+
+        $id = SignatureModel::create([
+            'userId'                => $args['id'],
+            'path'                  => $storeInfos['path'],
+            'filename'              => $storeInfos['filename'],
+            'fingerprint'           => $storeInfos['fingerprint'],
+            'external_application'  => null
+        ]);
+
+        HistoryController::add([
+            'code'          => 'OK',
+            'objectType'    => 'signatures',
+            'objectId'      => $id,
+            'type'          => 'CREATION',
+            'message'       => '{userSignatureAdded}',
+            'data'          => ['userId' => $args['id']]
+        ]);
+
+        return $response->withJson(['signatureId' => $id]);
+    }
+
+    public function delete(Request $request, Response $response, array $args)
+    {
+        if ($GLOBALS['id'] != $args['id'] && !UserController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_users'])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Privilege forbidden']);
+        }
+
+        SignatureModel::delete(['where' => ['user_id = ?', 'id = ?'], 'data' => [$args['id'], $args['signatureId']]]);
+
+        HistoryController::add([
+            'code'          => 'OK',
+            'objectType'    => 'signatures',
+            'objectId'      => $args['signatureId'],
+            'type'          => 'SUPPRESSION',
+            'message'       => '{userSignatureDeleted}',
+            'data'          => ['userId' => $args['id']]
+        ]);
+
+        return $response->withJson(['success' => 'success']);
+    }
+
+    public function updateExternalSignatures(Request $request, Response $response, array $args)
+    {
+        if ($GLOBALS['id'] != $args['id'] && !UserController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_users'])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Privilege forbidden']);
+        }
+
+        $body = $request->getParsedBody();
+
+        $img = file_get_contents('/home/damien/Documents/Test_Files/signature2.png'); //TODO remove
+
+        if (!Validator::arrayType()->notEmpty()->validate($body['signatures'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Body signature is empty or not an array']);
+        } elseif (!Validator::stringType()->notEmpty()->validate($body['externalApplication'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Body externalApplication is empty or not a string']);
+        }
+
+        foreach ($body['signatures'] as $key => $signature) {
+            $signature['encodedSignature'] = $body['signatures'][$key]['encodedSignature'] = base64_encode($img); //TODO remove
+            if (!Validator::notEmpty()->validate($signature['encodedSignature'])) {
+                return $response->withStatus(400)->withJson(['errors' => "Body signatures[{$key}] encodedSignature is empty"]);
+            } elseif (!Validator::stringType()->notEmpty()->validate($signature['format'])) {
+                return $response->withStatus(400)->withJson(['errors' => "Body signatures[{$key}] format is empty or not a string"]);
+            }
+        }
+
+        SignatureModel::delete(['where' => ['user_id = ?', 'external_application = ?'], 'data' => [$args['id'], $body['externalApplication']]]);
+
+        foreach ($body['signatures'] as $signature) {
+            $storeInfos = DocserverController::storeResourceOnDocServer([
+                'encodedFile'       => $signature['encodedSignature'],
+                'format'            => $signature['format'],
+                'docserverType'     => 'SIGNATURE'
+            ]);
+            if (!empty($storeInfos['errors'])) {
+                return $response->withStatus(500)->withJson(['errors' => $storeInfos['errors']]);
+            }
+
+            $id = SignatureModel::create([
+                'userId'                => $args['id'],
+                'path'                  => $storeInfos['path'],
+                'filename'              => $storeInfos['filename'],
+                'fingerprint'           => $storeInfos['fingerprint'],
+                'external_application'  => $body['externalApplication']
+            ]);
+
+            HistoryController::add([
+                'code'          => 'OK',
+                'objectType'    => 'signatures',
+                'objectId'      => $id,
+                'type'          => 'CREATION',
+                'message'       => '{userSignatureAdded}',
+                'data'          => ['userId' => $args['id'], 'externalApplication' => $body['externalApplication']]
+            ]);
+        }
+
+        return $response->withStatus(204);
+    }
+}
diff --git a/src/app/user/models/SignatureModel.php b/src/app/user/models/SignatureModel.php
new file mode 100755
index 0000000000000000000000000000000000000000..61e31f90e51f76f79bc94105171c692ed667521b
--- /dev/null
+++ b/src/app/user/models/SignatureModel.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+* Copyright Maarch since 2008 under licence GPLv3.
+* See LICENCE.txt file at the root folder for more details.
+* This file is part of Maarch software.
+*
+*/
+
+/**
+* @brief Signature Model
+* @author dev@maarch.org
+*/
+
+namespace User\models;
+
+use SrcCore\models\DatabaseModel;
+use SrcCore\models\ValidatorModel;
+
+class SignatureModel
+{
+    public static function get(array $aArgs)
+    {
+        ValidatorModel::arrayType($aArgs, ['select', 'where', 'data', 'orderBy']);
+        ValidatorModel::intType($aArgs, ['limit', 'offset']);
+
+        $aUsers = DatabaseModel::select([
+            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'table'     => ['signatures'],
+            'where'     => empty($aArgs['where']) ? [] : $aArgs['where'],
+            'data'      => empty($aArgs['data']) ? [] : $aArgs['data'],
+            'orderBy'   => empty($aArgs['orderBy']) ? [] : $aArgs['orderBy'],
+            'offset'    => empty($aArgs['offset']) ? 0 : $aArgs['offset'],
+            'limit'     => empty($aArgs['limit']) ? 0 : $aArgs['limit']
+        ]);
+
+        return $aUsers;
+    }
+
+    public static function create(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['userId', 'path', 'filename', 'fingerprint']);
+        ValidatorModel::stringType($aArgs, ['path', 'filename', 'fingerprint', 'external_application']);
+        ValidatorModel::intVal($aArgs, ['userId']);
+
+        $nextSequenceId = DatabaseModel::getNextSequenceValue(['sequenceId' => 'signatures_id_seq']);
+
+        DatabaseModel::insert([
+            'table'         => 'signatures',
+            'columnsValues' => [
+                'id'                    => $nextSequenceId,
+                'user_id'               => $aArgs['userId'],
+                'path'                  => $aArgs['path'],
+                'filename'              => $aArgs['filename'],
+                'fingerprint'           => $aArgs['fingerprint'],
+                'external_application'  => $aArgs['external_application']
+            ]
+        ]);
+
+        return $nextSequenceId;
+    }
+
+    public static function update(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['set', 'where', 'data']);
+        ValidatorModel::arrayType($args, ['set', 'where', 'data']);
+
+        DatabaseModel::update([
+            'table' => 'signatures',
+            'set'   => $args['set'],
+            'where' => $args['where'],
+            'data'  => $args['data']
+        ]);
+
+        return true;
+    }
+
+    public static function delete(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['where', 'data']);
+        ValidatorModel::arrayType($aArgs, ['where', 'data']);
+
+        DatabaseModel::delete([
+            'table' => 'signatures',
+            'where' => $aArgs['where'],
+            'data'  => $aArgs['data']
+        ]);
+
+        return true;
+    }
+}