Sync between a read only Exchange and a CalDav server, anonymizing the actual appointments by reducing them to a time frame and a dummy name.
Go to file
Andreas Schneider 765f8fc077 Added build script 2018-04-08 21:37:38 +02:00
src/calanonsync Implemented whitelist (fixed #4) 2018-04-06 22:03:39 +02:00
.gitignore Fixed negotiation offsets 2018-04-03 12:02:23 +02:00 Added license 2018-04-02 10:51:25 +02:00 Added README 2018-04-02 15:49:54 +02:00
build.go Added build script 2018-04-08 21:37:38 +02:00


This tool is used to sync between a read only Exchange server and a CalDAV server, anonymizing the actual appointments by reducing them to a time frame and (optionally) a dummy name.


The idea is, that an intranet Exchange server stores appointments relevant for work and therefore at least partially protected by NDAs or similar agreements. To still be able to know when one has an appointment while looking at a private, non corporate owned device, this tool was born.


CalAnonSync works pretty straight forward. It retrieves a list of all events from the given Exchange server using the EWS API. To be able to have some history but most importantly some view into the future, the events from the last month and the next two months will be retrieved.

Next, all events from the CalDAV server will be retrieved. All (yes, all) events, that are not known to the EWS server will be deleted from the CalDAV calendar. (It is therefore advised to use a dedicated CalDAV calendar; most providers allow to create multiple calendars.)

All existing events are synchronized by start and end time only. Other attributes stay untouched. It is therefore to your free liking to enhance each event manually.

All missing events get created on the CalDAV server. The following rules apply:

  • If the Exchange event is marked as "all day", CalAnonSync will try to mark the CalDAV event as "all day" as well. This will only work if the appointment is in your local timezone.
  • Timezone information are dropped. All event date/times are normalized to UTC. Since Exchange shall be the master of the appointments, this should not matter (since timezones are mostly relevant for moving and copying events as well as for recurring events).
  • Recurring events are converted into a bunch of single events. Therefore Exchange can apply all the rules it likes.
  • Cancelled or private events are considered "non existant" (i.e. they are neither created nor are they kept on the CalDAV server if they were there before).
  • If the config setting "Anonymize.Title" is set to a non empty string, the title (=summary) of the event is set to that string. Otherwise it is kept as it was in Exchange.

CalAnonSync synchronized one-way only. Exchange is the master, CalDAV the slave. If an event vanished from Exchange, it vanishes from CalDAV.


A config file named calanonsync.json is opened from the working directory. It has the following structure:

  "EWS": {
    "URL": "",
    "Username": "",
    "Password": "appkey"
  "CalDAV": {
    "URL": "https://path/to/a/caldav/resource",
    "Username": "myuser",
    "Password": ""
  "Anonymize": {
    "Title": "#Work"

Both passwords are optional. If they are left blank, CalAnonSync will prompt for the password upon startup. (Recommended for security reasons!)

The CalDAV URL should point to the URL of a dedicated calendar. Beware that CalAnonSync will remove all events from that calendar that are not known to Exchange.