Security
Last updated: May 2, 2026
How we protect your HubSpot data. Everything on this page describes what is actually implemented today.
Compliance posture
- GDPR Article 28 — in force via our Data Processing Agreement.
- EU Cloud Code of Conduct (Self-Attestation) — self-attested (2026-04-30); attestation document.
- ISO 27001 (Annex A self-attestation) — in force; statement of applicability published.
Self-attestation is a structured assessment against publicly published frameworks — not a third-party audit. See the Trust Center for the full evidence library.
EU-only infrastructure
Finland, France + Netherlands
AES-256-GCM encryption
Tokens encrypted at rest
Self-hosted database
No third-party SaaS
No US data storage
Infrastructure + AI in EU
Infrastructure
All PortalPilot infrastructure runs in the EU. We self-host our database and analytics on our own servers, not through third-party SaaS.
| Service | Provider | Location |
|---|---|---|
| Application + database | Hetzner Cloud (self-hosted Supabase) | Helsinki, Finland |
| AI processing | Mistral AI | Paris, France |
| Analytics | Plausible CE (self-hosted) | Helsinki, Finland |
| Payments | Mollie B.V. | Netherlands |
| Transactional email | Lettermint B.V. | Zwolle, Netherlands |
Encryption
- OAuth tokens: Encrypted with AES-256-GCM using PBKDF2 key derivation (100,000 iterations) and a random 16-byte salt per operation. Tokens are never stored in plaintext.
- In transit: All connections use TLS 1.2 or higher.
- Backups: Database backups (including authentication data) are GPG-encrypted with AES-256 and stored off-server.
- Client-side: No sensitive data is stored in the browser. Authentication tokens are handled by Supabase's secure session management.
Authentication and access control
- HubSpot OAuth 2.0: We never see or store your HubSpot password. Access is granted via OAuth consent and can be revoked at any time from your HubSpot settings.
- Application auth: Supabase JWT-based authentication with secure session handling.
- Row-Level Security: Every database table is protected by RLS policies. Users can only access data belonging to their own portals.
- Edge function auth: Every API call validates the JWT, verifies the user identity, and confirms portal ownership before processing.
OAuth scopes & justifications
PortalPilot requests the minimum HubSpot OAuth scopes required for diagnostics and customer-approved remediation. Each scope is justified below.
| Scope | Tier | Justification |
|---|---|---|
| oauth | Required | Required by HubSpot OAuth 2.0 to authorise the app and refresh access tokens. |
| crm.schemas.contacts.read | Required | Read contact property schemas to detect missing required fields and quality issues. |
| crm.schemas.contacts.write | Required | Allow remediation actions to add missing properties or correct schemas during cleanup. |
| crm.objects.contacts.read | Required | Sample contact records to compute fill-rate and validity scores in the Contacts diagnostic. |
| crm.objects.contacts.write | Required | Apply customer-approved cleanup actions (deduplication, property corrections) when triggered. |
| crm.schemas.companies.read | Required | Read company property schemas to evaluate the Companies diagnostic and association coverage. |
| crm.schemas.companies.write | Required | Add or correct company properties during customer-approved remediation. |
| crm.objects.companies.read | Required | Sample company records to compute fill-rate, association, and consistency scores. |
| crm.objects.companies.write | Required | Apply customer-approved cleanup actions on company records. |
| crm.schemas.deals.read | Required | Read deal property schemas to evaluate pipeline health and required-field coverage. |
| crm.schemas.deals.write | Required | Add or correct deal properties during customer-approved remediation. |
| crm.objects.deals.read | Required | Sample deal records to compute pipeline-stage and forecast-readiness diagnostics. |
| crm.objects.deals.write | Required | Apply customer-approved cleanup actions on deal records. |
| tickets | Required | Read ticket schemas and records to evaluate the Service Hub diagnostic. |
| e-commerce | Required | Access products and line items to evaluate Quotes/Commerce diagnostic coverage. |
| crm.objects.line_items.read | Required | Read line items to compute deal-value accuracy and product association coverage. |
| crm.objects.quotes.read | Required | Read quotes to evaluate quote-to-deal linkage health. |
| crm.objects.products.read | Required | Read product catalog entries to evaluate Quotes/Commerce diagnostic coverage. |
| crm.lists.read | Required | Read marketing and contact lists to evaluate segmentation health and list hygiene. |
| settings.users.read | Required | Read CRM users for ownership-distribution and team-rotation diagnostics. |
| crm.objects.leads.read | Optional | (Optional) Read leads object when available on the portal's tier; included in newer Leads diagnostic. |
| crm.schemas.custom.read | Optional | (Optional) Detect and analyse custom CRM objects beyond standard Contacts/Companies/Deals/Tickets. |
| crm.objects.custom.read | Optional | (Optional) Sample custom-object records to extend diagnostic coverage on portals using them. |
| automation | Optional | (Optional) Inspect workflow definitions to flag stale or broken automations. |
| crm.objects.goals.read | Optional | (Optional) Read goals to evaluate alignment between deals and forecast targets. |
| communication_preferences.read | Optional | (Optional) Read subscription preferences for compliance-posture diagnostics. |
| settings.users.teams.read | Optional | (Optional) Read team memberships to evaluate ownership distribution and rotation. |
Optional scopes are requested only when the corresponding HubSpot tier or feature is detected. Drift between this table and the canonical OAuth request list is enforced by an automated test.
Enterprise security hardening
As of March 2026, PortalPilot implements a comprehensive, multi-layer security hardening programme:
- Portal ownership verification: Every API endpoint verifies that the requesting user owns or is a team member of the portal before processing. Cross-tenant data access is impossible.
- AI prompt sanitisation: User-controlled data is sanitised before being sent to AI models, preventing prompt injection attacks.
- Data retention enforcement: Configurable per-portal retention policies with automated enforcement. Analysis history, pipeline data, and form analytics are automatically pruned based on your settings.
- Account deletion completeness: Deleting your account revokes all HubSpot OAuth grants, removes security audit records, and cleans up all associated data across 40+ database tables.
- Encrypted backups: Database backups (including auth data) are GPG-encrypted with AES-256 and stored off-server for disaster recovery.
- Supply chain protection: Build-time dependencies are pinned to exact versions. CI enforces authentication checks on all API endpoints.
Access controls
- Minimal team: PortalPilot is founder-operated. No third-party contractors or external personnel have access to production systems or customer data.
- Least privilege: All system access follows the principle of least privilege. Database access is restricted to scoped service roles.
- MFA required: Multi-factor authentication is enforced for all infrastructure access.
- SSH key authentication: Server access requires passphrase-protected SSH keys. No password-based authentication is permitted.
- Application isolation: Edge functions run in sandboxed Deno workers with no shared state between requests or tenants.
Incident response
We maintain a documented incident response process:
- Detection: Automated monitoring of authentication events, API access patterns, and system health. Comprehensive audit logging on all data access operations.
- Assessment: Incidents are classified by severity and impact. Both confirmed and assumed personal-data breaches are escalated immediately; the GDPR Article 33 notification path is entered when founder assessment determines the probability of compromise is more likely than not (greater than 50% threshold).
- Notification: In the event of a personal data breach, affected customers are notified within 72 hours as required by GDPR Article 33. The relevant supervisory authority is notified where required.
- Remediation: Root cause analysis, fix deployment, and post-incident review for every security event.
Contact: security@portalpilot.io
Business continuity
- Automated backups: Daily database backups including all schemas and authentication data.
- Encrypted at rest: All backups are GPG-encrypted with AES-256 and stored off-server, separate from the primary infrastructure.
- Recovery: Tested restoration procedures. Container orchestration via Coolify enables rapid service recovery.
- Data durability: Primary data resides on Hetzner's enterprise-grade storage with hardware redundancy.
Logging and monitoring
- Audit logging: All write operations, authentication events, and data access actions are logged with timestamps, user identifiers, and action details.
- Retention: Audit logs are retained for 90 days.
- PII protection: Email addresses and other personal identifiers are masked in log output to prevent accidental PII exposure.
- Security monitoring: Authentication failures, rate limit violations, and anomalous API access patterns are monitored.
Responsible disclosure
We welcome reports from security researchers who discover vulnerabilities in our application, API, or infrastructure.
- Report to: security@portalpilot.io
- Acknowledgement: We will acknowledge receipt within 3 business days and provide an initial assessment within 10 business days.
Scope
The following assets are in scope for vulnerability reports:
- The PortalPilot web application at
portalpilot.io - Edge function endpoints at
api.portalpilot.io - Supporting infrastructure operated under NordScope control
Out of scope
The following are explicitly out of scope for vulnerability reports:
- Third-party services we do not control: HubSpot, Mollie, Mistral AI, Lettermint, Plausible, Coolify, Hetzner, healthchecks.io
- Denial-of-service or volumetric testing of any kind
- Social engineering of NordScope employees, contractors, or customers
- Physical attacks on infrastructure or personnel
- Automated scanner output without proof-of-impact
Safe harbour
NordScope authorises good-faith security research within these published rules of engagement. Researchers must use only their own test accounts; must not exfiltrate, modify, or destroy data belonging to NordScope or its users; must not cause sustained service degradation; and must report findings promptly to security@portalpilot.io before any public disclosure. In practice, this covers probing OAuth and row-level-security boundaries from your own test accounts, fuzzing edge-function inputs using your own JWT, and inspecting the public bundle for leaked secrets or SBOM drift. For research conducted within these rules, NordScope (operated by Peter Sterkenburg in his capacity as owner of the toiminimi NordScope, Y-tunnus 3148476-5) will not initiate or recommend legal action under Finnish Criminal Code Chapter 38 §8 (data and communications offences) or related EU computer-misuse statutes. This safe harbour does not waive (i) NIS2 mandatory incident-reporting obligations to Finnish authorities, (ii) GDPR Article 33 personal-data-breach reporting, or (iii) any other statutory reporting obligation we cannot lawfully waive. This safe harbour applies only to NordScope and only to the assets listed in Scope; third-party services listed in Out of scope must be contacted directly under their own vulnerability-disclosure programmes.
Data handling
We access your HubSpot portal to analyse property configurations and compute health scores. Here is exactly what we access and store:
| Data type | Accessed | Stored |
|---|---|---|
| Property definitions (names, types, labels) | Yes | Yes (metadata only) |
| Record samples (up to 1,000 per object) | Yes | No — processed in memory, then discarded |
| Aggregate scores and statistics | Computed | Yes |
| Individual contact/deal/company records | No | No |
| Write operations (property edits) | User-initiated only | Audit log (90-day retention) |
AI processing
AI features (property suggestions, descriptions, embeddings) are processed by Mistral AI in Paris, France.
- Only property metadata is sent (names, descriptions, types) — not individual record values
- Per Mistral AI's data processing terms, API data is not stored beyond the request and is not used for model training
- All processing stays within the EU
GDPR compliance
- Data controller: NordScope, a Finnish sole trader (toiminimi), Y-tunnus 3148476-5, owner-operator Peter Sterkenburg
- DPA: A Data Processing Agreement is available for all customers
- Data export: Full export available on request
- Right to erasure: Delete your account and all associated data at any time. HubSpot OAuth grants are automatically revoked and all security audit records are cleaned up
- Supervisory authority: Office of the Data Protection Ombudsman (Finland)
Standards & frameworks
Frameworks PortalPilot has measured itself against:
Self-attestation is PortalPilot's own structured assessment against a publicly-published cloud-compliance framework — not a monitoring-body-validated declaration. Submission to SCOPE Europe is on our compliance roadmap.
Security roadmap
- Q3 2026 — external penetration test (full application + infrastructure).
- Q3 2026 — Cyber Essentials Plus certification.
- Q3 2026 — review SOC 2 Type II vs ISAE 3000 readiness.
- Q1 2027 — EU Cloud CoC Level 1 verified declaration (Phase 2; commercial terms under review).
Quarters subject to enterprise demand and budget allocation.
Questions?
For security questions, vulnerability reports, or to request a security questionnaire, contact us at security@portalpilot.io.