Skip to content

Setup guide & documentation

Overview

Request → approval → Workflow Automator Web Request → app checks addresses in Microsoft 365 → applies the change in Exchange Online → private note, status, optional reply.

Before you start

  • Freshservice with the Service Catalog and Workflow Automator (Web Request step).
  • Microsoft 365 with Exchange Online (cloud mailboxes; on-premises Exchange isn't supported).
  • A Microsoft 365 Global Administrator for the one-time Entra setup (about 10 minutes).
  • A Freshservice agent API key for an agent who can edit the relevant tickets.
  • About 30 minutes for the full setup.

Step 1 – Microsoft Entra app registration

Open entra.microsoft.com as a Global Administrator.

  • a. App registrations → New registration: any name (e.g. "Freshservice M365 Permissions"), "Accounts in this organizational directory only", no redirect URI → Register.
  • b. API permissions → Add a permission → APIs my organization uses → "Office 365 Exchange Online" → Application permissions → Exchange.ManageAsApp → Add permissions → Grant admin consent (green tick).
  • c. Roles & admins (under Entra ID, not inside the app registration) → Exchange Recipient Administrator → Add assignments → select the app → Active, Permanently assigned → Assign. Can take up to an hour.
  • d. Sign-in credential – choose one. Client secret: Certificates & secrets → New client secret → copy the Value (not the Secret ID); shown once. Note the expiry date.
  • Certificate (recommended): create a key and certificate, upload the public certificate (.crt/.cer) under Certificates → Upload certificate, note the Thumbprint and expiry. Upload the .crt/.cer; the .key.pem goes into the app, then delete it.
  • e. Copy the Directory (tenant) ID and Application (client) ID from the app’s Overview, and the tenant domain ending in .onmicrosoft.com (Entra ID → Domain names).

Mac/Linux

openssl req -x509 -newkey rsa:2048 -nodes -days 730 -subj "/CN=Freshservice M365 Permissions" -keyout freshservice-m365.key.pem -out freshservice-m365.crt

Windows – PowerShell 7

$rsa = [System.Security.Cryptography.RSA]::Create(2048)
$req = [System.Security.Cryptography.X509Certificates.CertificateRequest]::new('CN=Freshservice M365 Permissions', $rsa, [System.Security.Cryptography.HashAlgorithmName]::SHA256, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1)
$cert = $req.CreateSelfSigned((Get-Date).AddMinutes(-5), (Get-Date).AddYears(2))
[IO.File]::WriteAllBytes("$PWD/freshservice-m365.cer", $cert.Export('Cert'))
"-----BEGIN PRIVATE KEY-----`n" + [Convert]::ToBase64String($rsa.ExportPkcs8PrivateKey(), 'InsertLineBreaks') + "`n-----END PRIVATE KEY-----" | Set-Content -NoNewline "$PWD/freshservice-m365.key.pem"
$cert.Thumbprint

Step 2 – Freshservice API key

Admin → Agents → the agent → Permissions → enable API key; copy it from Profile settings → Your API key.

Step 3 – Service item (the request form)

Admin → Service Catalog → New Item "Mailbox & calendar access".

Fields: Action (Dropdown: Grant, Remove), Permission (Dropdown or multi-select, e.g. Full Access, Send As, Send on Behalf, Calendar - Reviewer, Calendar - Editor, Calendar - Delegate (incl. private)), User needing access, Target mailbox.

User and mailbox fields can be a Freshservice user picker (Dropdown → Select from Data Source → All Users) or a single-line text field for an email address; the app recognises both. A picked person becomes their work email (primary first, then secondary emails). You can use both on one form (e.g. picker + text field) – list both names in the settings, picker first.

Optional: separate items for mailbox and calendar access, each with its own wording and approval.

Internal field names: the label in lower case with underscores (e.g. "User needing access" → user_needing_access). Check them by raising a test request and opening https://yourcompany.freshservice.com/api/v2/tickets/<ticket_id>/requested_items while signed in.

Step 4 – Install the app and fill in the settings

1Microsoft 365 connectionCloud, tenant ID, tenant domain, client ID, secret or certificate → Test connection
2Freshservice connectionyourcompany.freshservice.com + API key → Test connection & load groups
3How the app startsAllow workflows, copy the webhook secret – shown only until you save; only apply approved requests; optional trigger groups/statuses
4Service item fieldsComma-separated names allowed
5PermissionsTurn off what you never want automated; your own wording
6RulesProtected mailboxes, tenant domains only, change limit, dry run
7After the app runsStatuses for success/warnings/failure, fallback group, reply to requester
8Mailbox & calendar optionsOutlook auto-mapping, calendar invitations
9Alerts & monitoringResult field, Teams/Slack/Power Automate webhook, expiry date, test alert
10Recent runsReview recent results

Step 5 – Workflow Automator

Admin → Workflow Automator → New Automator → Module: Tickets, Event Based Workflow. Event: Service Request is Raised. Condition: Requested items includes any → your item(s). Approval block.

On Approved, a Web Request: Request Type POST; Endpoint = the webhook URL (app settings, section 3, after installing); Credentials → API key, Key = X-Webhook-Secret, Value = the webhook secret; Header Content-Type: application/json. Save and Activate.

Workflows don't notify apps directly, so the Web Request is what starts the app.

Optional body fields for workflows without a service item: "action", "permission", "mailbox", "user"; add "dry_run": true to test a workflow.

Body

{"ticket_id": "{{ticket.id}}"}

Step 6 – Test with Dry run

Turn on Dry run in section 6, raise a test service request and approve it. Check the private note for the intended changes and any warnings; no permissions are changed.

When the result is correct, turn off Dry run and repeat the request. Check Exchange Online and the ticket note; Outlook can take up to an hour to reflect access.

What the results look like

The private note lists each change with ✅/❌, names and addresses, warnings and how to retry. The app updates statuses, assigns the fallback group when needed, and can reply to the requester.

Optional M365 result field values: Processing, Succeeded, Succeeded with warnings, Failed, Blocked, Dry run.

Alerts & monitoring

Alerts when the app stops working (once, then daily), when it recovers, on rejected workflow calls, optionally on every failed request; reminders 30/14/7/1 days before the secret or certificate expires; daily health check.

Updating vs reinstalling

An update keeps all settings, secrets, the webhook URL and secret (open the settings and click Save). Uninstalling and reinstalling creates a new webhook URL and secret and needs the settings again.

Renewing credentials

Create the new secret/certificate before the old one expires (both work meanwhile), enter it in section 1, update the expiry date, save, then delete the old one in Entra.

Troubleshooting

“This request isn't approved”Add an Approval step or untick “Only apply approved requests”.
“… was not found in Microsoft 365”Typo or the person has left – use the suggestion.
“… has no email address in this Microsoft 365 tenant”Add their work email to their Freshservice profile.
“Exchange returned 403”Assign the Exchange Recipient Administrator role (allow up to an hour).
“Webhook rejected”Copy the endpoint and secret again.
“Not attempted: time limit”Trigger again – changes already made are kept.
The Freshservice domain must be your yourcompany.freshservice.com addressEnter the freshservice.com domain.
"Not tested" on the settings page during an app updateExpected, save and test again afterwards.
Couldn't be checked in Microsoft 365 right nowExchange was busy, try again.
User … is a guest/distribution group/shared mailboxGive access to the person or a mail-enabled security group.
Nothing happens when a request is raisedIs the workflow activated and does it include the Web Request with the right URL and secret?