You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by mm...@apache.org on 2019/10/09 10:50:24 UTC

[syncope] branch master updated: SYNCOPE-1465: Add executor information to Report executions (#124)

This is an automated email from the ASF dual-hosted git repository.

mmoayyed pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new 7ff2793  SYNCOPE-1465: Add executor information to Report executions (#124)
7ff2793 is described below

commit 7ff279307f27e5c4e439b32b67024d457c70f720
Author: Misagh Moayyed <mm...@gmail.com>
AuthorDate: Wed Oct 9 14:50:19 2019 +0400

    SYNCOPE-1465: Add executor information to Report executions (#124)
    
    * SYNCOPE-1465: Add executor information to Task and Report executions
---
 .../console/reports/ReportExecutionDetails.java    |  2 +-
 .../console/tasks/ExecutionsDirectoryPanel.java    |  9 +++---
 .../tasks/ExecutionsDirectoryPanel.properties      |  1 +
 .../tasks/ExecutionsDirectoryPanel_it.properties   |  1 +
 .../tasks/ExecutionsDirectoryPanel_ja.properties   |  1 +
 .../ExecutionsDirectoryPanel_pt_BR.properties      |  1 +
 .../tasks/ExecutionsDirectoryPanel_ru.properties   |  1 +
 .../org/apache/syncope/common/lib/to/ExecTO.java   | 12 ++++++++
 .../org/apache/syncope/common/lib/to/ReportTO.java | 12 ++++++++
 .../org/apache/syncope/core/logic/GroupLogic.java  |  4 ++-
 .../org/apache/syncope/core/logic/RealmLogic.java  | 12 ++++----
 .../org/apache/syncope/core/logic/ReportLogic.java | 20 ++++++++-----
 .../org/apache/syncope/core/logic/TaskLogic.java   | 19 +++++++-----
 .../syncope/core/persistence/api/entity/Exec.java  |  3 ++
 .../core/persistence/jpa/entity/AbstractExec.java  | 13 ++++++++
 .../core/persistence/jpa/inner/TaskExecTest.java   |  1 +
 .../core/persistence/jpa/outer/ReportTest.java     |  1 +
 .../core/persistence/jpa/outer/TaskTest.java       |  3 ++
 .../core/provisioning/api/job/JobManager.java      |  5 ++--
 .../api/job/report/ReportJobDelegate.java          |  2 +-
 .../api/notification/NotificationJobDelegate.java  |  4 +--
 .../api/propagation/PropagationTaskExecutor.java   | 10 +++++--
 .../java/DefaultAnyObjectProvisioningManager.java  | 15 ++++++----
 .../java/DefaultGroupProvisioningManager.java      | 17 +++++++----
 .../java/DefaultUserProvisioningManager.java       | 24 ++++++++-------
 .../java/data/ReportDataBinderImpl.java            |  2 ++
 .../java/job/AbstractSchedTaskJobDelegate.java     |  3 ++
 .../core/provisioning/java/job/JobManagerImpl.java | 35 +++++++++++++++-------
 .../DefaultNotificationJobDelegate.java            |  8 ++---
 .../java/job/notification/NotificationJob.java     |  5 ++--
 .../java/job/report/DefaultReportJobDelegate.java  |  5 +++-
 .../provisioning/java/job/report/ReportJob.java    |  7 +++--
 .../AbstractPropagationTaskExecutor.java           | 16 ++++++----
 .../DefaultPropagationTaskCallable.java            |  2 +-
 .../PriorityPropagationTaskExecutor.java           |  3 +-
 .../java/pushpull/AbstractPullResultHandler.java   |  8 ++++-
 .../java/pushpull/AbstractPushResultHandler.java   | 11 +++++--
 .../pushpull/DefaultRealmPullResultHandler.java    | 14 ++++++---
 .../pushpull/DefaultRealmPushResultHandler.java    | 11 +++++--
 .../pushpull/DefaultUserPushResultHandler.java     |  7 +++--
 .../camel/component/PropagateComponent.java        |  8 ++++-
 .../camel/component/PropagateEndpoint.java         |  7 +++++
 .../camel/producer/AbstractProducer.java           | 10 +++++++
 .../producer/ConfirmPasswordResetProducer.java     |  2 +-
 .../camel/producer/CreateProducer.java             |  8 +++--
 .../camel/producer/DeleteProducer.java             |  6 ++--
 .../camel/producer/DeprovisionProducer.java        |  9 ++++--
 .../camel/producer/ProvisionProducer.java          |  6 ++--
 .../camel/producer/StatusProducer.java             |  3 +-
 .../camel/producer/SuspendProducer.java            |  2 +-
 .../camel/producer/UpdateProducer.java             |  6 ++--
 .../syncope/core/logic/UserRequestLogic.java       |  4 +--
 .../syncope/core/logic/UserWorkflowTaskLogic.java  |  5 ++--
 .../org/apache/syncope/fit/core/ReportITCase.java  | 25 ++++++++++++----
 .../syncope/fit/core/ReportTemplateITCase.java     | 14 ++++++++-
 55 files changed, 319 insertions(+), 126 deletions(-)

diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportExecutionDetails.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportExecutionDetails.java
index a152fbb..da638bc 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportExecutionDetails.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportExecutionDetails.java
@@ -82,7 +82,7 @@ public class ReportExecutionDetails extends MultilevelPanel.SecondLevel {
         }
 
         @Override
-        protected void addFurtherAcions(final ActionsPanel<ExecTO> panel, final IModel<ExecTO> model) {
+        protected void addFurtherActions(final ActionsPanel<ExecTO> panel, final IModel<ExecTO> model) {
             panel.add(new ActionLink<ExecTO>() {
 
                 private static final long serialVersionUID = -3722207913631435501L;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
index 9db6fa6..9acb60e 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
@@ -96,7 +96,8 @@ public abstract class ExecutionsDirectoryPanel
         final List<IColumn<ExecTO, String>> columns = new ArrayList<>();
 
         columns.add(new KeyPropertyColumn<>(new StringResourceModel("key", this), "key", "key"));
-
+        columns.add(new PropertyColumn<>(new StringResourceModel("executor", this), "executor", "executor"));
+        
         columns.add(new DatePropertyColumn<>(new StringResourceModel("start", this), "start", "start"));
 
         columns.add(new DatePropertyColumn<>(new StringResourceModel("end", this), "end", "end"));
@@ -139,12 +140,12 @@ public abstract class ExecutionsDirectoryPanel
             }
         }, ActionLink.ActionType.DELETE, IdRepoEntitlement.TASK_DELETE, true);
 
-        addFurtherAcions(panel, model);
+        addFurtherActions(panel, model);
 
         return panel;
     }
 
-    protected void addFurtherAcions(final ActionsPanel<ExecTO> panel, final IModel<ExecTO> model) {
+    protected void addFurtherActions(final ActionsPanel<ExecTO> panel, final IModel<ExecTO> model) {
     }
 
     @Override
@@ -179,7 +180,7 @@ public abstract class ExecutionsDirectoryPanel
 
         @Override
         public Iterator<ExecTO> iterator(final long first, final long count) {
-            int page = ((int) first / paginatorRows);
+            int page = (int) first / paginatorRows;
             return restClient.listExecutions(
                     taskKey, (page < 0 ? 0 : page) + 1, paginatorRows, getSort()).
                     iterator();
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.properties
index 99f323a..33bfd9e 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.properties
@@ -17,4 +17,5 @@
 start=Start
 end=End
 status=Status
+executor=Executor
 execution.view=Result status of execution '${key}'
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_it.properties
index 3c525b7..dcc952b 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_it.properties
@@ -17,4 +17,5 @@
 start=Start
 end=End
 status=Stato
+executor=Esecutore
 execution.view=Risultato dello stato dell'esecuzione '${key}'
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_ja.properties
index 118afa1..2325930 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_ja.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_ja.properties
@@ -17,4 +17,5 @@
 start=\u958b\u59cb
 end=\u7d42\u4e86
 status=\u30b9\u30c6\u30fc\u30bf\u30b9
+executor=Executor
 execution.view=\u5b9f\u884c '${key}' \u306e\u7d50\u679c\u30b9\u30c6\u30fc\u30bf\u30b9
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_pt_BR.properties
index 99f323a..33bfd9e 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_pt_BR.properties
@@ -17,4 +17,5 @@
 start=Start
 end=End
 status=Status
+executor=Executor
 execution.view=Result status of execution '${key}'
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_ru.properties
index bf48601..4239465 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel_ru.properties
@@ -22,4 +22,5 @@ end=\u041e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0435
 # status=Статус
 status=\u0421\u0442\u0430\u0442\u0443\u0441
 # execution.view=Итоговый статус запуска задачи '${key}'
+executor=Executor
 execution.view=\u0418\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0441\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 '${key}'
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ExecTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ExecTO.java
index 7ff6e99..1f98a5d 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ExecTO.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ExecTO.java
@@ -42,6 +42,8 @@ public class ExecTO extends AbstractStartEndBean implements EntityTO {
 
     private String message;
 
+    private String executor;
+
     @Override
     public String getKey() {
         return key;
@@ -92,6 +94,14 @@ public class ExecTO extends AbstractStartEndBean implements EntityTO {
         this.status = status;
     }
 
+    public String getExecutor() {
+        return executor;
+    }
+
+    public void setExecutor(final String executor) {
+        this.executor = executor;
+    }
+
     @Override
     public int hashCode() {
         return new HashCodeBuilder().
@@ -102,6 +112,7 @@ public class ExecTO extends AbstractStartEndBean implements EntityTO {
                 append(refDesc).
                 append(status).
                 append(message).
+                append(executor).
                 build();
     }
 
@@ -125,6 +136,7 @@ public class ExecTO extends AbstractStartEndBean implements EntityTO {
                 append(refDesc, other.refDesc).
                 append(status, other.status).
                 append(message, other.message).
+                append(executor, other.executor).
                 build();
     }
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java
index ec4eaeb..2c034ff 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java
@@ -58,6 +58,8 @@ public class ReportTO extends AbstractStartEndBean implements NamedEntityTO {
 
     private String template;
 
+    private String lastExecutor;
+    
     @Override
     public String getKey() {
         return key;
@@ -141,6 +143,14 @@ public class ReportTO extends AbstractStartEndBean implements NamedEntityTO {
         this.template = template;
     }
 
+    public String getLastExecutor() {
+        return lastExecutor;
+    }
+
+    public void setLastExecutor(final String lastExecutor) {
+        this.lastExecutor = lastExecutor;
+    }
+
     @Override
     public int hashCode() {
         return new HashCodeBuilder().
@@ -155,6 +165,7 @@ public class ReportTO extends AbstractStartEndBean implements NamedEntityTO {
                 append(nextExec).
                 append(active).
                 append(template).
+                append(lastExecutor).
                 build();
     }
 
@@ -182,6 +193,7 @@ public class ReportTO extends AbstractStartEndBean implements NamedEntityTO {
                 append(nextExec, other.nextExec).
                 append(active, other.active).
                 append(template, other.template).
+                append(lastExecutor, other.lastExecutor).
                 build();
     }
 }
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index 0d5a0c0..a3875fc 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -410,10 +410,12 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupCR, GroupUR> {
         task = taskDAO.save(task);
 
         try {
+            String executor = AuthContextUtils.getUsername();
             Map<String, Object> jobDataMap = jobManager.register(
                     task,
                     null,
-                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class));
+                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class),
+                    executor);
 
             jobDataMap.put(TaskJob.DRY_RUN_JOBDETAIL_KEY, false);
             jobDataMap.put(GroupMemberProvisionTaskJobDelegate.GROUP_KEY_JOBDETAIL_KEY, key);
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java
index a93a757..b3d5585 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java
@@ -117,11 +117,11 @@ public class RealmLogic extends AbstractTransactionalLogic<RealmTO> {
         }
 
         Realm realm = realmDAO.save(binder.create(parent, realmTO));
-
+        String executor = AuthContextUtils.getUsername();
         PropagationByResource<String> propByRes = new PropagationByResource<>();
         propByRes.addAll(ResourceOperation.CREATE, realm.getResourceKeys());
         List<PropagationTaskInfo> taskInfos = propagationManager.createTasks(realm, propByRes, null);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, false);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, false, executor);
 
         ProvisioningResult<RealmTO> result = new ProvisioningResult<>();
         result.setEntity(binder.getRealmTO(realm, true));
@@ -138,12 +138,12 @@ public class RealmLogic extends AbstractTransactionalLogic<RealmTO> {
 
             throw new NotFoundException(realmTO.getFullPath());
         }
-
+        String executor = AuthContextUtils.getUsername();
         PropagationByResource<String> propByRes = binder.update(realm, realmTO);
         realm = realmDAO.save(realm);
 
         List<PropagationTaskInfo> taskInfos = propagationManager.createTasks(realm, propByRes, null);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, false);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, false, executor);
 
         ProvisioningResult<RealmTO> result = new ProvisioningResult<>();
         result.setEntity(binder.getRealmTO(realm, true));
@@ -180,11 +180,11 @@ public class RealmLogic extends AbstractTransactionalLogic<RealmTO> {
             containedAnys.getElements().add(anyObjects + " anyObject(s)");
             throw containedAnys;
         }
-
+        String executor = AuthContextUtils.getUsername();
         PropagationByResource<String> propByRes = new PropagationByResource<>();
         propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys());
         List<PropagationTaskInfo> taskInfos = propagationManager.createTasks(realm, propByRes, null);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, false);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, false, executor);
 
         ProvisioningResult<RealmTO> result = new ProvisioningResult<>();
         result.setEntity(binder.getRealmTO(realm, true));
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
index 77568e6..e471af2 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
@@ -75,6 +75,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
 
 @Component
 public class ReportLogic extends AbstractExecutableLogic<ReportTO> {
@@ -99,12 +100,14 @@ public class ReportLogic extends AbstractExecutableLogic<ReportTO> {
         Report report = entityFactory.newEntity(Report.class);
         binder.getReport(report, reportTO);
         report = reportDAO.save(report);
-
+        String executor = AuthContextUtils.getUsername();
+        Assert.notNull(executor, "executor cannot be null when creating report");
         try {
             jobManager.register(
                     report,
                     null,
-                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class));
+                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class),
+                    executor);
         } catch (Exception e) {
             LOG.error("While registering quartz job for report " + report.getKey(), e);
 
@@ -125,12 +128,13 @@ public class ReportLogic extends AbstractExecutableLogic<ReportTO> {
 
         binder.getReport(report, reportTO);
         report = reportDAO.save(report);
-
+        String executor = AuthContextUtils.getUsername();
         try {
             jobManager.register(
                     report,
                     null,
-                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class));
+                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class),
+                    executor);
         } catch (Exception e) {
             LOG.error("While registering quartz job for report " + report.getKey(), e);
 
@@ -171,12 +175,14 @@ public class ReportLogic extends AbstractExecutableLogic<ReportTO> {
             sce.getElements().add("Report " + key + " is not active");
             throw sce;
         }
-
+        String executor = AuthContextUtils.getUsername();
+        Assert.notNull(executor, "executor cannot be null when executing report");
         try {
             jobManager.register(
                     report,
                     startAt,
-                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class));
+                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class),
+                    executor);
 
             scheduler.getScheduler().triggerJob(JobNamer.getJobKey(report));
         } catch (Exception e) {
@@ -194,7 +200,7 @@ public class ReportLogic extends AbstractExecutableLogic<ReportTO> {
         result.setStart(new Date());
         result.setStatus(ReportExecStatus.STARTED.name());
         result.setMessage("Job fired; waiting for results...");
-
+        result.setExecutor(executor);
         return result;
     }
 
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
index a8b18fa..96fba5d 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
@@ -110,7 +110,7 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
             sce.getElements().add("Found " + type + ", expected " + taskUtils.getType());
             throw sce;
         }
