Transparency

Security & Privacy

How JoinCal handles your calendar data — written in plain language, not legalese. Last updated: May 2026.

1. What we access

JoinCal requests the minimum OAuth scopes needed for each provider. We never ask for access to your email, contacts, or any data outside your calendar.

  • Google Calendar: calendar.readonly and calendar.events (write-back only)
  • Microsoft Outlook: Calendars.Read (and Calendars.ReadWrite for write-back)
  • Apple iCloud / CalDAV: Read-only CalDAV access to your selected calendars
  • Yahoo / GMX / ICS feeds: Read-only URL fetch — no OAuth at all

If you revoke JoinCal's access in your provider's security settings, we immediately stop syncing that account and mark it as needing re-authorisation.

2. How tokens are stored

OAuth access and refresh tokens are encrypted with AES-256-GCM before being written to the database. Each token has a unique 96-bit IV and a 128-bit authentication tag — providing both confidentiality and tamper detection.

The encryption key is stored only in environment variables and never appears in the codebase or database. A database breach does not expose usable tokens. Share-link passwords are stored as HMAC-SHA256 hashes using a separate secret, never in plaintext.

3. What calendar data we store

Events are synced to our database for fast rendering and sharing. We store:

  • iCalUID (provider's unique event identifier)
  • Title, start/end time (UTC), all-day flag
  • Location, description, conference URL (Zoom/Meet link)
  • Organiser display name and email

We do not store free-form attachments, attendee lists beyond the organiser, or any fields outside the above.

4. Sharing and permission enforcement

JoinCal enforces three permission levels on every shared calendar response — server-side, before data leaves our API:

  • Free/busy: Only the time slot is returned. Title, location, and description are stripped.
  • Titles only: Time slot and event title. Location and description are stripped.
  • Full details: All stored fields are returned.

This filter is applied in code on every API response. It cannot be bypassed by the client. Share links can be revoked instantly — revocation takes effect on the next request.

5. Audit trail

Every share-link access, permission change, invite sent, and link creation is written to an append-only audit log. Each entry records: timestamp, action type, IP address (first IP from the forwarding chain), user-agent string, and permission level at time of access.

Audit logs are visible to the calendar owner in their dashboard settings.

6. Data deletion

You control your data:

  • Disconnecting a calendar account immediately stops syncing and deletes all synced events for that account.
  • Deleting a combined calendar removes all associated share links, invites, and audit log entries.
  • Deleting your JoinCal account removes all your data permanently — connected accounts, synced events, calendars, share links, and audit logs.

We do not retain your data after deletion. There are no backups that persist calendar content beyond our standard database backup window (7 days), after which deleted data is unrecoverable.

7. What we don't do

  • We do not show ads or use calendar data for advertising.
  • We do not sell or share your calendar data with third parties.
  • We do not run machine learning models on your calendar content.
  • We do not store data beyond what is necessary for sync-and-share.
  • We do not have access to any data outside your calendar (no email, no contacts).

8. Incident response

In the event of a security incident affecting user data, we will notify affected users within 72 hours by email with details of what was affected and what steps we've taken.

Because OAuth tokens are encrypted at rest, a database breach does not automatically give an attacker usable calendar access. Our primary response to a database compromise is to rotate the encryption key — invalidating all stored tokens. To report a vulnerability, email . We aim to respond within 24 hours. security@joincal.net.

Questions about how JoinCal handles your data? privacy@joincal.net