Hero
At a glance
| Hetk does | Hetk does not |
|---|---|
| Sync events between iCloud and Google or Microsoft 365 | Receive push notifications from iCloud (CalDAV has none) |
| Bi-directional or one-way | Sync attachments |
Honour iCal CLASS (public / private / confidential) | Sync reminders / VALARM |
| Preserve all-day events, recurrence (RRULE), attendees | Sync attendee RSVP / participation status |
Free / busy via TRANSP (TRANSPARENT / OPAQUE) | Sync per-event color or category tags |
| Mark synced events as “Busy” with title and details stripped | Use your main Apple ID password (app-specific password is required) |
| Detect updates via CTag + RFC 6578 sync-collection | Connect via OAuth (iCloud has no OAuth for calendar data) |
| Sign DPAs on request | Sync iCloud Reminders / Tasks (event calendars only) |
How sync works with iCloud
Authentication
- iCloud calendar access uses the CalDAV standard (a calendar-specific extension of WebDAV).
- iCloud requires an app-specific password for third-party calendar clients. Your normal Apple ID password will not work, and Hetk recommends app-specific passwords as a security best practice — they can be revoked individually without affecting your Apple ID.
- Generate an app-specific password at appleid.apple.com → Sign-In and Security → App-Specific Passwords.
- Hetk stores the app-specific password encrypted at rest in Azure SQL with TDE. It is used only to issue CalDAV requests against
caldav.icloud.com. - There is no OAuth flow for iCloud calendar data. (Hetk does support Sign in with Apple for the Hetk account itself, but Sign in with Apple does not grant calendar access.)
What Hetk reads and writes
- Reads: the calendars in your iCloud calendar home, and event data within the configured sync window.
- Writes: events into a target calendar that you explicitly chose during sync setup.
- Filters out: task-only collections (VTODO). Hetk syncs event calendars only.
- Does not access: iCloud Mail, Drive, Photos, Reminders, Notes, or any other iCloud service.
How updates propagate (polling, not push)
CalDAV has no push notifications. Hetk detects iCloud changes via a scheduled poll:
- CTag check — a cheap PROPFIND for the calendar’s collection tag. If unchanged, Hetk does nothing further for that calendar.
- Sync-collection (RFC 6578) — a CalDAV
REPORTreturns the hrefs of changed and deleted events since the last sync token. - Multiget — a CalDAV
REPORTfetches the full iCalendar data for the changed hrefs.
If iCloud rejects a sync token (returns 404 or 410 Gone), Hetk falls back to a full re-sync of that calendar.
Latency: minutes, not seconds. The polling cadence is configurable per environment; document the production value here once it stabilises.
Recipes
iCloud + Google
iCloud + Microsoft 365
iCloud + iCloud (multiple Apple IDs)
For privacy-conscious users and security reviewers
| Concern | How Hetk handles it |
|---|---|
| Credential type | App-specific password only. Hetk never asks for the main Apple ID password. |
| Credential storage | Encrypted at rest in Azure SQL with TDE. Used only for CalDAV requests to caldav.icloud.com. |
| Revocation | Revoke at appleid.apple.com → App-Specific Passwords. Revocation takes effect immediately. |
| Network endpoints | All CalDAV traffic goes to caldav.icloud.com over HTTPS. |
| Data residency | Azure App Service and Azure SQL, North Europe region. See /security/ for full detail. |
| Regional iCloud variants | Hetk uses the global caldav.icloud.com endpoint. China-region iCloud accounts are not in scope. |
| Push vs poll | iCloud has no push API for CalDAV. Sync is polled — latency is best-effort minutes, not seconds. |
| Optimistic concurrency | Updates use HTTP If-Match with the event ETag; on ETag mismatch, Hetk refetches and retries once. |
Privacy controls
“Mark as Private” mapping
When a sync relationship is configured to mark synced events as private, Hetk writes to the iCloud target as follows:
| Field | Source value | Target value (iCal) |
|---|---|---|
SUMMARY | “Q3 strategy review with Acme Corp” | “Busy” |
DESCRIPTION | (any) | (cleared) |
LOCATION | (any) | (cleared) |
ATTENDEE | (any) | (cleared) |
CLASS | PUBLIC / PRIVATE / CONFIDENTIAL | PRIVATE |
TRANSP | (preserved unless overridden) | (preserved unless overridden) |
Source sensitivity preservation
Without “Mark as Private”, the source CLASS value is preserved (RFC 5545 standard):
PUBLIC(or omitted) →PUBLICPRIVATE→PRIVATECONFIDENTIAL→CONFIDENTIAL
Fields synced and not synced
Synced
- Title (
SUMMARY), description (DESCRIPTION), location (LOCATION). - Start / end with timezone (
DTSTART/DTEND, including TZID). - All-day flag (inferred from value type).
- Organizer email (
ORGANIZER) — read; target shows the sync identity. - Attendee email list (
ATTENDEEmailto URIs). - Recurrence (
RRULE). - Sensitivity (
CLASS). - Free / busy (
TRANSP). - Status (
STATUS: confirmed / tentative / cancelled). - UID and SEQUENCE (incremented on each update per RFC 5545).
- ETag (HTTP header, used for optimistic concurrency).
Not synced
- Reminders / alarms (
VALARM). - Attachments (
ATTACH). - Conference data (Meet, Zoom, Teams join links).
- Categories and custom properties.
- Calendar color (returned by iCloud but not preserved through sync).
- Attendee participation status (
PARTSTAT).
Pricing
FAQ
Why does Hetk need an app-specific password?
Does iCloud sync in real time?
Does Hetk sync iCloud Reminders or Tasks?
Does Hetk sync shared iCloud calendars?
What happens if I change my Apple ID password?
How can I revoke Hetk’s access to iCloud?
Are China-region iCloud accounts supported?
Where is data stored?
For organisation security reviewers
For organisation security reviews, email [email protected]. Hetk will sign your DPA on request. Full security documentation: /security/.