-
+        String executor = AuthContextUtils.getUsername();
         SchedTask task = binder.createSchedTask(taskTO, taskUtils);
         task = taskDAO.save(task);
 
@@ -118,7 +118,8 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
             jobManager.register(
                     task,
                     task.getStartAt(),
-                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class));
+                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class),
+                    executor);
         } catch (Exception e) {
             LOG.error("While registering quartz job for task " + task.getKey(), e);
 
@@ -146,12 +147,13 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
 
         binder.updateSchedTask(task, taskTO, taskUtils);
         task = taskDAO.save(task);
-
+        String executor = AuthContextUtils.getUsername();
         try {
             jobManager.register(
                     task,
                     task.getStartAt(),
-                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class));
+                    confParamOps.get(AuthContextUtils.getDomain(), "tasks.interruptMaxRetries", 1L, Long.class),
+                    executor);
         } catch (Exception e) {
             LOG.error("While registering quartz job for task " + task.getKey(), e);
 
@@ -231,7 +233,8 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
         }
 
         TaskUtils taskUtil = taskUtilsFactory.getInstance(task);
-
+        String executor = AuthContextUtils.getUsername();
+        
         ExecTO result = null;
         switch (taskUtil.getType()) {
             case PROPAGATION:
@@ -248,12 +251,12 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
                 taskInfo.setAnyType(taskTO.getAnyType());
                 taskInfo.setEntityKey(taskTO.getEntityKey());
 
-                TaskExec propExec = taskExecutor.execute(taskInfo);
+                TaskExec propExec = taskExecutor.execute(taskInfo, executor);
                 result = binder.getExecTO(propExec);
                 break;
 
             case NOTIFICATION:
-                TaskExec notExec = notificationJobDelegate.executeSingle((NotificationTask) task);
+                TaskExec notExec = notificationJobDelegate.executeSingle((NotificationTask) task, executor);
                 result = binder.getExecTO(notExec);
                 break;
 
@@ -271,7 +274,7 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
                             (SchedTask) task,
                             startAt,
                             confParamOps.get(AuthContextUtils.getDomain(),
-                                    "tasks.interruptMaxRetries", 1L, Long.class));
+                                    "tasks.interruptMaxRetries", 1L, Long.class), executor);
 
                     jobDataMap.put(TaskJob.DRY_RUN_JOBDETAIL_KEY, dryRun);
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Exec.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Exec.java
index 3f34ae1..ca4141d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Exec.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Exec.java
@@ -43,4 +43,7 @@ public interface Exec extends Entity {
 
     Date getEnd();
 
+    String getExecutor();
+
+    void setExecutor(String executor);
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractExec.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractExec.java
index a90dd67..e2ca193 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractExec.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractExec.java
@@ -38,6 +38,9 @@ public abstract class AbstractExec extends AbstractGeneratedKeyEntity implements
     @NotNull
     protected String status;
 
+    @NotNull
+    protected String executor;
+
     /**
      * Any information to be accompanied to this execution's result.
      */
@@ -70,6 +73,16 @@ public abstract class AbstractExec extends AbstractGeneratedKeyEntity implements
     }
 
     @Override
