The short version
- Scans go from the copier to one office PC, and from that PC straight to Microsoft Graph. They never pass through my servers.
- It asks Microsoft for three delegated permissions: Mail.Send, User.Read and offline_access. None of them lets it read anyone's mail.
- The only thing it ever sends me is a license key, once, when you type it in.
- The Microsoft sign-in is stored on that PC, encrypted with Windows DPAPI.
- Two things aren't done yet: the program isn't code-signed, so Windows SmartScreen will warn you, and the publisher isn't verified with Microsoft, so an admin has to approve the app once per organization.
Microsoft 365 permissions
Scan Relay signs in to a single work or school mailbox through Microsoft's own sign-in page. Click Sign in with Microsoft on the setup page, sign in in the browser on that PC, with MFA if your organization uses it, and Microsoft hands Scan Relay a token, so it never sees the password. This standard browser sign-in (authorization code with PKCE) works with Microsoft's security defaults, which block the older "enter a code" device sign-in. It only accepts work or school accounts, not personal Microsoft accounts.
It asks for these delegated permissions and no others:
| Permission | What Scan Relay uses it for |
|---|---|
| Mail.Send | Sending each scan as the signed-in mailbox. That's the only mailbox it can send as. |
| User.Read | Reading the signed-in account's email address once, after sign-in, so it knows which address to send from and can show it on the setup page. |
| offline_access | Getting a refresh token, so it keeps sending after the PC restarts without anyone signing in again. |
They're delegated permissions, not application permissions, so Scan Relay acts only as the one mailbox that signed in. It asks for no permission to read mail, contacts, calendars or files. I'd suggest a dedicated scanner mailbox, which most offices already have for the copier.
Before sending, Scan Relay sets the From address to the signed-in mailbox, because Microsoft 365 won't send as anyone else. It keeps the display name the copier used (or "Scanner"), removes the Sender and Return-Path headers, and adds any recipients the copier gave only in the SMTP envelope as Bcc. Each scan goes to Microsoft as one complete message, which Microsoft accepts up to about 3 MB with Mail.Send.
Scan size: with these permissions, Scan Relay sends scans up to about 3 MB per email. Set the copier's maximum email size (often called "split email by size" or a data size limit) to 3 MB, so bigger jobs arrive as several emails; if a scan still lands in the failed folder with a size message, try 2 MB, because some copiers count the file before it is encoded. Larger single emails need an option that isn't released yet, so don't plan on them.
Why an admin has to approve it once
Scan Relay's publisher (LeDuc Systems) isn't verified with Microsoft yet. In most organizations Microsoft won't let ordinary users approve an app from an unverified publisher, so the first sign-in shows "Need admin approval". A Microsoft 365 admin signs in once with the same button and ticks Consent on behalf of your organization. After that, any mailbox in the organization can be used. The consent screen lists the three permissions above.
Where your scans go
- Copier to the PC. The copier sends plain SMTP over your local network to the Scan Relay PC, on port 25, 587 or 2525 (you pick one on the setup page). This leg is not encrypted: Scan Relay doesn't offer TLS to the copier. It refuses connections from any address that isn't loopback, a private range (10.x, 172.16-31.x, 192.168.x, IPv6 unique-local) or link-local.
- The PC to Microsoft. Scan Relay sends each message over HTTPS to
graph.microsoft.com, and signs in throughlogin.microsoftonline.com.
That's the whole path. There's no LeDuc Systems relay or cloud service in between.
One thing to know: the copier-facing side accepts any username and password, because copiers that insist on one need something to type. In practice, any device on your local network that can reach the PC can send mail through it, as the signed-in mailbox, to any address. It accepts up to 100 recipients and 60 MB per message. Treat it as an internal relay: keep it on a trusted network, and use a scanner mailbox rather than a person's.
What it sends to LeDuc Systems
Exactly one thing, and only when someone enters a license key on the setup page: an HTTPS request to https://convert.leducsystems.com/api/license/<your key>. The key is the only thing in the request. The server answers whether the key is valid and which product it's for. Like any web server, mine sees the public IP address the request comes from, and its request log records it along with the request. Once a key is accepted, Scan Relay doesn't check it again.
Scan Relay has no telemetry, crash reporting, analytics or automatic update check. The 14-day trial is counted on the PC from the date it first ran; nothing is sent for that.
Separately, the download button on my website goes through convert.leducsystems.com/api/dl/scan-relay before it redirects to the file, so I can count downloads. That records the time, the product and the page you clicked from (plus the IP address in the server's request log). That's your browser downloading, not Scan Relay itself.
Where the sign-in is stored
Settings are in %ProgramData%\Scan Relay\config.json (normally C:\ProgramData\Scan Relay\config.json). It holds the port, the signed-in address, the license key, the trial start date and the Microsoft refresh token.
The refresh token is encrypted with Windows DPAPI in machine scope before it's written, then stored as base64. Machine scope means it can only be decrypted on that PC, so a copy of the file is useless anywhere else. It also means any program running on that PC that can read the file could decrypt it. So treat the PC like any machine that holds a service credential, and limit who can sign in to it. The short-lived access token is only kept in memory.
Sign out on the setup page deletes the refresh token and the account address from the file.
The retry queue
Every scan is written to disk before the copier is told it was accepted, so a dropped connection or a Microsoft outage doesn't lose it:
- Waiting scans are in
%ProgramData%\Scan Relay\queue\, one.emlfile (the message as the copier sent it) and one small.jsonfile (recipients, time received, attempts) per scan. They aren't encrypted, and each is deleted as soon as Microsoft accepts it. - It tries straight away, then once a minute.
- If the sign-in has expired, scans stay queued until someone signs in again on the setup page.
- If Microsoft rejects a scan outright (a 4xx error other than 401 or 429), or a scan has been failing for more than 72 hours since it arrived, Scan Relay stops trying and moves its
.emlfile to%ProgramData%\Scan Relay\failed\, where it stays until you delete it.
Scan Relay also keeps a log in %ProgramData%\Scan Relay\log.txt: times, the copier's IP address, recipient addresses, message sizes and errors. It's never sent anywhere.
What the installer changes
Double-clicking ScanRelay.exe asks for administrator permission (UAC), then:
- Copies itself to
C:\Program Files\Scan Relay\ScanRelay.exe. - Creates a Windows service named ScanRelay ("Scan Relay"), set to start automatically. It runs as the default service account (LocalSystem), and Windows restarts it if it stops unexpectedly (after 5 seconds, 30 seconds, then 2 minutes).
- Adds one inbound Windows Firewall rule, Scan Relay (copier mail): TCP ports 25, 587 and 2525, from the local subnet only, for that program only.
- Creates
%ProgramData%\Scan Relay\for its settings, queue and log. - Starts the service and opens the setup page in your browser.
That's all it changes: no browser extensions, no scheduled tasks, no other startup entries.
The setup page
The setup page is at http://localhost:2526. It listens on the PC's own loopback address only (127.0.0.1 and ::1), so it can't be reached from other computers, and the firewall rule doesn't include its port. It also has these guards:
- It refuses any request whose Host isn't
localhost:2526or127.0.0.1:2526, which stops DNS rebinding attacks from websites. - Anything that changes a setting (sign in, sign out, port, license, test message) must be a POST with a custom
X-Scan-Relayheader. Another website can't send that without a CORS preflight, and Scan Relay never answers one. - The one exception is Microsoft's redirect back after sign-in (
/auth/callback), which has to be a plain link. It only works with the single-use code Scan Relay created for that sign-in, which expires after 10 minutes. - The page sends a Content-Security-Policy that stops other sites from framing it.
It has no password of its own. Anyone signed in to that PC can open it, which is another reason to limit who can sign in to the PC.
Code signing and SmartScreen
ScanRelay.exe is not code-signed yet. Windows SmartScreen will warn that it's from an unrecognised publisher the first time it runs. To go ahead, click More info, then Run anyway. If your policy doesn't allow unsigned software, I understand. Email me and I'll tell you when a signed build is out.
Removing it cleanly
- Open
http://localhost:2526on the PC and click Sign out. That deletes the stored refresh token. - Run
"C:\Program Files\Scan Relay\ScanRelay.exe" uninstall(it asks for administrator permission). This stops and deletes the service and removes the firewall rule. - The uninstall deliberately keeps your settings in case you reinstall, and leaves the program file in place. To remove everything, delete
C:\Program Files\Scan Relay\andC:\ProgramData\Scan Relay\. The second folder holds any queued or failed scans and the log, so check it first. - Point the copier back at whatever it should use instead.
Revoking its access in Microsoft 365
Signing out on the PC deletes Scan Relay's copy of the token, but doesn't tell Microsoft. To cut off access from Microsoft's side as well:
- For the whole organization: in the Microsoft Entra admin center, go to Enterprise applications, open Scan Relay, and delete it or remove its granted permissions.
- For one mailbox: the user can remove Scan Relay from their apps in My Apps (myapps.microsoft.com), if your organization allows that. An admin can also revoke that user's sign-in sessions in Entra, which invalidates their refresh tokens, Scan Relay's included.
Microsoft moves these menus around from time to time. If the names don't match, look for "Enterprise applications" and "Permissions".
Questions IT people ask
Can Scan Relay read our mail?
No. It asks only for Mail.Send, User.Read and offline_access, and none of those lets it read messages. It sends each scan as one message and doesn't create drafts in the mailbox.
How big can a scan be?
About 3 MB per email. That's the most Microsoft accepts in one message sent with the Mail.Send permission. Set the copier's maximum email size, or "split email by size", to 3 MB (2 MB if a scan still fails), so a long job arrives as several emails. A scan that's too big isn't sent: it's kept in %ProgramData%Scan Relayailed and the error is in the log. Larger single emails need an option that isn't released yet.
Do scans or email addresses ever reach your servers?
No. The program's only request to my server is the license key check, and that carries the key and nothing else. Scans, recipients and the account address stay on the PC and go to Microsoft.
What if the PC is stolen or the disk is copied?
The refresh token is encrypted with DPAPI for that machine, so a copied file can't be decrypted elsewhere. Someone with the PC itself and a working sign-in to it is a different matter. If the PC goes missing, revoke Scan Relay's access in Entra as described above. Queued and failed scans on the disk aren't encrypted by Scan Relay, so full-disk encryption like BitLocker is worth having.
Can someone on the internet use it to send spam?
Not directly. It refuses connections from anything but private, loopback and link-local addresses, and the firewall rule only lets in the local subnet. But any device on your local network can send through it, so keep it on a network you trust.
Does it need inbound access from the internet, a static IP or DNS changes?
No. It only makes outgoing HTTPS connections to Microsoft and, once, to my license server.
What happens when the trial ends without a license?
The copier gets a "trial ended" error and new scans aren't accepted. Nothing is sent to me when the trial ends; the count is done on the PC.
Is the source code available?
Not publicly. If you're evaluating it for a client or a security review, email tyler@leducsystems.com with your questions and I'll answer from the code.
Scan Relay is made by LeDuc Systems LLC, an Arizona limited liability company in Phoenix, Arizona. Questions: tyler@leducsystems.com or (623) 320-5633. See also the privacy policy.