Skip to main content

Strip personal data from iCalendar files while preserving technical properties for bug reproduction

Project description

icalendar-anonymizer

Strip personal data from iCalendar files while preserving technical properties for bug reproduction.

Calendar bugs are hard to reproduce without actual calendar data, but people can't share their calendars publicly due to privacy concerns. This tool uses hash-based anonymization to remove sensitive information (names, emails, locations, descriptions) while keeping all date/time, recurrence, and timezone data intact.

Tests codecov PyPI version Python versions Docker pulls License: AGPL-3.0-or-later Ruff

Installation

# Library only
pip install icalendar-anonymizer

# With CLI tool
pip install icalendar-anonymizer[cli]

# With web service
pip install icalendar-anonymizer[web]

# Everything
pip install icalendar-anonymizer[all]

Docker:

docker-compose up -d

From source:

git clone https://github.com/mergecal/icalendar-anonymizer.git
cd icalendar-anonymizer
pip install -e ".[dev]"

Usage

Python API

from icalendar import Calendar
from icalendar_anonymizer import anonymize

# Load calendar
with open('calendar.ics', 'rb') as f:
    cal = Calendar.from_ical(f.read())

# Anonymize
anonymized_cal = anonymize(cal)

# Preserve specific properties (e.g., CATEGORIES for bug reproduction)
anonymized_cal = anonymize(cal, preserve={"CATEGORIES", "LOCATION"})

# Deterministic output with fixed salt
salt = b"reproducible-salt-for-testing"
anonymized_cal = anonymize(cal, salt=salt)

# Save
with open('anonymized.ics', 'wb') as f:
    f.write(anonymized_cal.to_ical())

Command Line

# Basic usage
icalendar-anonymize input.ics -o output.ics

# Shorter alias
ican input.ics -o output.ics

# Unix-style piping
cat calendar.ics | icalendar-anonymize > anonymized.ics

# Stdout by default
icalendar-anonymize calendar.ics

Options:

  • -i, --input FILE - Input file (default: stdin)
  • -o, --output FILE - Output file (default: stdout)
  • -v, --verbose - Show processing details
  • --version - Print version

Web Service

# POST with ICS content
curl -X POST https://anonymizer.example.com/anonymize \
     -H "Content-Type: application/json" \
     -d '{"ics": "BEGIN:VCALENDAR..."}'

# Upload ICS file
curl -X POST https://anonymizer.example.com/upload \
     -F "file=@calendar.ics"

# Fetch and anonymize URL
curl "https://anonymizer.example.com/fetch?url=https://example.com/cal.ics"

FastAPI provides interactive docs at /docs for testing.

Self-hosting:

docker-compose up -d

Runs on port 8000 by default. Includes SSRF protection (blocks localhost and private IPs), 10-second timeout, and 10MB max file size.

How It Works

Hash-based anonymization - Same input always produces the same output, preserving patterns for bug analysis.

Structure preservation - A 10-word summary stays 10 words. Emails still look like emails.

What gets anonymized:

  • SUMMARY, DESCRIPTION, LOCATION
  • ATTENDEE, ORGANIZER (including CN fields)
  • COMMENT, CONTACT
  • Unknown/X- properties (safe by default)

What stays intact:

  • DTSTART, DTEND, DUE, DURATION, DTSTAMP
  • RRULE, RDATE, EXDATE
  • VTIMEZONE, TZID, TZOFFSETFROM, TZOFFSETTO
  • UID (hashed but unique)
  • SEQUENCE, STATUS, TRANSP, CLASS, PRIORITY

Custom preservation: Use preserve parameter to keep specific properties:

anonymize(cal, preserve={"CATEGORIES", "COMMENT"})

User responsibility to ensure preserved properties don't contain sensitive data.

Contributing

See CONTRIBUTING.md for development workflow, commit format, and testing requirements.

License

AGPL-3.0-or-later. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

icalendar_anonymizer-0.1.0.tar.gz (39.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

icalendar_anonymizer-0.1.0-py3-none-any.whl (29.4 kB view details)

Uploaded Python 3

File details

Details for the file icalendar_anonymizer-0.1.0.tar.gz.

File metadata

  • Download URL: icalendar_anonymizer-0.1.0.tar.gz
  • Upload date:
  • Size: 39.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for icalendar_anonymizer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 215a830ef77a9665be36fc63ecdc34946d62f3c144fa92c1ba8535234cac88d5
MD5 d7cf8219179ca8651266a2189f15977d
BLAKE2b-256 87b943965cd15cd821a871613434548165d3fe014954563e95e7c951268ffeb5

See more details on using hashes here.

Provenance

The following attestation bundles were made for icalendar_anonymizer-0.1.0.tar.gz:

Publisher: publish.yml on mergecal/icalendar-anonymizer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file icalendar_anonymizer-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for icalendar_anonymizer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 92dd87a9c530afff642177ce1945660d9e1343a94cb376cb185175fdf9b49092
MD5 eb08136c84175998c46a9d0e254d5c67
BLAKE2b-256 6e0930e95fd54f3e1f3a8d42618c7652f3f5cba1911404a910606e161d0b4f09

See more details on using hashes here.

Provenance

The following attestation bundles were made for icalendar_anonymizer-0.1.0-py3-none-any.whl:

Publisher: publish.yml on mergecal/icalendar-anonymizer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page