+    public String getExecutor() {
+        return this.executor;
+    }
+
+    @Override
+    public void setExecutor(final String executor) {
+        this.executor = executor;
+    }
+
+    @Override
     public String getMessage() {
         return message;
     }
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
index af257f5..7391026 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
@@ -80,6 +80,7 @@ public class TaskExecTest extends AbstractTest {
         exec.setEnd(new Date());
         exec.setStatus(ExecStatus.SUCCESS.name());
         exec.setMessage(faultyMessage);
+        exec.setExecutor("admin");
 
         task.add(exec);
         exec.setTask(task);
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
index 76ae60f..c3bbd24 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
@@ -88,6 +88,7 @@ public class ReportTest extends AbstractTest {
         reportExec.setStart(new Date());
         reportExec.setEnd(new Date());
         reportExec.setStatus(ReportExecStatus.SUCCESS);
+        reportExec.setExecutor("admin");
 
         report.add(reportExec);
         reportDAO.save(report);
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
index 3656449..1516f30 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
@@ -151,6 +151,7 @@ public class TaskTest extends AbstractTest {
         execution.setTask(task);
         execution.setStatus(ExecStatus.CREATED.name());
         execution.setStart(new Date());
+        execution.setExecutor("admin");
         task.add(execution);
 
         taskDAO.save(task);
@@ -174,6 +175,7 @@ public class TaskTest extends AbstractTest {
         execution.setTask(task);
         execution.setStart(new Date());
         execution.setMessage("A message");
+        execution.setExecutor("admin");
         task.add(execution);
 
         taskDAO.save(task);
@@ -197,6 +199,7 @@ public class TaskTest extends AbstractTest {
         execution.setTask(task);
         execution.setStart(new Date());
         execution.setMessage("A message");
+        execution.setExecutor("admin");
         task.add(execution);
 
         taskDAO.save(task);
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobManager.java
index 95c3026..ed34fc3 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobManager.java
@@ -30,15 +30,16 @@ import org.quartz.SchedulerException;
 public interface JobManager {
 
     String DOMAIN_KEY = "domain";
+    String EXECUTOR_KEY = "executor";
 
     JobKey NOTIFICATION_JOB = new JobKey("notificationJob", Scheduler.DEFAULT_GROUP);
 
     boolean isRunning(JobKey jobKey) throws SchedulerException;
 
-    Map<String, Object> register(SchedTask task, Date startAt, long interruptMaxRetries)
+    Map<String, Object> register(SchedTask task, Date startAt, long interruptMaxRetries, String executor)
             throws SchedulerException;
 
-    void register(Report report, Date startAt, long interruptMaxRetries)
+    void register(Report report, Date startAt, long interruptMaxRetries, String executor)
             throws SchedulerException;
 
     void unregister(Task task);
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/report/ReportJobDelegate.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/report/ReportJobDelegate.java
index bbf455f..9aad7aa 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/report/ReportJobDelegate.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/report/ReportJobDelegate.java
@@ -23,5 +23,5 @@ import org.quartz.JobExecutionException;
 
 public interface ReportJobDelegate extends JobDelegate {
 
-    void execute(String reportKey) throws JobExecutionException;
+    void execute(String reportKey, String executor) throws JobExecutionException;
 }
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/NotificationJobDelegate.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/NotificationJobDelegate.java
index 3dfcddd..16b2e79 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/NotificationJobDelegate.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/NotificationJobDelegate.java
@@ -25,7 +25,7 @@ import org.quartz.JobExecutionException;
 
 public interface NotificationJobDelegate extends JobDelegate {
 
-    TaskExec executeSingle(NotificationTask task);
+    TaskExec executeSingle(NotificationTask task, String executor);
 
-    void execute() throws JobExecutionException;
+    void execute(String executor) throws JobExecutionException;
 }
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java
index a000d78..6447fca 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java
@@ -45,18 +45,20 @@ public interface PropagationTaskExecutor {
      * Execute the given PropagationTask and returns the generated {@link TaskExec}.
      *
      * @param taskInfo to be executed
+     * @param executor the executor of this task
      * @return the generated TaskExec
      */
-    TaskExec execute(PropagationTaskInfo taskInfo);
+    TaskExec execute(PropagationTaskInfo taskInfo, String executor);
 
     /**
      * Execute the given PropagationTask and returns the generated {@link TaskExec}.
      *
      * @param taskInfo to be executed
      * @param reporter to report propagation execution status
+     * @param executor the executor of this task
      * @return the generated TaskExec
      */
-    TaskExec execute(PropagationTaskInfo taskInfo, PropagationReporter reporter);
+    TaskExec execute(PropagationTaskInfo taskInfo, PropagationReporter reporter, String executor);
 
     /**
      * Execute a collection of PropagationTask objects.
@@ -65,7 +67,9 @@ public interface PropagationTaskExecutor {
      *
      * @param taskInfos to be execute, in given order
      * @param nullPriorityAsync asynchronously executes tasks related to resources with no priority
+     * @param executor the executor of this task
      * @return reporter to report propagation execution status
      */
-    PropagationReporter execute(Collection<PropagationTaskInfo> taskInfos, boolean nullPriorityAsync);
+    PropagationReporter execute(Collection<PropagationTaskInfo> taskInfos, boolean nullPriorityAsync,
+                                String executor);
 }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
index 34fddd0..1efe3b6 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
@@ -43,8 +43,13 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+
 public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisioningManager {
 
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
     @Autowired
     protected AnyObjectWorkflowAdapter awfAdapter;
 
@@ -81,7 +86,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
                 created.getPropByRes(),
                 anyObjectCR.getVirAttrs(),
                 excludedResources);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return Pair.of(created.getResult(), propagationReporter.getStatuses());
     }
@@ -109,7 +114,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
                 null,
                 anyObjectUR.getVirAttrs(),
                 excludedResources);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return Pair.of(updated.getResult(), propagationReporter.getStatuses());
     }
@@ -138,7 +143,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
                 propByRes,
                 null,
                 excludedResources);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         try {
             awfAdapter.delete(key);
@@ -175,7 +180,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
                 null,
                 null,
                 null);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return propagationReporter.getStatuses();
     }
@@ -195,7 +200,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
                 anyObjectDAO.findAllResourceKeys(key).stream().
                         filter(resource -> !resources.contains(resource)).
                         collect(Collectors.toList()));
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return propagationReporter.getStatuses();
     }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
