Open source tooling to automatically remove malicious calendar events when email security solutions quarantine ICS phishing attacks.
Stack-specific standalone scripts (e.g., proofpoint-microsoft365.py, mimecast-google-workspace.py) are
provided for each combination of these email security providers and calendar providers:
Email security providers:
- Proofpoint
- Mimecast
- Abnormal Security
Calendar providers:
- Microsoft 365
- Google Workspace
Go to Quickstart to get right to it!
Not seeing your stack? Don't hesitate to tell us what stack you want supported at opensource@sublimesecurity.com.
These scripts require an email security solution that is already detecting ICS phishing emails, but that is not removing the calendar events created through those emails.
If you don't have an email security solution detecting ICS phishing, Sublime Core offers free and self-hostable email security with built-in ICS phishing detection and automatic calendar remediation.
ICS phishing is a two-pronged attack that delivers malicious payloads to both a user's inbox and calendar simultaneously. This attack vector saw a ~100x increase from Q1 to Q4 2025, per Sublime's 2026 Email Threat Research Report, with over 20% of Q4 callback phishing attacks using calendar invites as a delivery mechanism.
The critical security gap: calendar events persist even when email security solutions quarantine or delete the malicious email. This affects both secure email gateways (SEGs) and API-based email security solutions, most of which do not clean up malicious calendar events as of February 2026.
These Python scripts automatically delete malicious calendar events when your email security solution quarantines ICS phishing emails. The scripts:
- Fetch quarantined messages from your email security provider
- Extract
.icscalendar attachments and other iCalendar-compliant attachments from those messages - Find and delete matching events from users' calendars (Microsoft 365 or Google Workspace)
These scripts are based on Sublime's built-in remediation of malicious calendar events.
As pure Python, you can run these scripts in many SOARs, including Tines, Splunk SOAR, and Cortex XSOAR.
We're also working on SOAR-specific guides. Please reach out to opensource@sublimesecurity.com if you need help or want to be notified when we publish documentation for a particular SOAR.
Each standalone script requires:
- A compatible runtime
- Environment variables containing API credentials
- Appropriate API permissions for your email security solution and calendar provider
You can run these scripts in any environment with:
- Python 3.9 or later
- Support for installing the PyPI packages listed in
requirements.txt(requestsandPyJWT)
For production deployments, you'll also want to schedule the script to run regularly, e.g., with a cron job.
The scripts run in dry-run mode by default to prevent accidental deletion of events. See configuration options for how to enable deletion and how to implement custom logic in response to discovery of malicious invitations and events.
export PROOFPOINT_CLIENT_ID="your-client-id"
export PROOFPOINT_CLIENT_SECRET="your-client-secret"PROOFPOINT_CLIENT_ID: OAuth 2.0 client ID for Proofpoint Cloud Threat Response APIPROOFPOINT_CLIENT_SECRET: OAuth 2.0 client secret
export MIMECAST_CLIENT_ID="your-client-id"
export MIMECAST_CLIENT_SECRET="your-client-secret"
export MIMECAST_REGION="global" # Options: global, us, uk (default: global)MIMECAST_CLIENT_ID: OAuth 2.0 client ID for Mimecast API 2.0MIMECAST_CLIENT_SECRET: OAuth 2.0 client secretMIMECAST_REGION: API region endpoint (optional, defaults to global)
Required API Permissions:
Services | Threat Remediation | ReadGateway | Tracking | ReadArchive | Read
export ABNORMAL_API_KEY="your-api-key"ABNORMAL_API_KEY: API key from Abnormal Security platform
# Option 1: Service Account File
export GOOGLE_SERVICE_ACCOUNT_FILE="/path/to/service-account.json"
# Option 2: Service Account JSON (inline)
export GOOGLE_SERVICE_ACCOUNT_JSON='{"type":"service_account",...}'GOOGLE_SERVICE_ACCOUNT_FILE: Path to service account JSON key fileGOOGLE_SERVICE_ACCOUNT_JSON: Inline service account credentials as JSON string
Required Setup:
- Enable domain-wide delegation for the service account
- Authorize scope:
https://www.googleapis.com/auth/calendar.events - Configure in Google Workspace Admin Console
export MICROSOFT_CLIENT_ID="your-client-id"
export MICROSOFT_CLIENT_SECRET="your-client-secret"
export MICROSOFT_TENANT_ID="your-tenant-id"MICROSOFT_CLIENT_ID: Azure AD application (client) IDMICROSOFT_CLIENT_SECRET: Azure AD application client secretMICROSOFT_TENANT_ID: Azure AD directory (tenant) ID
Required API Permission: Calendars.ReadWrite (Application permission)
export ICS_PHISHING_REMEDIATION_MODE="dry_run" # "dry_run" is default
export MESSAGE_LOOKBACK_MINUTES=10
export PROOFPOINT_CLIENT_ID="your-client-id"
export PROOFPOINT_CLIENT_SECRET="your-secret"
export MICROSOFT_TENANT_ID="your-tenant"
export MICROSOFT_CLIENT_ID="your-client"
export MICROSOFT_CLIENT_SECRET="your-secret"
python3 proofpoint-microsoft365.pyBy default, all scripts run in dry-run mode to prevent accidental deletions. In this mode, the script will:
- Fetch quarantined emails and extract calendar invitations
- Search for matching calendar events
- Log what events would be deleted without actually deleting anything
This allows you to verify the script is working correctly before enabling actual deletion.
To actually delete calendar events, set the ICS_PHISHING_REMEDIATION_MODE environment variable:
export ICS_PHISHING_REMEDIATION_MODE="delete_events"Valid values:
dry_run(default) - Preview actions without deletingdelete_events- Actually delete matching calendar events
Invalid values will raise an error to prevent misconfiguration.
All scripts search for quarantined messages within a configurable time window:
export MESSAGE_LOOKBACK_MINUTES=10 # Optional, defaults to 5 minutesImportant: This value should match your cron schedule frequency with a small buffer to ensure no messages are missed. For example, if running every 5 minutes, set the lookback window to 10 minutes.
For additional integrations, such as with logging systems or monitoring tools, you can implement custom callbacks in
your script and pass them to the delete_events_from_remediated_emails function:
on_invitation_found_callback(invitation: CalendarInvitation)- Called when a calendar invitation is found in a quarantined messageon_event_found_callback(invitation: CalendarInvitation, event: CalendarEvent)- Called for each matching calendar event
Example:
def log_invitation(invitation):
print(f"Found malicious invitation for {invitation.user_id}, UID: {invitation.ics_uid}")
def log_event(invitation, event):
print(f"Found calendar event {event.id} matching invitation {invitation.ics_uid}")
fetcher = ProofpointCloudFetcher()
deleter = GoogleWorkspaceEventDeleter()
delete_events_from_remediated_emails(
fetcher,
deleter,
mode="delete_events", # Override default dry_run mode
on_invitation_found_callback=log_invitation,
on_event_found_callback=log_event
)Note: Errors in callbacks are logged but do not stop event processing.
All scripts follow a common pattern defined in common.py:
class MessageFetcher:
def yield_remediated_emails(self) -> Iterator[Message]:
"""Fetch quarantined messages from your email security solution"""
class EventDeleter:
def delete_matching_events(
self,
invitation: CalendarInvitation,
mode: Mode,
on_event_found_callback: Optional[Callable[[CalendarInvitation, CalendarEvent], None]]
) -> None:
"""Delete calendar events matching the ICS attachment"""Stack-specific implementations handle API authentication and provider-specific logic.
- Questions, feature requests, or bug reports: opensource@sublimesecurity.com
- SOAR integration guides: Contact us at opensource@sublimesecurity.com for early access to detailed deployment guides for your SOAR platform
- Threat intelligence: Read our ICS phishing blog post and 2026 Email Threat Research Report