Back to skill

Security audit

Granola Meeting Transcripts

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it advertises, but it uses Granola app tokens to bulk export private meeting data on a recurring schedule without enough scoping, storage hardening, or safeguards.

Review before installing. Use a protected local directory, avoid shared or synced folders unless intended, understand that Granola app tokens are reused to download meeting content, and remove or avoid the cron job if you do not want ongoing background sync. The package should ideally validate meeting IDs, set restrictive file permissions, add network timeouts, pin dependencies, and document how to disable scheduled sync.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sync.py:166
Finding

API-Controlled Meeting ID Allows Path Traversal Outside the Output Directory

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/sync.py:171
Finding

Sensitive Meeting Records Are Written Without Restrictive Filesystem Permissions

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:16
Finding

Installation Instructions Use an Unpinned and Unverified Third-Party Dependency

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/sync.py:62
Finding

Granola API Requests Can Block Indefinitely Because No Timeout Is Configured

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill documentation directs users to install dependencies, run a Python sync script, and configure a recurring cron job that performs network access and writes meeting data to local disk, yet the skill declares no permissions. This undermines transparency and informed consent because users and reviewers are not explicitly told that the skill has ongoing network and file-write capabilities over potentially sensitive meeting content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The setup instructions tell the user to sync cloud-hosted meeting transcripts and notes to a local directory and then schedule that sync every 6 hours, but they do not clearly warn that sensitive meeting content will be persistently written to disk on an ongoing basis. In the context of meeting transcripts and AI notes, this can expose confidential business or personal information to local compromise, backups, shared accounts, or accidental redistribution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation states that the sync script reads authentication from ~/Library/Application Support/Granola/supabase.json but does not explicitly warn that it is accessing locally stored auth tokens from the Granola app. Referencing an app credential store without clear disclosure is risky because it can normalize silent credential reuse and may surprise users who do not realize the skill is operating with bearer tokens tied to their account.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script exports highly sensitive meeting content, attendee information, transcripts, and notes to local files by default with no consent prompt, access-control guidance, or minimization. In an agent skill context, this broad bulk export increases the chance of unintended disclosure through shared machines, insecure backups, other tools reading the output directory, or accidental onward sharing.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The script reads an access token from Granola's local authentication store and uses it to access meeting data in bulk. In an agent skill, local credential harvesting is sensitive because it bypasses an explicit re-auth flow and enables broad access to private meetings if the script is run in a context where the user did not understand that their stored token would be consumed.

Content

Scanner excerpt · scripts/sync.py (reported line 37)May include surrounding context.

python
def get_token():
    """Get access token from Granola's local auth file."""
    if not SUPABASE_PATH.exists():
        print(f"Error: Auth file not found at {SUPABASE_PATH}")
        print("Make sure Granola is installed and you're signed in.")

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The code extracts and validates the access token from local storage, confirming that the skill actively leverages a resident credential to impersonate the user to the Granola API. This is dangerous in a skill context because compromise or misuse of the skill grants access to all meetings available to that token without additional user authorization barriers.

Content

Scanner excerpt · scripts/sync.py (reported line 50)May include surrounding context.

python
token = tokens.get("access_token")
    
    if not token:
        print("Error: No access token found. Try signing into Granola again.")
        sys.exit(1)
    
    # Check expiration

Static analysis

No suspicious patterns detected.