index e3b1532..08783bb 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
@@ -46,8 +46,13 @@ import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+
 public class DefaultGroupProvisioningManager implements GroupProvisioningManager {
 
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
     @Autowired
     protected GroupWorkflowAdapter gwfAdapter;
 
@@ -77,7 +82,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
                 created.getPropByRes(),
                 groupCR.getVirAttrs(),
                 Set.of());
-        PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync, this.adminUser);
 
         return Pair.of(created.getResult(), propagationReporter.getStatuses());
     }
@@ -103,7 +108,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
                 created.getPropByRes(),
                 groupCR.getVirAttrs(),
                 excludedResources);
-        PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync, this.adminUser);
 
         return Pair.of(created.getResult(), propagationReporter.getStatuses());
     }
@@ -131,7 +136,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
                 null,
                 groupUR.getVirAttrs(),
                 excludedResources);
-        PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync, this.adminUser);
 
         return Pair.of(updated.getResult(), propagationReporter.getStatuses());
     }
@@ -175,7 +180,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
                 null,
                 null));
 
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         gwfAdapter.delete(key);
 
@@ -203,7 +208,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
                 null,
                 null,
                 null);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return propagationReporter.getStatuses();
     }
@@ -223,7 +228,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
                 groupDAO.findAllResourceKeys(key).stream().
                         filter(resource -> !resources.contains(resource)).
                         collect(Collectors.toList()));
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return propagationReporter.getStatuses();
     }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
index 6294d38..4439bc6 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
@@ -53,10 +53,15 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+
 public class DefaultUserProvisioningManager implements UserProvisioningManager {
 
     protected static final Logger LOG = LoggerFactory.getLogger(UserProvisioningManager.class);
 
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
     @Autowired
     protected UserWorkflowAdapter uwfAdapter;
 
@@ -96,7 +101,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                 created.getPropByLinkedAccount(),
                 userCR.getVirAttrs(),
                 excludedResources);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return Pair.of(created.getResult().getLeft(), propagationReporter.getStatuses());
     }
@@ -106,7 +111,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
         UserWorkflowResult<Pair<UserUR, Boolean>> updated = uwfAdapter.update(userUR);
 
         List<PropagationTaskInfo> taskInfos = propagationManager.getUserUpdateTasks(updated);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return Pair.of(updated.getResult().getLeft(), propagationReporter.getStatuses());
     }
@@ -167,7 +172,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
 
         List<PropagationTaskInfo> taskInfos = propagationManager.getUserUpdateTasks(
                 updated, updated.getResult().getLeft().getPassword() != null, excludedResources);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return Pair.of(updated.getResult().getLeft(), propagationReporter.getStatuses());
     }
@@ -200,7 +205,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                 propByRes,
                 propByLinkedAccount,
                 excludedResources);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         try {
             uwfAdapter.delete(key);
@@ -261,7 +266,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                 null,
                 null,
                 null);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return propagationReporter.getStatuses();
     }
@@ -280,7 +285,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                     updated.getLeft().getPropByRes(),
                     updated.getLeft().getPropByLinkedAccount(),
                     updated.getLeft().getPerformedTasks()));
-            taskExecutor.execute(taskInfos, false);
+            taskExecutor.execute(taskInfos, false, this.adminUser);
         }
     }
 
@@ -313,7 +318,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                 Pair.of(userUR, (Boolean) null), propByRes, null, "update");
 
         List<PropagationTaskInfo> taskInfos = propagationManager.getUserUpdateTasks(wfResult, changePwd, null);
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return propagationReporter.getStatuses();
     }
@@ -340,7 +345,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                 userDAO.findAllResourceKeys(key).stream().
                         filter(resource -> !resources.contains(resource)).
                         collect(Collectors.toList()));
-        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
+        PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, this.adminUser);
 
         return propagationReporter.getStatuses();
     }
@@ -355,7 +360,6 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
         UserWorkflowResult<Pair<UserUR, Boolean>> updated = uwfAdapter.confirmPasswordReset(key, token, password);
 
         List<PropagationTaskInfo> taskInfos = propagationManager.getUserUpdateTasks(updated);
-
-        taskExecutor.execute(taskInfos, false);
+        taskExecutor.execute(taskInfos, false, this.adminUser);
     }
 }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java
index abf2f2b..ea9a33b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java
@@ -108,6 +108,7 @@ public class ReportDataBinderImpl implements ReportDataBinder {
             reportTO.setStart(latestExec.getStart());
             reportTO.setEnd(latestExec.getEnd());
 
+            reportTO.setLastExecutor(latestExec.getExecutor());
             reportTO.setLastExec(reportTO.getStart());
         }
 
@@ -148,6 +149,7 @@ public class ReportDataBinderImpl implements ReportDataBinder {
         execTO.setStart(execution.getStart());
         execTO.setEnd(execution.getEnd());
 
+        execTO.setExecutor(execution.getExecutor());
         return execTO;
     }
 }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
index 796abc4..ab952cd 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.provisioning.java.job;
 import java.util.Date;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.core.provisioning.api.job.JobManager;
 import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
@@ -110,9 +111,11 @@ public abstract class AbstractSchedTaskJobDelegate implements SchedTaskJobDelega
             return;
         }
 
+        String executor = context.getMergedJobDataMap().getString(JobManager.EXECUTOR_KEY);
         TaskExec execution = entityFactory.newEntity(TaskExec.class);
         execution.setStart(new Date());
         execution.setTask(task);
+        execution.setExecutor(executor);
 
         status.set("Initialization completed");
 
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
index c10c593..b14bf09 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
@@ -28,6 +28,8 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+
+import javax.annotation.Resource;
 import javax.sql.DataSource;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
