Inquiry: Enforcing User Access Validation During Outgoing Sync in Exalate

Dear Exalate Support Team,

We are currently utilizing Exalate version 7.0.3 to synchronize issues between our IFS Jira Data Center 10.3.3 instance (source) and our DTP Jira instance (target). We have a custom field, “Assign to Support,” with a single selectable value: “DTP.” When a user selects “DTP” and fills in the required fields, the issue is eligible for synchronization to the DTP instance.

Requirement:

We would like to ensure that only users who have valid access on the DTP side can trigger the synchronization. Specifically, if a user without access on DTP selects “DTP” and attempts to update the issue, the synchronization should be blocked, and an error should be thrown, preventing the issue from being created on the DTP side.

Questions:

User Access Validation:

Is it possible to validate user access on the DTP instance during the outgoing synchronization process in Exalate?

If so, which Exalate helper methods or APIs can be utilized to check if a user has the necessary permissions on the DTP side?

Sync Interruption and Error Handling:

If an unauthorized user attempts to trigger the synchronization, can Exalate abort the sync process and throw an error?

How can we implement this behavior in the outgoing sync script?

Does Exalate provide logging or auditing capabilities to track when a synchronization is blocked due to user access issues?

We appreciate your assistance in implementing this functionality to ensure that only authorized users can trigger synchronization to the DTP instance.

Best regards,
Musthafha

Great questions! Here’s a breakdown of how you can approach user access validation and error handling during outgoing syncs in Exalate for Jira Data Center:

1. User Access Validation on the DTP Side
Exalate’s sync scripts (Script mode) run independently on each side, and by default, the outgoing sync script on your source Jira (IFS) doesn’t have direct access to the user directory or permissions of the target Jira (DTP). This means you can’t natively check DTP-side user permissions in the outgoing script alone.

However, you can implement a workaround:

  • Maintain a list of authorized users (or user emails/usernames) in your outgoing sync script.
  • Before allowing the sync, check if the user triggering the sync is in this list.
  • For dynamic validation against DTP’s actual permissions, you’d need to use an external API call to DTP Jira (e.g., via Jira REST API) from within your script, but Exalate’s scripting environment doesn’t support direct HTTP calls for security reasons.

2. Helper Methods or APIs

  • Exalate’s built-in helper methods (like replica, issue, currentUser) only provide info about the local instance.
  • For cross-instance validation, you’d need to maintain a mapping or use an external service.

3. Aborting Sync and Throwing Errors

  • You can abort the sync in the outgoing sync script by throwing an exception if the user is unauthorized. For example:
def authorizedUsers = ["user1", "user2", "user3"] // Replace with actual usernames/emails
if (!authorizedUsers.contains(issue.reporter?.name)) {
    throw new com.exalate.api.exception.IssueTrackerException("User not authorized to sync to DTP.")
}

This will stop the sync and log an error in Exalate’s logs.

4. Logging and Auditing

  • Exalate logs all sync errors, including those thrown by custom scripts, in the Exalate logs on both source and target nodes.
  • You can review these logs for auditing blocked sync attempts. For more details, see the Exalate logging documentation.

Summary

  • Direct DTP-side permission checks aren’t possible in the outgoing script, but you can maintain an allowlist or use external validation.
  • Use exceptions in the script to block unauthorized syncs.
  • All such events are logged for auditing.

For more on scripting and error handling, check out:

This approach should help you enforce user-based sync controls and maintain a clear audit trail.

1 Like

Hi Exalate Community,

We have tried the below method

  • IFS assignee should map to reporter in DTP.

  • We have removed the default reporter fallback on the DTP side, so if the IFS assignee is not valid on DTP, the sync should fail / not create the issue.

