Secure Outlook Calendar CLI for AI Agents
Microsoft Graph's Calendars.ReadWrite permission exposes every calendar, every event, and every attendee in your Microsoft 365 tenant. The Secure Outlook Calendar CLI puts precise, scriptable boundaries on what AI agents can access.
Connect PortEden to Outlook Calendar (CLI)
npx @porteden/cli connect outlook-calendarRead full CLI setup docsHow PortEden Protects You
Six layers of security between AI and your data.
Graph API Calendar Scoping
Restrict which Outlook calendars each AI agent can access, with the CLI filtering Graph API responses to include only explicitly allowed calendars.
Attendee Redaction
Strip attendee names, emails, and response statuses from calendar event responses before they reach the agent.
Meeting Body Filtering
Control whether agents see the full meeting body, a stripped-text version, or no body at all.
Read-Only Calendar Enforcement
Enforce read-only access for agents even when the underlying Graph API token has Calendars.ReadWrite permissions.
Shared calendars, room resources, and the Graph delegated-permission trap
Where Google Calendar exposes ~10 calendars per user, a typical M365 user has access to 50+ — direct delegates, department-shared calendars, room resources, equipment resources, and ex-employee mailboxes that were never reclaimed. The Graph endpoint GET /me/calendars?$top=100 returns every one. List them first:
$ porteden outlook-calendar list
NAME OWNER PERMISSIONS
Calendar adam@porteden.com Owner
Boardroom A rooms@porteden.com FreeBusyRead
Eng Standup eng-leads@porteden.com Read
RecruitingShared hr@porteden.com Write ⚠
ExEmployee_2024_07 (delegate) leaver@porteden.com FullAccess ⚠The two calendars marked ⚠ are the kind of thing that ends up in incident post-mortems: an agent helping you book a meeting stumbles into the recruiting calendar and reads candidate interview slots, or worse, the un-offboarded mailbox of a departed exec. The CLI's explicit allowlist makes both impossible:
agents:
scheduler:
calendar_allowlist:
- "Calendar" # only the user's primary
- "Boardroom A" # rooms ok
strip_attendees: true # response.attendees = []
strip_body: true # response.body.content = ""
delta: true # use /calendarView/delta
write_mode: deny # Calendars.ReadWrite → effectively .ReadRoom-resource booking restrictions
Room mailboxes (Type: Room) and equipment mailboxes (Type: Equipment) auto-accept meetings based on calendar processing rules. An agent with Calendars.ReadWrite can book — or worse, double-book — every conference room in the tenant. Set write_mode: deny for room resources, or scope booking to specific floors/buildings via a room_allowlist pattern.
Why /calendarView, not /events
/calendarView expands recurring events into instances automatically and respects $top pagination. /events returns recurrence masters that the client then has to expand — and most agent clients get it wrong. The CLI rewrites /events requests to /calendarView behind the scenes, which fixes a whole class of "the agent missed my recurring 1:1" tickets.
Get Started in 3 Steps
Install and Connect
Install the PortEden CLI with npm and authenticate with your Microsoft 365 account via OAuth.
Configure Calendar Rules
Define which calendars agents can access, what event fields they see, and what time range they can query.
Route and Audit
Point your AI agents to the PortEden proxy so every Graph API calendar call is filtered through your config with full audit logging.
Without vs. With PortEden
Without PortEden
- Calendars.ReadWrite exposes every calendar and event in the tenant
- Attendee lists with email addresses visible to any agent with calendar access
- Meeting bodies with agendas and internal links fully exposed
- Azure AD calendar policies require manual portal configuration
With PortEden
- Per-calendar access controls limit agents to allowed calendars only
- Attendee information stripped from event responses before agents see them
- Meeting body filtering removes sensitive content automatically
- Calendar rules defined in code and deployed via CI/CD pipelines