@@ -98,6 +100,9 @@ public class JobManagerImpl implements JobManager, SyncopeCoreLoader {
     @Autowired
     private ConfParamOps confParamOps;
 
+    @Resource(name = "adminUser")
+    private String adminUser;
+    
     private boolean disableQuartzInstance;
 
     public void setDisableQuartzInstance(final boolean disableQuartzInstance) {
@@ -216,7 +221,8 @@ public class JobManagerImpl implements JobManager, SyncopeCoreLoader {
     }
 
     @Override
-    public Map<String, Object> register(final SchedTask task, final Date startAt, final long interruptMaxRetries)
+    public Map<String, Object> register(final SchedTask task, final Date startAt, final long interruptMaxRetries,
+                                        final String executor)
             throws SchedulerException {
 
         TaskJob job = createSpringBean(TaskJob.class);
@@ -238,8 +244,7 @@ public class JobManagerImpl implements JobManager, SyncopeCoreLoader {
                     + " does not provide any " + SchedTaskJobDelegate.class.getSimpleName());
         }
 
-        Map<String, Object> jobMap = new HashMap<>();
-        jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain());
+        Map<String, Object> jobMap = createJobMapForExecutionContext(executor);
         jobMap.put(TaskJob.DELEGATE_IMPLEMENTATION, jobDelegate.getKey());
 
         registerJob(
@@ -252,18 +257,24 @@ public class JobManagerImpl implements JobManager, SyncopeCoreLoader {
     }
 
     @Override
-    public void register(final Report report, final Date startAt, final long interruptMaxRetries)
-            throws SchedulerException {
+    public void register(final Report report, final Date startAt, final long interruptMaxRetries,
+                         final String executor) throws SchedulerException {
 
         ReportJob job = createSpringBean(ReportJob.class);
         job.setReportKey(report.getKey());
 
-        Map<String, Object> jobMap = new HashMap<>();
-        jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain());
+        Map<String, Object> jobMap = createJobMapForExecutionContext(executor);
 
         registerJob(JobNamer.getJobKey(report).getName(), job, report.getCronExpression(), startAt, jobMap);
     }
 
+    private static Map<String, Object> createJobMapForExecutionContext(final String executor) {
+        Map<String, Object> jobMap = new HashMap<>();
+        jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain());
+        jobMap.put(JobManager.EXECUTOR_KEY, executor);
+        return jobMap;
+    }
+
     private void unregisterJob(final String jobName) {
         try {
             scheduler.getScheduler().unscheduleJob(new TriggerKey(jobName, Scheduler.DEFAULT_GROUP));
@@ -336,7 +347,7 @@ public class JobManagerImpl implements JobManager, SyncopeCoreLoader {
             for (Iterator<SchedTask> it = tasks.iterator(); it.hasNext() && !loadException;) {
                 SchedTask task = it.next();
                 try {
-                    register(task, task.getStartAt(), conf.getRight());
+                    register(task, task.getStartAt(), conf.getRight(), this.adminUser);
                 } catch (Exception e) {
                     LOG.error("While loading job instance for task " + task.getKey(), e);
                     loadException = true;
@@ -350,7 +361,7 @@ public class JobManagerImpl implements JobManager, SyncopeCoreLoader {
                 for (Iterator<Report> it = reportDAO.findAll().iterator(); it.hasNext() && !loadException;) {
                     Report report = it.next();
                     try {
-                        register(report, null, conf.getRight());
+                        register(report, null, conf.getRight(), this.adminUser);
                     } catch (Exception e) {
                         LOG.error("While loading job instance for report " + report.getName(), e);
                         loadException = true;
@@ -376,12 +387,13 @@ public class JobManagerImpl implements JobManager, SyncopeCoreLoader {
 
                 try {
                     NotificationJob job = createSpringBean(NotificationJob.class);
+                    Map<String, Object> jobData = createJobMapForExecutionContext(this.adminUser);
                     registerJob(
                             NOTIFICATION_JOB.getName(),
                             job,
                             conf.getLeft(),
                             null,
-                            Map.of());
+                            jobData);
                 } catch (Exception e) {
                     LOG.error("While loading {} instance", NotificationJob.class.getSimpleName(), e);
                 }
@@ -391,12 +403,13 @@ public class JobManagerImpl implements JobManager, SyncopeCoreLoader {
             LOG.debug("Registering {}", SystemLoadReporterJob.class);
             try {
                 SystemLoadReporterJob job = createSpringBean(SystemLoadReporterJob.class);
+                Map<String, Object> jobData = createJobMapForExecutionContext(this.adminUser);
                 registerJob(
                         StringUtils.uncapitalize(SystemLoadReporterJob.class.getSimpleName()),
                         job,
                         "0 * * * * ?",
                         null,
-                        Map.of());
+                        jobData);
             } catch (Exception e) {
                 LOG.error("While loading {} instance", SystemLoadReporterJob.class.getSimpleName(), e);
             }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java
index 76485ba..6c5ff84 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/DefaultNotificationJobDelegate.java
@@ -127,11 +127,11 @@ public class DefaultNotificationJobDelegate implements InitializingBean, Notific
 
     @Transactional
     @Override
-    public TaskExec executeSingle(final NotificationTask task) {
+    public TaskExec executeSingle(final NotificationTask task, final String executor) {
         TaskExec execution = entityFactory.newEntity(TaskExec.class);
         execution.setTask(task);
         execution.setStart(new Date());
-
+        execution.setExecutor(executor);
         boolean retryPossible = true;
 
         if (StringUtils.isBlank(task.getSubject()) || task.getRecipients().isEmpty()
@@ -250,14 +250,14 @@ public class DefaultNotificationJobDelegate implements InitializingBean, Notific
 
     @Transactional
     @Override
-    public void execute() throws JobExecutionException {
+    public void execute(final String executor) throws JobExecutionException {
         List<NotificationTask> tasks = taskDAO.<NotificationTask>findToExec(TaskType.NOTIFICATION);
 
         status.set("Sending out " + tasks.size() + " notifications");
 
         for (int i = 0; i < tasks.size() && !interrupt; i++) {
             LOG.debug("Found notification task {} to be executed: starting...", tasks.get(i));
-            executeSingle(tasks.get(i));
+            executeSingle(tasks.get(i), executor);
             LOG.debug("Notification task {} executed", tasks.get(i));
         }
         if (interrupt) {
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/NotificationJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/NotificationJob.java
index 1ccf569..f5afad8 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/NotificationJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/NotificationJob.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.provisioning.java.job.notification;
 
 import org.apache.syncope.core.persistence.api.DomainHolder;
+import org.apache.syncope.core.provisioning.api.job.JobManager;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.provisioning.api.job.JobDelegate;
 import org.apache.syncope.core.provisioning.api.notification.NotificationJobDelegate;
@@ -63,12 +64,12 @@ public class NotificationJob extends AbstractInterruptableJob {
     @Override
     public void execute(final JobExecutionContext context) throws JobExecutionException {
         LOG.debug("Waking up...");
-
+        String executor = context.getMergedJobDataMap().getString(JobManager.EXECUTOR_KEY);
         for (String domain : domainHolder.getDomains().keySet()) {
             try {
                 AuthContextUtils.callAsAdmin(domain, () -> {
                     try {
-                        delegate.execute();
+                        delegate.execute(executor);
                     } catch (Exception e) {
                         LOG.error("While sending out notifications", e);
                         throw new RuntimeException(e);
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/DefaultReportJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/DefaultReportJobDelegate.java
index e4050b7..c95aa20 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/DefaultReportJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/DefaultReportJobDelegate.java
@@ -35,6 +35,7 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
+
 import org.apache.syncope.common.lib.types.ReportExecStatus;
 import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
 import org.apache.syncope.core.persistence.api.dao.ReportDAO;
@@ -108,7 +109,7 @@ public class DefaultReportJobDelegate implements ReportJobDelegate {
 
     @Transactional
     @Override
-    public void execute(final String reportKey) throws JobExecutionException {
+    public void execute(final String reportKey, final String executor) throws JobExecutionException {
         Report report = reportDAO.find(reportKey);
         if (report == null) {
             throw new JobExecutionException("Report " + reportKey + " not found");
@@ -124,6 +125,8 @@ public class DefaultReportJobDelegate implements ReportJobDelegate {
         execution.setStatus(ReportExecStatus.STARTED);
         execution.setStart(new Date());
         execution.setReport(report);
+
+        execution.setExecutor(executor);
         execution = reportExecDAO.save(execution);
 
         report.add(execution);
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java
index 6b2fbfa..fa80c42 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java
@@ -61,10 +61,13 @@ public class ReportJob extends AbstractInterruptableJob {
     @Override
     public void execute(final JobExecutionContext context) throws JobExecutionException {
         try {
-            AuthContextUtils.callAsAdmin(context.getMergedJobDataMap().getString(JobManager.DOMAIN_KEY),
+            String domainKey = context.getMergedJobDataMap().getString(JobManager.DOMAIN_KEY);
+            String executor = context.getMergedJobDataMap().getString(JobManager.EXECUTOR_KEY);
+
+            AuthContextUtils.callAsAdmin(domainKey,
                     () -> {
                         try {
-                            delegate.execute(reportKey);
+                            delegate.execute(reportKey, executor);
                         } catch (Exception e) {
                             LOG.error("While executing report {}", reportKey, e);
                             throw new RuntimeException(e);
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index ca26d3c..40e9943 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -342,12 +342,13 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
     }
 
     @Override
-    public TaskExec execute(final PropagationTaskInfo taskInfo) {
-        return execute(taskInfo, null);
+    public TaskExec execute(final PropagationTaskInfo taskInfo, final String executor) {
+        return execute(taskInfo, null, executor);
     }
 
     @Override
-    public TaskExec execute(final PropagationTaskInfo taskInfo, final PropagationReporter reporter) {
+    public TaskExec execute(final PropagationTaskInfo taskInfo, final PropagationReporter reporter,
+                            final String executor) {
         PropagationTask task;
         if (taskInfo.getKey() == null) {
             task = entityFactory.newEntity(PropagationTask.class);
@@ -376,6 +377,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
 
         TaskExec execution = entityFactory.newEntity(TaskExec.class);
         execution.setStatus(ExecStatus.CREATED.name());
+        execution.setExecutor(executor);
 
         String taskExecutionMessage = null;
         String failureReason = null;
@@ -553,16 +555,18 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
     }
 
     protected abstract void doExecute(
-            Collection<PropagationTaskInfo> taskInfos, PropagationReporter reporter, boolean nullPriorityAsync);
+            Collection<PropagationTaskInfo> taskInfos, PropagationReporter reporter, boolean nullPriorityAsync,
+            String executor);
 
     @Override
     public PropagationReporter execute(
             final Collection<PropagationTaskInfo> taskInfos,
-            final boolean nullPriorityAsync) {
+            final boolean nullPriorityAsync,
+            final String executor) {
 
         PropagationReporter reporter = new DefaultPropagationReporter();
         try {
-            doExecute(taskInfos, reporter, nullPriorityAsync);
+            doExecute(taskInfos, reporter, nullPriorityAsync, executor);
         } catch (PropagationException e) {
             LOG.error("Error propagation priority resource", e);
             reporter.onPriorityResourceFailure(e.getResourceName(), taskInfos);
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationTaskCallable.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationTaskCallable.java
index da9b97a..1c8ece2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationTaskCallable.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationTaskCallable.java
@@ -79,7 +79,7 @@ public class DefaultPropagationTaskCallable implements PropagationTaskCallable {
 
         LOG.debug("Execution started for {}", taskInfo);
 
-        TaskExec execution = taskExecutor.execute(taskInfo, reporter);
+        TaskExec execution = taskExecutor.execute(taskInfo, reporter, username);
 
         LOG.debug("Execution completed for {}, {}", taskInfo, execution);
 
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
index 11261a9..0a60ba2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
@@ -82,7 +82,8 @@ public class PriorityPropagationTaskExecutor extends AbstractPropagationTaskExec
     protected void doExecute(
             final Collection<PropagationTaskInfo> taskInfos,
             final PropagationReporter reporter,
-            final boolean nullPriorityAsync) {
+            final boolean nullPriorityAsync,
+            final String executorId) {
 
         Map<PropagationTaskInfo, ExternalResource> taskToResource = new HashMap<>(taskInfos.size());
         List<PropagationTaskInfo> prioritizedTasks = new ArrayList<>();
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
index 4e22d29..5097e9e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
@@ -69,10 +69,15 @@ import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+
 @Transactional(rollbackFor = Throwable.class)
 public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHandler<PullTask, PullActions>
         implements SyncopePullResultHandler {
 
+    @Resource(name = "adminUser")
+    protected String adminUser;
+    
     @Autowired
     protected PullUtils pullUtils;
 
@@ -454,7 +459,8 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                                 propByRes,
                                 null,
                                 null),
-                                false);
+                                false,
+                                this.adminUser);
 
                         AnyUR anyUR = null;
                         if (matchingRule == MatchingRule.UNASSIGN) {
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
index ec32114..73ced5d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
@@ -62,12 +62,17 @@ import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+
 public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
         implements SyncopePushResultHandler {
 
     @Autowired
     protected PushUtils pushUtils;
 
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
     /**
      * Notification Manager.
      */
@@ -124,7 +129,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         if (!taskInfos.isEmpty()) {
             taskInfos.get(0).setBeforeObj(Optional.of(beforeObj));
             PropagationReporter reporter = new DefaultPropagationReporter();
-            taskExecutor.execute(taskInfos.get(0), reporter);
+            taskExecutor.execute(taskInfos.get(0), reporter, this.adminUser);
             reportPropagation(result, reporter);
         }
     }
@@ -148,7 +153,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         if (!taskInfos.isEmpty()) {
             taskInfos.get(0).setBeforeObj(Optional.of(beforeObj));
             PropagationReporter reporter = new DefaultPropagationReporter();
-            taskExecutor.execute(taskInfos.get(0), reporter);
+            taskExecutor.execute(taskInfos.get(0), reporter, this.adminUser);
             reportPropagation(result, reporter);
         }
     }
@@ -172,7 +177,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         if (!taskInfos.isEmpty()) {
             taskInfos.get(0).setBeforeObj(Optional.ofNullable(null));
             PropagationReporter reporter = new DefaultPropagationReporter();
-            taskExecutor.execute(taskInfos.get(0), reporter);
+            taskExecutor.execute(taskInfos.get(0), reporter, this.adminUser);
             reportPropagation(result, reporter);
         }
     }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java
index 9a2adf6..af39823 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java
@@ -57,11 +57,16 @@ import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+
 @Transactional(rollbackFor = Throwable.class)
 public class DefaultRealmPullResultHandler
         extends AbstractRealmResultHandler<PullTask, PullActions>
         implements RealmPullResultHandler {
 
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
     @Autowired
     private PullUtils pullUtils;
 
@@ -239,7 +244,7 @@ public class DefaultRealmPullResultHandler
             propByRes.addAll(ResourceOperation.CREATE, realm.getResourceKeys());
             if (unmatchingRule == UnmatchingRule.ASSIGN) {
                 List<PropagationTaskInfo> taskInfos = propagationManager.createTasks(realm, propByRes, null);
-                taskExecutor.execute(taskInfos, false);
+                taskExecutor.execute(taskInfos, false, this.adminUser);
             }
 
             RealmTO actual = binder.getRealmTO(realm, true);
@@ -325,7 +330,7 @@ public class DefaultRealmPullResultHandler
                         RealmTO updated = binder.getRealmTO(realm, true);
 
                         List<PropagationTaskInfo> taskInfos = propagationManager.createTasks(realm, propByRes, null);
-                        taskExecutor.execute(taskInfos, false);
+                        taskExecutor.execute(taskInfos, false, this.adminUser);
 
                         for (PullActions action : profile.getActions()) {
                             action.after(profile, delta, updated, result);
@@ -414,7 +419,8 @@ public class DefaultRealmPullResultHandler
 
                         PropagationByResource<String> propByRes = new PropagationByResource<>();
                         propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
-                        taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
+                        taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null),
+                            false, this.adminUser);
 
                         RealmTO realmTO;
                         if (unlink) {
@@ -609,7 +615,7 @@ public class DefaultRealmPullResultHandler
                         PropagationByResource<String> propByRes = new PropagationByResource<>();
                         propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys());
                         List<PropagationTaskInfo> taskInfos = propagationManager.createTasks(realm, propByRes, null);
-                        taskExecutor.execute(taskInfos, false);
+                        taskExecutor.execute(taskInfos, false, this.adminUser);
 
                         realmDAO.delete(realm);
 
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java
index 062265f..1460e6a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java
@@ -60,10 +60,15 @@ import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+
 public class DefaultRealmPushResultHandler
         extends AbstractRealmResultHandler<PushTask, PushActions>
         implements RealmPushResultHandler {
 
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
     @Autowired
     private MappingManager mappingManager;
 
@@ -110,7 +115,7 @@ public class DefaultRealmPushResultHandler
         if (!taskInfos.isEmpty()) {
             taskInfos.get(0).setBeforeObj(Optional.ofNullable(beforeObj));
             PropagationReporter reporter = new DefaultPropagationReporter();
-            taskExecutor.execute(taskInfos.get(0), reporter);
+            taskExecutor.execute(taskInfos.get(0), reporter, this.adminUser);
             reportPropagation(result, reporter);
         }
 
@@ -128,7 +133,7 @@ public class DefaultRealmPushResultHandler
         if (!taskInfos.isEmpty()) {
             taskInfos.get(0).setBeforeObj(Optional.ofNullable(beforeObj));
             PropagationReporter reporter = new DefaultPropagationReporter();
-            taskExecutor.execute(taskInfos.get(0), reporter);
+            taskExecutor.execute(taskInfos.get(0), reporter, this.adminUser);
             reportPropagation(result, reporter);
         }
     }
@@ -141,7 +146,7 @@ public class DefaultRealmPushResultHandler
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
         PropagationReporter reporter = taskExecutor.execute(
-                propagationManager.createTasks(realm, propByRes, noPropResources), false);
+                propagationManager.createTasks(realm, propByRes, noPropResources), false, this.adminUser);
         reportPropagation(result, reporter);
     }
 
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
index 8ee48cf..535d705 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
@@ -82,7 +82,8 @@ public class DefaultUserPushResultHandler extends AbstractPushResultHandler impl
                 propByLinkedAccount,
                 before.getVirAttrs(),
                 noPropResources),
-                false);
+                false,
+                this.adminUser);
         reportPropagation(result, reporter);
     }
 
@@ -121,7 +122,7 @@ public class DefaultUserPushResultHandler extends AbstractPushResultHandler impl
         if (!taskInfos.isEmpty()) {
             taskInfos.get(0).setBeforeObj(Optional.of(beforeObj));
             PropagationReporter reporter = new DefaultPropagationReporter();
-            taskExecutor.execute(taskInfos.get(0), reporter);
+            taskExecutor.execute(taskInfos.get(0), reporter, this.adminUser);
             reportPropagation(result, reporter);
         }
     }
@@ -152,7 +153,7 @@ public class DefaultUserPushResultHandler extends AbstractPushResultHandler impl
         if (!taskInfos.isEmpty()) {
             taskInfos.get(0).setBeforeObj(Optional.of(beforeObj));
             PropagationReporter reporter = new DefaultPropagationReporter();
-            taskExecutor.execute(taskInfos.get(0), reporter);
+            taskExecutor.execute(taskInfos.get(0), reporter, this.adminUser);
             reportPropagation(result, reporter);
         }
     }
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateComponent.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateComponent.java
index e445177..8bc34fa 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateComponent.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateComponent.java
@@ -31,6 +31,8 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecu
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import javax.annotation.Resource;
+
 public class PropagateComponent extends DefaultComponent {
 
     @Autowired
@@ -54,6 +56,9 @@ public class PropagateComponent extends DefaultComponent {
     @Autowired
     protected UserWorkflowAdapter uwfAdapter;
 
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
     @Override
     protected Endpoint createEndpoint(final String uri, final String remaining,
             final Map<String, Object> parameters) throws Exception {
@@ -67,7 +72,8 @@ public class PropagateComponent extends DefaultComponent {
         endpoint.setAnyObjectDAO(anyObjectDAO);
         endpoint.setGroupDataBinder(groupDataBinder);
         endpoint.setUwfAdapter(uwfAdapter);
-
+        endpoint.setExecutor(adminUser);
+        
         setProperties(endpoint, parameters);
         return endpoint;
     }
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateEndpoint.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateEndpoint.java
index 000611f..469dd52 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateEndpoint.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateEndpoint.java
@@ -72,6 +72,8 @@ public class PropagateEndpoint extends DefaultEndpoint {
 
     private UserWorkflowAdapter uwfAdapter;
 
+    private String executor;
+    
     public PropagateEndpoint(final String endpointUri, final Component component) {
         super(endpointUri, component);
     }
@@ -114,6 +116,7 @@ public class PropagateEndpoint extends DefaultEndpoint {
             producer.setPropagationManager(propagationManager);
             producer.setPropagationTaskExecutor(taskExecutor);
             producer.setPull(pull);
+            producer.setExecutor(this.executor);
         }
         return producer;
     }
@@ -179,4 +182,8 @@ public class PropagateEndpoint extends DefaultEndpoint {
     public void setUwfAdapter(final UserWorkflowAdapter uwfAdapter) {
         this.uwfAdapter = uwfAdapter;
     }
+
+    public void setExecutor(final String executor) {
+        this.executor = executor;
+    }
 }
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/AbstractProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/AbstractProducer.java
index 54df5d8..5a411a9 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/AbstractProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/AbstractProducer.java
@@ -34,6 +34,8 @@ public abstract class AbstractProducer extends DefaultProducer {
 
     private boolean pull;
 
+    private String executor;
+
     public AbstractProducer(final Endpoint endpoint, final AnyTypeKind anyTypeKind) {
         super(endpoint);
         this.anyTypeKind = anyTypeKind;
@@ -66,4 +68,12 @@ public abstract class AbstractProducer extends DefaultProducer {
     public void setPull(final boolean pull) {
         this.pull = pull;
     }
+
+    public String getExecutor() {
+        return executor;
+    }
+
+    public void setExecutor(final String executor) {
+        this.executor = executor;
+    }
 }
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ConfirmPasswordResetProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ConfirmPasswordResetProducer.java
index 0465166..c6eb70a 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ConfirmPasswordResetProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ConfirmPasswordResetProducer.java
@@ -43,7 +43,7 @@ public class ConfirmPasswordResetProducer extends AbstractProducer {
 
             List<PropagationTaskInfo> taskInfos = getPropagationManager().getUserUpdateTasks(updated);
 
-            getPropagationTaskExecutor().execute(taskInfos, false);
+            getPropagationTaskExecutor().execute(taskInfos, false, getExecutor());
         }
     }
 }
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/CreateProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/CreateProducer.java
index fe93b6d..7eac9e0 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/CreateProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/CreateProducer.java
@@ -61,7 +61,8 @@ public class CreateProducer extends AbstractProducer {
                         created.getPropByLinkedAccount(),
                         ((UserCR) actual).getVirAttrs(),
                         excludedResources);
-                PropagationReporter reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+                PropagationReporter reporter = getPropagationTaskExecutor()
+                    .execute(taskInfos, nullPriorityAsync, getExecutor());
 
                 exchange.getMessage().setBody(
                         Pair.of(created.getResult().getKey(), reporter.getStatuses()));
@@ -80,7 +81,7 @@ public class CreateProducer extends AbstractProducer {
                             created.getPropByRes(),
                             ((AnyCR) actual).getVirAttrs(),
                             excludedResources);
-                    getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+                    getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
 
                     exchange.getMessage().setBody(Pair.of(created.getResult(), null));
                 } else {
@@ -91,7 +92,8 @@ public class CreateProducer extends AbstractProducer {
                             created.getPropByRes(),
                             ((AnyCR) actual).getVirAttrs(),
                             excludedResources);
-                    PropagationReporter reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+                    PropagationReporter reporter =
+                        getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
 
                     exchange.getMessage().setBody(Pair.of(created.getResult(), reporter.getStatuses()));
                 }
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeleteProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeleteProducer.java
index e765f71..7049b8c 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeleteProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeleteProducer.java
@@ -79,7 +79,7 @@ public class DeleteProducer extends AbstractProducer {
                             propByRes,
                             propByLinkedAccount,
                             excludedResources);
-                    reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+                    reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
                     exchange.setProperty("statuses", reporter.getStatuses());
                     break;
 
@@ -111,7 +111,7 @@ public class DeleteProducer extends AbstractProducer {
                             null,
                             null,
                             null));
-                    reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+                    reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
                     exchange.setProperty("statuses", reporter.getStatuses());
                     break;
 
@@ -122,7 +122,7 @@ public class DeleteProducer extends AbstractProducer {
                             null,
                             null,
                             excludedResources);
-                    reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+                    reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
                     exchange.setProperty("statuses", reporter.getStatuses());
                     break;
 
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeprovisionProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeprovisionProducer.java
index 8560220..d9cc568 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeprovisionProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeprovisionProducer.java
@@ -82,7 +82,8 @@ public class DeprovisionProducer extends AbstractProducer {
                             propByLinkedAccount,
                             userDAO.findAllResourceKeys(key).stream().
                                     filter(resource -> !resources.contains(resource)).collect(Collectors.toList()));
-                    propagationReporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+                    propagationReporter =
+                        getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
                     exchange.getMessage().setBody(propagationReporter.getStatuses());
                     break;
 
@@ -95,7 +96,8 @@ public class DeprovisionProducer extends AbstractProducer {
                             null,
                             groupDAO.findAllResourceKeys(key).stream().
                                     filter(resource -> !resources.contains(resource)).collect(Collectors.toList()));
-                    propagationReporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+                    propagationReporter =
+                        getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
                     exchange.getMessage().setBody(propagationReporter.getStatuses());
                     break;
 
@@ -108,7 +110,8 @@ public class DeprovisionProducer extends AbstractProducer {
                             null,
                             anyObjectDAO.findAllResourceKeys(key).stream().
                                     filter(resource -> !resources.contains(resource)).collect(Collectors.toList()));
-                    propagationReporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+                    propagationReporter =
+                        getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
                     exchange.getMessage().setBody(propagationReporter.getStatuses());
                     break;
 
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ProvisionProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ProvisionProducer.java
index f669e2e..48459b9 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ProvisionProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ProvisionProducer.java
@@ -73,7 +73,8 @@ public class ProvisionProducer extends AbstractProducer {
                     Pair.of(userUR, (Boolean) null), propByRes, null, "update");
 
             List<PropagationTaskInfo> taskInfos = getPropagationManager().getUserUpdateTasks(wfResult, changePwd, null);
-            PropagationReporter reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+            PropagationReporter reporter =
+                getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
 
             exchange.getMessage().setBody(reporter.getStatuses());
         } else {
@@ -101,7 +102,8 @@ public class ProvisionProducer extends AbstractProducer {
                     propByLinkedAccount,
                     null,
                     null);
-            PropagationReporter reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+            PropagationReporter reporter =
+                getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
 
             exchange.getMessage().setBody(reporter.getStatuses());
         }
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/StatusProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/StatusProducer.java
index 076def4..a30289f 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/StatusProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/StatusProducer.java
@@ -108,7 +108,8 @@ public class StatusProducer extends AbstractProducer {
                     propByLinkedAccount,
                     null,
                     null);
-            PropagationReporter reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+            PropagationReporter reporter =
+                getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
 
             exchange.getMessage().setBody(Pair.of(updated.getResult(), reporter.getStatuses()));
         }
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java
index 9261bb5..a669932 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java
@@ -51,7 +51,7 @@ public class SuspendProducer extends AbstractProducer {
                                 updated.getLeft().getPropByRes(),
                                 updated.getKey().getPropByLinkedAccount(),
                                 updated.getLeft().getPerformedTasks()));
-                getPropagationTaskExecutor().execute(taskInfos, false);
+                getPropagationTaskExecutor().execute(taskInfos, false, getExecutor());
             }
         }
     }
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/UpdateProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/UpdateProducer.java
index 112bba0..b3bb169 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/UpdateProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/UpdateProducer.java
@@ -57,7 +57,8 @@ public class UpdateProducer extends AbstractProducer {
                 } else {
                     taskInfos = getPropagationManager().getUserUpdateTasks(updated);
                 }
-                PropagationReporter reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+                PropagationReporter reporter =
+                    getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
 
                 exchange.getMessage().setBody(Pair.of(updated.getResult().getLeft(), reporter.getStatuses()));
             } else if (actual instanceof AnyUR) {
@@ -73,7 +74,8 @@ public class UpdateProducer extends AbstractProducer {
                         null,
                         ((AnyUR) actual).getVirAttrs(),
                         excludedResources);
-                PropagationReporter reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
+                PropagationReporter reporter =
+                    getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync, getExecutor());
 
                 exchange.getMessage().setBody(Pair.of(updated.getResult(), reporter.getStatuses()));
             }
diff --git a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java
index 832b23b..2df4c59 100644
--- a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java
+++ b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java
@@ -184,7 +184,7 @@ public class UserRequestLogic extends AbstractTransactionalLogic<EntityTO> {
         }
 
         UserWorkflowResult<UserUR> wfResult = userRequestHandler.submitForm(form);
-
+        String executor = AuthContextUtils.getUsername();
         // propByRes can be made empty by the workflow definition if no propagation should occur 
         // (for example, with rejected users)
         if (wfResult.getPropByRes() != null && !wfResult.getPropByRes().isEmpty()) {
@@ -195,7 +195,7 @@ public class UserRequestLogic extends AbstractTransactionalLogic<EntityTO> {
                             wfResult.getPropByLinkedAccount(),
                             wfResult.getPerformedTasks()));
 
-            taskExecutor.execute(taskInfos, false);
+            taskExecutor.execute(taskInfos, false, executor);
         }
 
         UserTO userTO;
diff --git a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowTaskLogic.java b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowTaskLogic.java
index e7bce81..0de8c70 100644
--- a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowTaskLogic.java
+++ b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowTaskLogic.java
@@ -36,6 +36,7 @@ import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.flowable.api.WorkflowTaskManager;
 import org.apache.syncope.core.provisioning.api.UserWorkflowResult;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -79,8 +80,8 @@ public class UserWorkflowTaskLogic extends AbstractTransactionalLogic<EntityTO>
                         updated.getPropByRes(),
                         updated.getPropByLinkedAccount(),
                         updated.getPerformedTasks()));
-
-        taskExecutor.execute(taskInfos, false);
+        String executor = AuthContextUtils.getUsername();
+        taskExecutor.execute(taskInfos, false, executor);
 
         return binder.getUserTO(updated.getResult());
     }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
index 34b2e3c..d458347 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
@@ -54,21 +54,36 @@ import org.apache.syncope.common.rest.api.batch.BatchResponseItem;
 import org.apache.syncope.common.rest.api.beans.ExecDeleteQuery;
 import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
 import org.apache.syncope.fit.AbstractITCase;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
 
 public class ReportITCase extends AbstractITCase {
 
+    @BeforeAll
+    public static void setup() {
+        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+            new User("admin", "FAKE_PASSWORD", List.of()), "FAKE_PASSWORD", List.of());
+        auth.setDetails(new SyncopeAuthenticationDetails("Master"));
+        SecurityContextHolder.getContext().setAuthentication(auth);
+    }
+    
     protected static String execReport(final String reportKey) {
         ReportTO reportTO = reportService.read(reportKey);
         assertNotNull(reportTO);
         assertNotNull(reportTO.getExecutions());
 
         int preExecSize = reportTO.getExecutions().size();
-        ExecTO exec = reportService.execute(new ExecuteQuery.Builder().key(reportKey).build());
+        ExecuteQuery query = new ExecuteQuery.Builder().key(reportKey).build();
+        ExecTO exec = reportService.execute(query);
         assertNotNull(exec);
-
+        assertNotNull(exec.getExecutor());
+        
         int i = 0;
         int maxit = 50;
 
@@ -83,7 +98,7 @@ public class ReportITCase extends AbstractITCase {
 
             assertNotNull(reportTO);
             assertNotNull(reportTO.getExecutions());
-
+            
             i++;
         } while (preExecSize == reportTO.getExecutions().size() && i < maxit);
         if (i == maxit) {
@@ -146,10 +161,8 @@ public class ReportITCase extends AbstractITCase {
 
         report = createReport(report);
         assertNotNull(report);
-
         ReportTO actual = reportService.read(report.getKey());
         assertNotNull(actual);
-
         assertEquals(actual, report);
     }
 
@@ -357,7 +370,7 @@ public class ReportITCase extends AbstractITCase {
         reportTO.setTemplate("sample");
         reportTO = createReport(reportTO);
         assertNotNull(reportTO);
-
+        
         ExecTO execution = reportService.execute(new ExecuteQuery.Builder().key(reportTO.getKey()).build());
         assertNotNull(execution);
 
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
index 68bbb51..535b84f 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
@@ -36,11 +36,23 @@ import org.apache.syncope.common.lib.to.ReportTemplateTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.ReportExecExportFormat;
 import org.apache.syncope.common.lib.types.ReportTemplateFormat;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
 import org.apache.syncope.fit.AbstractITCase;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
 
 public class ReportTemplateITCase extends AbstractITCase {
-
+    @BeforeAll
+    public static void setup() {
+        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+            new User("admin", "FAKE_PASSWORD", List.of()), "FAKE_PASSWORD", List.of());
+        auth.setDetails(new SyncopeAuthenticationDetails("Master"));
+        SecurityContextHolder.getContext().setAuthentication(auth);
+    }
+    
     @Test
     public void read() {
         ReportTemplateTO reportTemplateTO = reportTemplateService.read("sample");