Security: Attachment Exporter
Last updated: 12 November 2026
This page describes how Attachment Exporter protects your HubSpot account and the files it handles.
Least privilege
- The app asks for read-only permissions:
files.read,files.ui_hidden.read,crm.objects.contacts.read,crm.objects.companies.read,crm.objects.deals.read,crm.objects.tickets.read,crm.lists.readandsales-email-read, plusoauthfor the sign-in. It cannot create, change or delete anything in your HubSpot account. - It does not ask for the permission HubSpot uses to download files
marked sensitive. Such files are listed as
restrictedand not copied. - The hidden-files permission is needed because HubSpot stores the attachments of notes and emails as hidden files.
Authentication and request integrity
- The app connects to HubSpot through OAuth. HubSpot shows the requested permissions before you connect.
- Every request from the app’s settings page and card to our backend carries HubSpot’s signature (X-HubSpot-Signature-v3). The backend checks it with the app’s client secret and rejects requests that are unsigned, changed or older than five minutes. The HubSpot account and user come from the signed request, never from the request body.
- Only app admins (at first, the installer) can scan, export, buy packs and change settings. The record card is open to every user of the account (the app cannot see HubSpot’s per-record permissions), limited to 300 files per record and 40 downloads per account per day.
- Stripe webhooks are verified with Stripe’s signature.
Files and download links
- Zips and manifests are stored in a private bucket. There is no public listing and no public URL.
- A download link is signed with an HMAC, carries the account, the export and an expiry, and is checked against the export on every request. It expires after 7 days at the latest, and stops working when the export is deleted or the app is uninstalled. Anyone who holds a link can download that file, so do not share it.
- Files are streamed from HubSpot into the zip; a large file is not loaded into memory.
- Names inside the zip are normalised and made safe (no path separators or control characters). The manifest CSV protects against spreadsheet formula injection: a cell that starts with = + - @, a tab or a line break is written as text.
- Our logs hold no file contents and no file or record names.
Data protection
- OAuth tokens are encrypted at rest with AES-256-GCM, with the HubSpot account ID bound to each ciphertext so it cannot be used for another account. The key is a Cloudflare secret, separate from the database.
- Every database query is limited to the HubSpot account from the verified request.
- All traffic uses TLS. Hosting is on Cloudflare Workers with a D1 database, R2 storage and Queues.
- The app stores no card numbers or bank details.
Reliability
- Jobs run in background queues and save their progress. If a worker stops, the job continues without fetching finished files again, and downloads are retried a few times with a delay before a file is marked failed.
- The app keeps below HubSpot’s API rate limit and honours Retry-After.
- Files that fail are credited back.
Uninstall and deletion
Uninstalling stops running jobs, deletes zips, manifests and job data, and removes the tokens. See privacy and data for the periods.
Reporting a vulnerability
Email support@kayabyte.dev with the subject “Security”. We confirm receipt within one business day. Please do not test against accounts you do not own.
See also the data processing agreement, sub-processors, privacy and data and the privacy policy.