What we’ve done / what’s happening:

  1. We tested with an IFS user who does not exist in DTP. After assigning them as assignee in IFS, the sync shows “Waiting for Remote” and no issue is created in DTP. (Expected behavior.)

  2. On the same issue, we updated the IFS assignee to a user who does exist in DTP (same email / user identity). We expected the sync to proceed / issue to be created on DTP. But the sync remains in “Waiting for Remote”. No issue created. Un-exalating + re-syncing didn’t help — still “Waiting for Remote”.

What we have verified:

  • The assignee in IFS truly corresponds to a valid user in DTP (email/username mapping aligns).

  • Removed default reporter fallback, so no fallback path.

  • Confirmed required fields and permissions in DTP are satisfied for sync (or so we think).

  • Checked that Exalate proxy/connector account has appropriate permissions.

What we need help with:

  1. What could cause “Waiting for Remote” to persist even when the assignee is valid?

  2. Are there hidden requirements on the DTP side (validators, field constraints, permissions) that might block the sync even when user mapping is okay?

  3. Are there known issues / pitfalls in Exalate scripts / mapping logic when mapping assignee-to-reporter (especially after removing default reporter) that can cause this state?

  4. What logging or diagnostic info would help reveal what is going wrong (e.g. what remote side sees, why it’s rejecting or not processing)?

    Best,
    Mustafa

Hi @Mustafa ,

Thanks for sharing the detailed testing steps — that helps a lot.

When you see “Waiting for Remote”, it usually means the source node has already sent the payload, but the target (DTP Jira) hasn’t processed it. That doesn’t always mean the user mapping failed; it can also be caused by other constraints on the DTP side.

A couple of things to check:

  • Reporter permissions → make sure the Exalate proxy account has Modify Reporter and Browse Users permissions in the DTP project. Even if the user exists, Jira won’t allow setting them as reporter without these.

  • Workflow/field validators → confirm that no required fields or workflow conditions are silently blocking issue creation.

  • Logs → check the Exalate logs on the DTP side (especially the sync log) around the timestamp. That usually reveals whether the reporter/user was rejected or another field caused the rejection.

  • Fallback test → try re-enabling the default reporter fallback temporarily. If the sync goes through with fallback, the problem is specifically with reporter/user mapping. If not, it’s more likely workflow/field configuration.

In short, “Waiting for Remote” = target side not accepting the payload. The logs on DTP should tell you exactly why.

Thanks, Dhiren

Hi Dhiren,

A few points to clarify:

  • When we remove the default reporter on the DTP side, any attempt to sync with a new user (who doesn’t have access on DTP) fails, showing “Waiting for Remote”.

  • If we create a new ticket and sync using a user who already has access on DTP, the sync works as expected.

  • However, the previous ticket still remains in “Waiting for Remote” status. Even after we change the assignee on the IFS side to a valid user (one who has DTP access), the ticket sync still shows “Waiting for Remote”.

  • Logically, since the assignee on IFS side now has access on DTP, the sync should proceed. But it doesn’t.

Could you please help confirm if any other constraints or caching issues could be preventing that previously “waiting” ticket from progressing?

Thanks,
Mustafa

Hi @Mustafa ,

Is the DTP side Jira Cloud or Jira Data Center?

Thanks, Dhiren

Hi @Dhiren ,

DTP side Jira data center.

Best,
Mustafa

Hi Mustafa,

Thanks for the additional details — this makes the behavior much clearer.

Once a sync transaction enters the Waiting for Remote state, it means:

  • The payload has already been generated and pushed by the IFS node

  • The DTP node attempted to process it and failed

  • The same payload will not automatically be regenerated unless something on the source side triggers Exalate to build a new outgoing payload

Changing the assignee later does not retroactively fix the failed transaction.
This is expected, because:

  • The original payload still contains the original reporter value (the invalid one)

  • The target side already rejected the transaction once

  • Exalate will keep retrying with the same payload, unless a new transaction is created

So this isn’t caching — it’s a characteristic of how the Exalate queue works.

Thanks, Dhiren

Hi @Mustafa ,

Hope you are doing well.

Do you need any more details or are we good here?

Thanks, Dhiren