ISO 27001:2022 Annex A Control Register
Standard: ISO/IEC 27001:2022 Annex A (93 controls across 4 themes).
Theme totals (live): A.5 Organizational: 37 · A.6 People: 8 · A.7 Physical: 14 · A.8 Technological: 34 · Total: 93
Expected totals: A.5: 37 · A.6: 8 · A.7: 14 · A.8: 34 · Total: 93.
| ID | Title | Status | Justification | Evidence | Addresses risks | Last reviewed |
|---|---|---|---|---|---|---|
| A.5.1 | Policies for information security | Implemented | Information-security policy is documented across three artefacts: the ISMS scope statement (founder-attested, defines scope/classification/roles/review cadence), the security runbook (incident response, RLS posture, key handling, backup/recovery), and the agent-security ruleset (4-layer defence model on the AI coding-agent surface). The set is reviewed quarterly per ISMS §7 and was independently verified by the Q2 2026 internal audit. | /compliance/isms-scope-statement.html, internal security runbook (NDA counterpart), agent-security ruleset (NDA counterpart) | R-04, R-08 | 2026-05-01 |
| A.5.10 | Acceptable use of information and other associated assets | Implemented | Customer-side acceptable use is governed by the Terms of Service. Internal acceptable use (founder workstation, agent surface) is governed by ISMS §3 (out-of-scope handling — no customer data at rest on the laptop, FDE enabled, automatic screen-lock) and the agent-security ruleset (PreToolUse hooks block credential-network combinations and other dangerous patterns on the AI coding agent). | /terms, /compliance/isms-scope-statement.html#3-out-of-scope, agent-security ruleset (NDA counterpart) | R-04, R-08 | 2026-05-01 |
| A.5.11 | Return of assets | N/A | No employment relationships exist (single-founder organisation), so no internal return-of-assets event applies. Sub-processor data return on contract termination is governed by individual DPAs (e.g. Hetzner deletion within their contracted retention windows). Customer data return on disconnect is governed by the PortalPilot DPA Annex II export endpoints + cascade-delete posture and is treated under A.5.34 (Privacy and protection of PII). | /compliance/isms-scope-statement.html, /dpa | R-08 | 2026-05-01 |
| A.5.12 | Classification of information | Implemented | ISMS scope statement §5 defines the information-classification scheme: Public (marketing/blog/trust artefacts published at portalpilot.io/trust and portalpilot.io/compliance), Internal (operational runbooks, internal audit findings), Confidential (customer PII, OAuth tokens, internal-counterpart documents released only under NDA), Restricted (root credentials, encryption-key material, JWT secret). Storage-encryption posture and access controls scale with classification. | /compliance/isms-scope-statement.html#5-information-classification | R-04 | 2026-05-01 |
| A.5.13 | Labelling of information | Implemented | Information-labelling is enforced through (a) repository structure that separates NDA-only material from procurement-public material from externally published trust artefacts; (b) PII-inventory pseudonymisation/visibility columns per field; (c) automated label taxonomy on tracked work items; (d) verbatim status enums in this register (Implemented / Accepted-risk / N/A / Transferred-to-supplier). | /trust/pii-inventory.json, /compliance/isms-scope-statement.html#5-information-classification | R-04 | 2026-05-01 |
| A.5.14 | Information transfer | Implemented | All customer-data transfer is encrypted in transit per DPA Annex II §5.1 (TLS 1.2+ across every interface — customer browser ↔ frontend Nginx, frontend ↔ Supabase REST/Auth, edge functions ↔ HubSpot API, edge functions ↔ Mistral inference, edge functions ↔ Mollie billing). DPA Annex I documents the categories and processing flow. Internal administrative transfer (developer workstation ↔ Hetzner host) uses SSH key-based authentication only; agent egress is constrained by the credential-guard hook. | /dpa#annex-i, /dpa#annex-ii, /privacy | R-02, R-04 | 2026-05-01 |
| A.5.15 | Access control | Implemented | Customer-facing access control is implemented via Supabase Auth (JWT) at every edge-function entry point. The pattern enforced across all tier-gated functions: CORS → requireAuth (JWT validation via anon client) → requirePortalAccess (owner-or-team-member check) → rate limit → tier check → business logic. Postgres RLS policies provide defence-in-depth at the database layer; the service role key is used only inside edge functions, never exposed to clients. |
/security, edge-function shared module (NDA counterpart), internal security runbook (NDA counterpart) | R-04, R-08, R-13 | 2026-05-01 |
| A.5.16 | Identity management | Implemented | Identity is managed by self-hosted Supabase Auth (api.portalpilot.io). User accounts are created via email + password authentication with optional MFA enrolment. HubSpot portal identities are linked at OAuth callback via a portals.user_id foreign key to the Supabase user. No federated identity providers are configured at present; AAL2 enforcement on token-rotation paths is tracked under (planned). |
/security, edge-function shared module (NDA counterpart) | R-04 | 2026-05-01 |
| A.5.17 | Authentication information | Implemented | Customer credentials are stored as Supabase Auth bcrypt hashes; plaintext passwords are never persisted. HubSpot OAuth tokens are encrypted at rest via AES-256-GCM in edge-function shared module (NDA counterpart) (V2 envelope, enc2: prefix, random per-operation salt) keyed by the server-side TOKEN_ENCRYPTION_KEY secret; raw tokens never appear in URLs (V3 OAuth endpoints only, post-v1 removal). Edge functions never select('*') on portal_credentials — only the specific columns required. |
edge-function shared module (NDA counterpart), /security, security ruleset (NDA counterpart) | R-04 | 2026-05-01 |
| A.5.18 | Access rights | Implemented | Access rights are provisioned per portal: only the OAuth-installing user is granted portals.user_id ownership. Team-member sharing is opt-in via a partner team-member relation, gated by requirePortalAccess in every tier-gated edge function. Rights are evaluated on every request (no stale-cache risk) and revoked instantly on portal disconnect through CASCADE deletes. Postgres RLS policies provide defence-in-depth at the database layer. |
internal security runbook (NDA counterpart), edge-function shared module (NDA counterpart) | R-04, R-08 | 2026-05-01 |
| A.5.19 | Information security in supplier relationships | Implemented | Sub-processors are enumerated in ISMS scope §2.4 (Hetzner Cloud — Helsinki/EU; self-hosted Supabase running on PortalPilot's Hetzner host; Mistral AI — Paris/EU; Mollie — Amsterdam/EU). Each is engaged under a DPA covering Article 28 processor obligations. New sub-processors are introduced only via ISMS update + DPA Annex I revision + customer notification per the DPA sub-processor change clause. | /compliance/isms-scope-statement.html#24-sub-processors-third-party-processors, /dpa#annex-i | R-02 | 2026-05-01 |
| A.5.2 | Information security roles and responsibilities | Implemented | The single-founder organisation concentrates information-security roles (CISO, DPO, sysadmin, developer) on one person, attested in ISMS §6 with explicit segregation-of-duties tradeoff. Sub-processor responsibilities are delineated through individual DPAs (Hetzner infrastructure, Mistral inference, Mollie billing); no sub-processor can independently access customer data outside its contracted role. | /compliance/isms-scope-statement.html#6-roles--responsibilities, /dpa | R-08 | 2026-05-01 |
| A.5.20 | Addressing information security within supplier agreements | Implemented | Each sub-processor relationship is governed by a written DPA containing GDPR Article 28(3) requirements: confidentiality, security measures, sub-processor restrictions, data-subject-rights assistance, breach notification, audit rights, and end-of-contract data return/deletion. PortalPilot's customer-facing DPA Annex I lists the contracted sub-processors and their roles; Annex II details the technical and organisational measures carried through the chain. | /dpa#annex-i, /dpa#annex-ii | R-02 | 2026-05-01 |
| A.5.21 | Managing information security in the ICT supply chain | Implemented | ICT supply-chain composition is tracked through package.json + package-lock.json for the npm dependency tree and through ISMS §2.4 for the infrastructure-supplier chain. Vulnerability monitoring is via GitHub Dependabot + npm audit (CI + release pipeline); upstream vendor advisories are subscribed to (Hetzner status page, Supabase upgrades, Mistral model deprecations). A formal SBOM (internal compliance artefact (NDA counterpart)) is generated by the compliance-pack build script and ships with (planned — see Trust Center evidence library). |
package.json, /compliance/isms-scope-statement.html#24-sub-processors-third-party-processors | R-02, R-12 | 2026-05-01 |
| A.5.22 | Monitoring, review and change management of supplier services | Implemented | Sub-processor services are monitored continuously: (a) Hetzner — infrastructure availability via daily backend-health-check + status page subscription; (b) self-hosted Supabase containers — docker ps health + Coolify scheduled tasks; (c) Mistral — model-deprecation watch (an automated Mistral alias-check script, daily 07:00 UTC backend-health-check covers mistralDeprecations); (d) Mollie — webhook delivery monitoring + payment-return correlation logs. Material change to a sub-processor triggers a DPA Annex I update + ISMS §2.4 revision. |
internal security runbook (NDA counterpart), /compliance/isms-scope-statement.html#24-sub-processors-third-party-processors | R-02 | 2026-05-01 |
| A.5.23 | Information security for use of cloud services | Implemented | PortalPilot is fully cloud-hosted: Hetzner Cloud (Helsinki, EU) provides the production VM; Coolify orchestrates the self-hosted Supabase stack on that host. Customer-data residency is therefore EU-only by deployment topology, asserted in the EU Cloud Code of Conduct Phase 1 self-attestation. Cloud-service security posture is governed by the ISMS scope statement, the DPA Annex II (TOMs), and the Hetzner ISO 27001 / 27017 / 27018 certified data-centre programme. | /compliance/isms-scope-statement.html#24-sub-processors-third-party-processors, /dpa#annex-ii, https://portalpilot.io/compliance/eu-cloud-coc-self-attestation.html | R-02 | 2026-05-01 |
| A.5.24 | Information security incident management planning and preparation | Implemented | Incident-response planning is documented in the security runbook with a step-by-step checklist covering detection → containment → eradication → recovery → post-incident review. The runbook names the responsible role (founder), the supervisory authority (Tietosuojavaltuutettu) for Article 33 notification, and the customer-notification path. Q2 2026 internal audit verified the runbook coverage. | internal security runbook (NDA counterpart), /compliance/internal-audit-2026-q2.html | R-02, R-04, R-11 | 2026-05-01 |
| A.5.25 | Assessment and decision on information security events | Implemented | Security events are triaged against the runbook decision tree: (a) Article 33 personal-data-breach criteria (likely-to-result-in-risk threshold) → 72-hour DPA notification; (b) availability incidents → status-page update + customer-comms threshold; (c) agent-surface anomalies (audit-log spikes, hook denials) → log review + remediation. The decision is recorded in the GitHub triage system and, for material incidents, a post-incident memo committed to internal NDA-only compliance documents. | internal security runbook (NDA counterpart) | R-04 | 2026-05-01 |
| A.5.26 | Response to information security incidents | Implemented | Incident response follows the runbook checklist with the founder as on-call engineer (single-founder constraint accepted under A.5.3). Supporting tooling: SSH MCP for production access, Supabase MCP for database forensics, Coolify API for service restarts and env-var rotation, the encryption-key rotation procedure for TOKEN_ENCRYPTION_KEY if compromise is suspected (V1→V2 lazy re-encryption already in place). |
internal security runbook (NDA counterpart) | R-04 | 2026-05-01 |
| A.5.27 | Learning from information security incidents | Implemented | Post-incident learning is captured through (a) the CogniLayer memory system (gotcha, error_fix, pattern fact types — searchable across future sessions); (b) commit messages on the fix that reference the incident; (c) for material incidents, an explicit post-incident memo in internal NDA-only compliance documents. The Q2 2026 audit findings drove durable runbook updates as a worked example. |
/compliance/internal-audit-2026-q2.html, internal security runbook (NDA counterpart) | R-04, R-08, R-11 | 2026-05-01 |
| A.5.28 | Collection of evidence | Implemented | Evidentiary artefacts are collected through (a) hubspot_write_operations table (90-day rolling, cron-enforced via cleanup_old_write_operations) — every customer-facing write is captured with before/after JSONB; (b) Supabase auth logs and edge-function logs retained on the Hetzner host; (c) internal agent-telemetry log (NDA counterpart) for agent-tool-use telemetry; (d) Hetzner Cloud Firewall logs at the network layer. Chain-of-custody for production-incident evidence follows the runbook. |
internal security runbook (NDA counterpart), /trust/pii-inventory.json | R-04 | 2026-05-01 |
| A.5.29 | Information security during disruption | Implemented | Disruption-time information-security posture is documented in internal database backup/recovery runbook (NDA counterpart), originating from the 2026-02-05 Coolify volume-recreate incident that drove the formal recovery procedure. Backups are encrypted at rest in /opt/backups/supabase/; restore procedures preserve RLS policies, encrypted-token columns, and the JWT secret; the recovery target keeps the same security boundary as production. |
internal database backup/recovery runbook (NDA counterpart), internal security runbook (NDA counterpart) | R-02, R-04 | 2026-05-01 |
| A.5.3 | Segregation of duties | Accepted-risk | True personnel segregation of duties is impossible at the single-founder organisational scale. ISMS §6 documents this explicitly. Compensating controls: (a) contractual segregation across sub-processors (Hetzner infrastructure / Mistral inference / Mollie billing — none can independently breach customer data); (b) audit-log tamper-evidence via Postgres-side hubspot_write_operations retention (90 days, cron-enforced); (c) Q2 2026 internal audit provided independent verification of the runbook. |
/compliance/isms-scope-statement.html#6-roles--responsibilities, /compliance/internal-audit-2026-q2.html | R-08 | 2026-05-01 |
| A.5.30 | ICT readiness for business continuity | Implemented | ICT business-continuity readiness rests on (a) the documented backup/restore procedure (internal database backup/recovery runbook (NDA counterpart) — daily Postgres dumps + Hetzner Cloud snapshots; restore tested against the 2026-02-05 incident); (b) Coolify's automated container restart and health-check loops; (c) Hetzner's certified data-centre programme covering power/cooling/network redundancy. RTO/RPO targets are defined in the recovery doc and reviewed at the ISMS quarterly cadence. | internal database backup/recovery runbook (NDA counterpart) | R-02, R-04 | 2026-05-01 |
| A.5.31 | Legal, statutory, regulatory and contractual requirements | Implemented | Applicable legal/regulatory framework is documented across: ISMS scope §1 (jurisdiction — Finnish sole trader, Y-tunnus 3148476-5); the customer-facing Privacy Policy (GDPR data-subject rights Art 15/17/20); the DPA (GDPR Article 28 processor obligations + Standard Contractual Clauses where required); the Terms of Service (contractual obligations to customers). Compliance with Finnish supervisory-authority requirements (Tietosuojavaltuutettu) is recognised in A.5.5. | /privacy, /dpa, /terms, /compliance/isms-scope-statement.html#1-organisation-profile | R-04 | 2026-05-01 |
| A.5.32 | Intellectual property rights | Implemented | Third-party IP is tracked through the npm dependency tree in package.json + package-lock.json; license metadata per dependency is enumerated by the SBOM regeneration step (the compliance-pack build script) which publishes internal compliance artefact (NDA counterpart) + a license summary as part of (planned — see Trust Center evidence library). PortalPilot's own source code is closed-source under founder ownership (NordScope toiminimi); customer rights are governed by the Terms of Service. |
package.json, /terms, internal compliance artefact (NDA counterpart) | R-04 | 2026-05-01 |
| A.5.33 | Protection of records | Implemented | Records are protected per their classification (A.5.12). Customer-data records have explicit retention windows in the PII inventory retention table (per-field, e.g. hubspot_write_operations.before_value 90 days; OAuth tokens until disconnect; account data until deletion). Encryption at rest (LUKS) and in transit (TLS 1.3) protects all classifications. Compliance/audit records (this register, /compliance/internal-audit-2026-q2.html, ISMS scope) are version-controlled in git with founder-signed commits. |
/trust/pii-inventory.json, /compliance/isms-scope-statement.html#5-information-classification | R-04 | 2026-05-01 |
| A.5.34 | Privacy and protection of PII | Implemented | Privacy posture is the (planned) deliverable: a 14-field PII inventory mapped to GDPR Article 30 record-of-processing requirements (source, storage, encryption, retention, lawful basis, sub-processor access, GDPR-rights enforcement). The customer-facing Privacy Policy declares lawful basis and data-subject rights; the DPA Annex II details TOMs; data-flow diagrams (pii-data-flow.pdf) are published at portalpilot.io/trust/. |
/trust/pii-inventory.json, /privacy, /dpa#annex-ii, https://portalpilot.io/trust/pii-inventory.pdf | R-04, R-10 | 2026-05-01 |
| A.5.35 | Independent review of information security | Implemented | The Q2 2026 internal audit was conducted as a structured independent review of the ISMS, security runbook, edge-function authentication patterns, RLS policy posture, and the agent-surface defence model. Findings + closure status are committed to /compliance/internal-audit-2026-q2.html. ISMS §7 sets a quarterly review cadence; the next independent review is scheduled accordingly. |
/compliance/internal-audit-2026-q2.html, /compliance/isms-scope-statement.html#7-review-cadence | R-04, R-08 | 2026-05-01 |
| A.5.36 | Compliance with policies, rules and standards for information security | Implemented | Policy-compliance enforcement combines (a) automated gates: the design-system + accuracy + security rules in engineering rulesets (NDA counterpart) are loaded on-demand into every relevant edit, the compliance-pack lint at three layers, the design lint, and the type-check + test suite all run as part of release pipeline; (b) procedural gates: post-plan gate, chunk-verification gate, Mistral chunk-review, and release pipeline quality gates; (c) periodic verification: the Q2 2026 internal audit confirmed real-world adherence. | /compliance/isms-scope-statement.html, /compliance/internal-audit-2026-q2.html, internal contributor guide (NDA counterpart) | R-04, R-08 | 2026-05-01 |
| A.5.37 | Documented operating procedures | Implemented | Operating procedures are documented as living artefacts: the security runbook (incident response, RLS verification, key handling, SSH MCP usage, Coolify operations); the database backup/recovery procedure (post-incident); the documented release-pipeline quality gates; and the per-rule engineering supplements (NDA counterpart). Procedures are revised in-line whenever new gotchas are encountered. | internal security runbook (NDA counterpart), internal database backup/recovery runbook (NDA counterpart), edge-function ruleset (NDA counterpart), database ruleset (NDA counterpart), server-operations ruleset (NDA counterpart) | R-04, R-08 | 2026-05-01 |
| A.5.4 | Management responsibilities | Implemented | The founder is the sole management-equivalent and has signed the ISMS founder-attestation accepting personal responsibility for information-security policy enforcement, sub-processor oversight, GDPR Article 33 incident notification, and the ISMS quarterly review cadence. The attestation is renewed at every ISMS scope review per §7. | /compliance/isms-scope-statement.html#founder-attestation, /compliance/isms-scope-statement.html#6-roles--responsibilities | R-08 | 2026-05-01 |
| A.5.5 | Contact with authorities | Implemented | For GDPR purposes the lead supervisory authority is the Finnish Office of the Data Protection Ombudsman (Tietosuojavaltuutettu, Helsinki), reachable via tietosuoja.fi. GDPR Article 33 personal-data-breach notification within 72 hours is documented in the security-runbook incident-response checklist. For criminal-cyber-incident reporting the relevant authority is NCSC-FI / Traficom Cybersecurity Centre. | internal security runbook (NDA counterpart), /privacy | R-04 | 2026-05-01 |
| A.5.6 | Contact with special interest groups | N/A | PortalPilot is not currently a member of formal information-security forums (FIRST.org, ISACs, vendor security partnerships) at the single-founder scale. Threat intelligence is consumed through public sources — see A.5.7. This control is documented N/A pending future organisational growth that would justify formal membership; no risk increase identified at the current scale. | /compliance/isms-scope-statement.html | R-04 | 2026-05-01 |
| A.5.7 | Threat intelligence | Implemented | Threat-intelligence inputs: (1) GitHub Dependabot alerts on the repository; (2) npm audit run as part of CI and release pipeline; (3) Hetzner status page and security advisories; (4) periodic adversarial-prompt-injection sweeps via Claude Code on the agent surface (logged in internal agent-telemetry log (NDA counterpart)); (5) GitHub Security advisories / CVE feeds for the dependency tree. Methodology was independently verified by the Q2 2026 internal audit. |
/compliance/internal-audit-2026-q2.html, agent-security ruleset (NDA counterpart) | R-04, R-08 | 2026-05-01 |
| A.5.8 | Information security in project management | Implemented | All product changes follow the documented structured design + review workflow chain in internal contributor guide (NDA counterpart). Security-affecting changes (auth, encryption, RLS, edge function authentication) are explicitly flagged for Mistral chunk-review and Claude Code review second opinion. Foundational-area edits (token encryption, RLS policies, edge↔frontend type contracts) cannot be deferred per the cost-of-deferral discipline rule. | internal contributor guide (NDA counterpart), accuracy ruleset (NDA counterpart) | R-04 | 2026-05-01 |
| A.5.9 | Inventory of information and other associated assets | Implemented | The PII inventory enumerates personal-data fields with source, storage location, encryption posture, retention, lawful basis, and sub-processor access (per GDPR Article 30 record-of-processing). The ISMS scope statement §2 enumerates non-PII assets: production application, customer data, operational infrastructure, sub-processors, and engineering tooling (the coding-agent surface). | /trust/pii-inventory.json, /compliance/isms-scope-statement.html#2-in-scope-assets | R-04 | 2026-05-01 |
| A.6.1 | Screening | N/A | PortalPilot is a single-founder operation (NordScope toiminimi, Y-tunnus 3148476-5). There is no hiring process, no employees, and no contractors with access to production. Pre-employment screening is therefore not applicable. This will be revisited if the organisation hires its first employee. | /compliance/isms-scope-statement.html | R-08 | 2026-04-27 |
| A.6.2 | Terms and conditions of employment | N/A | No employment relationships exist. The founder operates as sole director under a Finnish toiminimi structure, where information-security obligations bind directly to the natural person under Finnish data-protection law and the GDPR. | /compliance/isms-scope-statement.html | R-08 | 2026-04-27 |
| A.6.3 | Information security awareness, education and training | Implemented | Founder-attested ongoing security review per ISMS scope §7 (review cadence): quarterly internal audit, continuous monitoring of dependencies, sub-processors, and applicable regulations. Compliance reading covers ENISA, NCSC-FI, Hetzner / Supabase / Mistral security advisories. | /compliance/isms-scope-statement.html, /compliance/internal-audit-2026-q2.html | R-04, R-08 | 2026-04-27 |
| A.6.4 | Disciplinary process | N/A | Single-founder organisation has no disciplinary chain. Sanctions for information-security policy violations apply only to sub-processors via contract (DPA termination clause); no internal process exists or is meaningful at this organisational scale. | /compliance/isms-scope-statement.html | R-08 | 2026-04-27 |
| A.6.5 | Information security responsibilities after termination or change of employment | N/A | No employment relationships exist; consequently no termination or change-of-employment events to govern. The single founder remains fully responsible for ongoing information-security obligations. | /compliance/isms-scope-statement.html | R-08 | 2026-04-27 |
| A.6.6 | Confidentiality or non-disclosure agreements | Implemented | Confidentiality is bound at every interface: customers accept the standard Terms of Service and Data Processing Agreement on sign-up; sub-processors (Hetzner, Supabase self-hosted on PortalPilot infrastructure, Mistral AI, Mollie) are bound by their own DPAs covering customer-data confidentiality. Internal-counterpart documents (e.g., ISMS scope internal) are NDA-only and released bilaterally to procurement reviewers. | /dpa, /terms, internal NDA-only compliance documents | R-02 | 2026-04-27 |
| A.6.7 | Remote working | Implemented | All operational work is remote by design. Founder workstation hygiene is documented in ISMS scope §3 (out-of-scope, with attested handling): no customer data at rest on the laptop, FDE enabled, automatic screen-lock, MFA on all admin entry points. Production access is over authenticated, encrypted channels only (HTTPS to Coolify, SSH key-based to the host). | /compliance/isms-scope-statement.html, internal security runbook (NDA counterpart) | R-04, R-08 | 2026-04-27 |
| A.6.8 | Information security event reporting | Implemented | Event reporting paths are documented in internal security runbook (NDA counterpart): (1) public security contact security@portalpilot.io for external reporters; (2) internal monitoring via daily backend health-check, Coolify scheduled tasks, and Hetzner Cloud Firewall logs; (3) GDPR-grade incident response triggers within 72 hours per Article 33. The Q2-2026 internal audit verified runbook alignment. | internal security runbook (NDA counterpart), /compliance/internal-audit-2026-q2.html | R-04, R-08 | 2026-04-27 |
| A.7.1 | Physical security perimeters | Transferred-to-supplier | PortalPilot operates with no physical offices. Production infrastructure runs in Hetzner Cloud data centres (Helsinki/Finland region, EU); physical perimeter control is delegated to Hetzner under their ISO/IEC 27001, 27017, and 27018 certification scope. | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.10 | Storage media | Transferred-to-supplier | Production storage media (PostgreSQL, object storage, backups) reside on Hetzner-managed disks within certified data centres; physical handling, sanitisation, and end-of-life disposal are performed by Hetzner per their certified media-handling procedures. Founder workstation media is encrypted at rest (Annex A.8). | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.11 | Supporting utilities | Transferred-to-supplier | Power, cooling, network connectivity, and other supporting utilities for production infrastructure are provided by Hetzner data centres under their certified facilities programme (redundant feeds, UPS, generators). | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.12 | Cabling security | Transferred-to-supplier | All physical network and power cabling within Hetzner data centres is installed and protected by Hetzner staff per their certified cabling-security procedures. PortalPilot operates no physical cabling of its own. | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.13 | Equipment maintenance | Transferred-to-supplier | Equipment maintenance (hardware servicing, replacement, firmware updates at the host level) is performed by Hetzner data centre staff per their supplier agreement and certified maintenance procedures. | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.14 | Secure disposal or re-use of equipment | Transferred-to-supplier | Decommissioning, disk wiping, and secure disposal or re-use of production hardware are performed by Hetzner under their certified equipment lifecycle procedures (covered by ISO 27001 / 27017 / 27018 scope). | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.2 | Physical entry | Transferred-to-supplier | No PortalPilot-controlled premises. Physical entry controls (access cards, escorts, visitor logs) are operated by Hetzner data centre staff under their certified physical-access management procedures. | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.3 | Securing offices, rooms and facilities | Transferred-to-supplier | PortalPilot has no offices, server rooms, or facilities of its own. All compute facilities are Hetzner data centres operated under their ISO 27001 certified physical-security regime. | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.4 | Physical security monitoring | Transferred-to-supplier | CCTV, intrusion detection, and on-site monitoring of production infrastructure are operated by Hetzner per their certified data centre security programme. | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.5 | Protecting against physical and environmental threats | Transferred-to-supplier | Fire suppression, flood protection, seismic protection, and other environmental threat mitigations for production infrastructure are operated by Hetzner under their certified data centre programme. | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.6 | Working in secure areas | Transferred-to-supplier | PortalPilot personnel never enter Hetzner data centre secure areas; all administration is remote over authenticated channels. Secure-area working procedures inside the data centre are operated by Hetzner staff under certification. | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.7 | Clear desk and clear screen | Transferred-to-supplier | No physical desks or shared workstations exist. Founder workstation lock-screen / disk-encryption hygiene is treated under Annex A.8 (Technological) as endpoint security; data-centre clear-desk discipline is operated by Hetzner. | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.8 | Equipment siting and protection | Transferred-to-supplier | Production servers are sited within Hetzner data centres; physical siting (rack placement, environmental exposure, blast/utility separation) is controlled by Hetzner per their certified facilities programme. | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.7.9 | Security of assets off-premises | Transferred-to-supplier | PortalPilot has no premises; the only off-premises asset is the founder workstation, addressed under Annex A.8 (Technological) endpoint controls. Production assets remain inside Hetzner facilities under their certified physical-security regime. | https://www.hetzner.com/unternehmen/zertifizierung | R-02 | 2026-04-27 |
| A.8.1 | User end point devices | Implemented | The only end-point device in scope of this ISMS is the founder's macOS workstation. Practical controls: FileVault full-disk encryption, automatic screen-lock with password on resume, Gatekeeper + System Integrity Protection enforced. Production secrets are never persisted locally — the production environment loads secrets from Hetzner / Supabase environment variables at runtime. The agent-surface defence layers (credential-guard, read-guard, write-guard, mcp-guard hooks under internal agent-execution guard hooks (NDA counterpart)) prevent the local coding agent from reading SSH keys, exfiltrating credentials, or executing destructive operations against production. ISMS §3 records the laptop's out-of-scope status for customer-data-at-rest; this control covers the residual transit-time exposure. | /compliance/isms-scope-statement.html#3-out-of-scope, agent-security ruleset (NDA counterpart) | R-03, R-06 | 2026-05-01 |
| A.8.10 | Information deletion | Implemented | Three deletion paths are implemented: (1) HubSpot contact, company, and deal deletion webhooks are handled in supabase/functions/hubspot-webhook/index.ts (the GDPR right-to-be-forgotten path is the contact.privacyDeletion subscription); (2) customer-account deletion follows the documented procedure in security-runbook §Account Deletion (cascade-delete of portal data); (3) sub-processor data deletion is governed by the per-sub-processor DPA retention windows. The PII inventory documents the deletion policy per data category. |
supabase/functions/hubspot-webhook/index.ts, internal security runbook (NDA counterpart), /trust/pii-inventory.json | R-01 | 2026-05-01 |
| A.8.11 | Data masking | Implemented | PII masking applies on three surfaces: (1) structured logging — edge-function shared module (NDA counterpart) exposes maskEmail (and is the standard utility for any new PII redaction needs) to scrub identifiers from log lines before container log emission; (2) LLM inference — edge-function shared module (NDA counterpart) truncates inputs to 2000 characters and rejects multi-word prompt-injection patterns before any Mistral call, limiting accidental PII transmission to the inference sub-processor; (3) data-minimisation at the persistence layer — the PII inventory documents the categories actually stored vs derived-and-discarded. |
edge-function shared module (NDA counterpart), edge-function shared module (NDA counterpart), /trust/pii-inventory.json | R-01, R-10 | 2026-05-01 |
| A.8.12 | Data leakage prevention | Implemented | Multi-layer DLP posture: (a) outbound LLM inference is sanitised by edge-function shared module (NDA counterpart) (2000-char truncation + multi-word blocklist) before the Mistral call; (b) audit-log JSONB columns are queryable only via authenticated edge functions with portal-ownership verification — direct PostgREST access is blocked by RLS; (c) the agent-surface egress controls (credential-guard.sh) enforce a network-tool allowlist that blocks combinations of credential reads with outbound network calls; (d) export endpoints surface only the data the authenticated user already owns. The PII inventory documents the leakage controls per data category and processing path. |
/trust/pii-inventory.json, edge-function shared module (NDA counterpart), agent-security ruleset (NDA counterpart) | R-01, R-06 | 2026-05-01 |
| A.8.13 | Information backup | Implemented | PostgreSQL is backed up daily via pg_dump to /opt/backups/supabase/ on the Hetzner host, with retention and verification documented in internal database backup/recovery runbook (NDA counterpart). Restore procedure is tested as part of the documented runbook with target RTO ≈ 1 h and RPO ≤ 24 h. Hetzner additionally operates infrastructure-level snapshots at the VM layer. The Q2 2026 internal audit verified backup freshness and restore-procedure currency. |
internal database backup/recovery runbook (NDA counterpart), /compliance/internal-audit-2026-q2.html | R-09 | 2026-05-01 |
| A.8.14 | Redundancy of information processing facilities | Accepted-risk | Production runs on a single Hetzner Cloud VM with no application-tier hot redundancy or active-active multi-region deployment. This is an explicit accepted risk: introducing multi-region active-active or warm standby would impose roughly 2–3× infrastructure cost not justified at current customer scale. Compensating controls: (a) Hetzner infrastructure SLA at the IaaS layer; (b) automated daily backups per A.8.13 with documented restore procedure (RTO ≈ 1 h); (c) Coolify-driven container restart on health-check failure; (d) the PortalPilot DPA Annex II commits to availability via these specific compensating controls rather than via uptime guarantees. Reassessment trigger: first enterprise customer requiring contractual uptime SLA, or at >50 paying customers. | internal database backup/recovery runbook (NDA counterpart), /compliance/isms-scope-statement.html, /dpa#annex-ii | R-08, R-09 | 2026-05-01 |
| A.8.15 | Logging | Implemented | Structured logging via edge-function shared module (NDA counterpart) is used across every edge function with PII masking applied at emission time; security-relevant events (authentication failures, rate-limit triggers, ownership-check denials, billing/credit operations) are written via edge-function shared module (NDA counterpart) to the audit_log table with portal-id correlation. Coolify-managed Nginx access logs cover frontend traffic; Docker container logs are accessible per server-operations ruleset (NDA counterpart) for ad-hoc investigation. Log-retention semantics are documented in security-runbook §Hetzner-managed log escalation. |
edge-function shared module (NDA counterpart), edge-function shared module (NDA counterpart), server-operations ruleset (NDA counterpart), internal security runbook (NDA counterpart) | R-04, R-07, R-10 | 2026-05-01 |
| A.8.16 | Monitoring activities | Implemented | Active monitoring covers (a) container/service health via the Coolify dashboard with restart-on-failure policies; (b) edge-function structured-log surface for authentication failures, rate-limit triggers, webhook delivery anomalies; (c) the daily backend-health-check cron (Coolify scheduled task on service igk0g8sgss4o4w4woosww404) which exercises a representative edge-function path and surfaces deprecation warnings (e.g., Mistral substrate); (d) Mistral-substrate alias check via an automated Mistral alias-check script. The quarterly internal audit (per ISMS §7) reviews the monitoring outputs as a pull-based control. |
edge-function shared module (NDA counterpart), /compliance/internal-audit-2026-q2.html, internal security runbook (NDA counterpart), server-operations ruleset (NDA counterpart) | R-04, R-07 | 2026-05-01 |
| A.8.17 | Clock synchronization | Implemented | The Hetzner Cloud VM hosting production uses the upstream public NTP pool via systemd-timesyncd (Hetzner default configuration); Supabase containers inherit the host clock through the Docker daemon. This produces consistent timestamps across edge-function logs, Nginx access logs, the audit-log table, and any cross-service correlation. Founder workstation clock is similarly NTP-synchronised. No application logic depends on monotonic clocks across hosts. |
internal architecture documents (NDA counterpart) | R-08 | 2026-05-01 |
| A.8.18 | Use of privileged utility programs | Implemented | The set of privileged utility programs in scope is small and concentrated on the founder principal: SSH client to the Hetzner host (key-authenticated only), psql via the supabase-db-igk0 container, the Docker CLI on the host, and the Coolify orchestration UI. The agent-surface restrictions are the load-bearing control here — mcp__ssh-hetzner__sudo-exec is gated by per-invocation user approval per the agent-security model; read-guard.sh blocks reads of ~/.ssh/* and other credential paths; branch-guard.sh and session-guard.sh prevent destructive cross-session operations. There is no shared use of privileged utilities that would warrant a separate authorisation register. |
/compliance/isms-scope-statement.html#6-roles--responsibilities, agent-security ruleset (NDA counterpart), server-operations ruleset (NDA counterpart) | R-03, R-06 | 2026-05-01 |
| A.8.19 | Installation of software on operational systems | Implemented | Software reaches production only via the Coolify auto-deploy pipeline triggered by push to main, which in turn requires a Pull Request that has passed CI (TypeScript, lint:design, build, vitest). Production Node and Deno dependencies are pinned via package-lock.json and edge-function shared imports respectively; container images for Supabase services come from official Supabase tags pinned by Coolify; no ad-hoc installation occurs on the production host. internal contributor guide (NDA counterpart) documents the workflow chain and release pipeline enforces all quality gates as a single shipping gate. |
automated CI workflow, internal architecture documents (NDA counterpart), internal contributor guide (NDA counterpart) | R-04, R-07 | 2026-05-01 |
| A.8.2 | Privileged access rights | Implemented | Privileged access is concentrated on the single founder principal per ISMS §6 Roles and responsibilities; no other internal accounts exist. Application-tier privilege separation is enforced by the edge-function authentication pattern: every authenticated function calls requireAuth (validates Supabase JWT) followed by requirePortalAccess (verifies the calling user owns or is a team member of the target portal) before any portal-data access. Service-role database credentials are scoped to edge functions only and are never returned to the client. Sudo on the production host requires SSH key authentication; the MCP sudo-exec tool requires per-invocation approval per the agent-security model. |
/security, edge-function shared module (NDA counterpart), /compliance/isms-scope-statement.html#6-roles--responsibilities, agent-security ruleset (NDA counterpart) | R-03, R-07 | 2026-05-01 |
| A.8.20 | Networks security | Implemented | Two independent firewall layers operate in default-deny mode (Hetzner Cloud Firewall at the network edge plus host-level UFW on the VM); only TCP 22 (SSH key-authenticated), 80 (Let's Encrypt ACME, redirected to HTTPS), and 443 (HTTPS) are open through the intersection of both. TLS 1.2+ terminates at a Traefik reverse proxy that routes by host header to the appropriate backend service. CORS allowlisting at the application layer (security-headers.ts) restricts which browser origins can reach edge functions. ISMS §4 documents the layered model end-to-end. |
/compliance/isms-scope-statement.html, edge-function shared module (NDA counterpart) | R-01, R-05, R-13 | 2026-05-01 |
| A.8.21 | Security of network services | Implemented | All customer-facing network services (frontend, Supabase Auth, REST, Edge Functions, Realtime) are served over TLS via Traefik with HTTP Strict Transport Security; security headers (CSP, X-Frame-Options, etc.) applied uniformly via edge-function shared module (NDA counterpart). Per-edge-function rate limiting via _shared/rateLimit.ts protects against brute-force and abuse; the rate-limiter handles dual-format portal IDs (UUID and HubSpot numeric) safely. Supabase Kong fronts internal API services and provides a uniform gateway with consistent header treatment. |
edge-function shared modules (NDA counterpart)/rateLimit.ts, edge-function shared module (NDA counterpart), /compliance/isms-scope-statement.html | R-01, R-07 | 2026-05-01 |
| A.8.22 | Segregation of networks | Implemented | The production VM has no peering relationships to other networks. Internal services (PostgreSQL, Auth, REST, Edge Runtime, Storage, Realtime, Studio) communicate only over the Coolify-managed Docker network; only the Kong gateway (supabase-kong-igk0) and the frontend Nginx (rcw8) are externally reachable. Administrative SSH (port 22) is segregated from customer-facing 443 by firewall rules. The public attack surface is therefore exactly two ports on one host. |
/compliance/isms-scope-statement.html, internal architecture documents (NDA counterpart) | R-01, R-07 | 2026-05-01 |
| A.8.23 | Web filtering | N/A | PortalPilot is an authenticated SaaS with no proxying surface, no general-purpose browsing experience for customers, and no outbound web request originated on behalf of a customer to an arbitrary URL. There is therefore no end-user web-filtering surface to govern. Founder-side egress (the engineering tooling surface) is constrained at the agent layer by the credential-guard hook's network-tool allowlist; this is captured under A.8.7 (malware) and A.8.18 (privileged utilities) rather than as web-filtering. | agent-security ruleset (NDA counterpart) | R-08 | 2026-05-01 |
| A.8.24 | Use of cryptography | Implemented | AES-256-GCM is used for OAuth-token encryption at rest via edge-function shared module (NDA counterpart), with per-operation random 16-byte salt (enc2: prefix) and lazy upgrade from the deprecated enc: v1 format on next refresh. Unencrypted tokens are rejected at decrypt time. Database encryption at rest is AES-256 at the Supabase storage layer (per the DPA Annex II Encryption section). All transit uses TLS 1.2+. The encryption-key rotation procedure is documented in security-runbook §Encryption Key Rotation. Security rule mandates column-specific selects on portal_credentials to prevent accidental encrypted-token exposure. |
edge-function shared module (NDA counterpart), /dpa#annex-ii, internal security runbook (NDA counterpart), security ruleset (NDA counterpart) | R-05 | 2026-05-01 |
| A.8.25 | Secure development life cycle | Implemented | The pp-* workflow chain documented in internal contributor guide (NDA counterpart) is the SDLC: brief → spec → brainstorming → critique → test-scenarios → writing-plans → post-plan gate (Issues + sub-issues) → build → release pipeline. Every gate has explicit artefacts; release pipeline is the only path to commit and push, embedding type-check, lint, build, vitest, code review, Mistral second opinion, docs update, and memory harvest. The Q2 2026 internal audit Methodology section validated the SDLC as actually followed in practice (not just documented). |
internal contributor guide (NDA counterpart), /compliance/internal-audit-2026-q2.html | R-04, R-07 | 2026-05-01 |
| A.8.26 | Application security requirements | Implemented | Security requirements are explicitly captured at design time via internal workflow step (P0/P1/P2 acceptance criteria), validated via internal workflow step, and translated into test scenarios via internal workflow step before any plan is written. The on-demand rules under security ruleset (NDA counterpart), edge-function ruleset (NDA counterpart), and agent-security ruleset (NDA counterpart) auto-load whenever the corresponding code areas are touched, ensuring security requirements stay enforceable at edit time. The agent-security threat model (agent-security ruleset (NDA counterpart)) is the authoritative statement of the application's adversarial assumptions. |
security ruleset (NDA counterpart), edge-function ruleset (NDA counterpart), agent-security ruleset (NDA counterpart), internal contributor guide (NDA counterpart) | R-01, R-07, R-11 | 2026-05-01 |
| A.8.27 | Secure system architecture and engineering principles | Implemented | The architecture follows defence-in-depth (firewall → reverse proxy → application auth → RLS → encryption-at-rest), least-privilege (per-edge-function ownership verification before any portal-data access), and explicit-allow (CORS allowlist, network firewall default-deny, RLS default-deny). The edge-function shared modules (auth.ts, rateLimit.ts, crypto.ts, security-headers.ts, audit.ts) enforce these principles uniformly across every authenticated function. Architecture and engineering principles are documented in the internal architecture documents and engineering rulesets (NDA counterpart). |
internal architecture documents (NDA counterpart), edge-function ruleset (NDA counterpart), edge-function shared module (NDA counterpart) | R-01, R-07 | 2026-05-01 |
| A.8.28 | Secure coding | Implemented | TypeScript with strict null checks and unknown over any is the baseline; ESLint and the design-system lint enforce style and structural rules; the agent-security guards prevent dangerous patterns (raw error logging in crypto code, select('*') on portal_credentials, tokens in URLs) at edit time via the loaded security ruleset (NDA counterpart) and edge-function ruleset (NDA counterpart) policies. The Q2 2026 internal audit reviewed coding patterns across the auth/crypto/edge-function surface and found no critical secure-coding deviations. |
security ruleset (NDA counterpart), agent-security ruleset (NDA counterpart), /compliance/internal-audit-2026-q2.html | R-01, R-07 | 2026-05-01 |
| A.8.29 | Security testing in development and acceptance | Implemented | The Vitest test suite (180 files / ~3 015 tests as of v3.41.0) covers edge-function pure logic, auth flows, RLS-relevant query shapes, and shared modules; CI runs the full suite on every PR via the quality job. The (planned) compliance-pack lint adds a third lint layer (cardinality, cross-references, evidence integrity) once (planned) activates. Stryker mutation-testing tooling is configured for targeted use. Acceptance testing is performed manually at the application surface before each release pipeline for any user-visible change. | automated CI workflow, /compliance/internal-audit-2026-q2.html | R-07 | 2026-05-01 |
| A.8.3 | Information access restriction | Implemented | Customer-data access is restricted at three independent layers: (1) PostgreSQL row-level security policies enforced on every customer table (verified during the Q2 2026 internal audit); (2) the edge-function pattern documented in edge-function ruleset (NDA counterpart) that mandates CORS allowlist → JWT validation → portal-ownership verification → rate-limit → tier check before any business logic runs; (3) per-edge-function requirePortalAccess calls that confirm the authenticated principal owns or is a team member of the target portal before any read or write. The portal_credentials table is an explicit hardening case — security rule mandates column-specific selects (no select('*')) so encrypted tokens never enter shared response payloads. |
edge-function shared module (NDA counterpart), edge-function ruleset (NDA counterpart), internal security runbook (NDA counterpart), security ruleset (NDA counterpart) | R-01, R-07 | 2026-05-01 |
| A.8.30 | Outsourced development | N/A | There is no outsourced development — NordScope is a single-founder organisation and all production code is authored by the founder, optionally with assistance from the Claude Code coding agent (which operates under the in-scope coding-agent surface controls per A.5.18 and the agent-security defence model, not as an external developer). The closest analogue is sub-processor reliance on third-party libraries and SaaS dependencies; that is governed by the SBOM ((planned) deliverable) and the sub-processor inventory in ISMS §2.4, with each sub-processor bound by its own DPA. | /compliance/isms-scope-statement.html#24-sub-processors-third-party-processors, agent-security ruleset (NDA counterpart), internal SBOM summary (NDA counterpart) | R-08, R-12 | 2026-05-01 |
| A.8.31 | Separation of development, test and production environments | Accepted-risk | Two environments exist — the founder's local development environment (laptop, ISMS §3 out-of-scope) and the Hetzner production environment — with no dedicated staging or QA environment. This is an explicit accepted risk: a staging environment would impose duplicate infrastructure cost, drift-management overhead, and a second secret-management surface, none of which is justified at current customer scale. Compensating measures: (a) production secrets are never present locally — the production environment loads secrets from Hetzner / Supabase env at runtime; (b) every change traverses PR → CI → branch-protection before reaching main; (c) Coolify auto-deploy on push gives a fast rollback path via git revert; (d) the pp-tdd discipline (test-first for new behaviour) constrains regression risk; (e) database migrations are reviewed against the live database schema via the Supabase MCP before authoring per database ruleset (NDA counterpart). Reassessment trigger: first compliance customer demanding a staging environment, or at >50 paying customers. |
/compliance/isms-scope-statement.html#3-out-of-scope, internal contributor guide (NDA counterpart), database ruleset (NDA counterpart) | R-08 | 2026-05-01 |
| A.8.32 | Change management | Implemented | Every change to production traverses the same gated path: branch off main → commit on a feature branch → open a PR → CI quality + e2e jobs must pass → branch-protection on main enforces squash-merge → Coolify auto-deploys. Per-ship discipline: the changelog entry, version bump in package.json (single source of truth), internal implementation-status tracker (NDA counterpart) row, and post-deploy verification per release pipeline. The chunk-verification gate (Mistral chunk-review at end of each chunk) adds an extra review checkpoint inside multi-chunk plans. |
automated CI workflow, internal contributor guide (NDA counterpart), /compliance/internal-audit-2026-q2.html | R-04, R-08 | 2026-05-01 |
| A.8.33 | Test information | N/A | Test fixtures use synthetic data only — production customer data is never copied into the test suite, into local development databases, or into the laptop. The PII inventory documents data-flow boundaries that confirm customer PII never leaves production storage. Vitest fixtures, Stryker baseline data, and test scenario inputs are all hand-crafted synthetic records or anonymised analogues of real shapes. | /trust/pii-inventory.json | R-01 | 2026-05-01 |
| A.8.34 | Protection of information systems during audit testing | Implemented | Internal audits (per ISMS §7 quarterly cadence) are conducted by the founder using read-only inspection of production state via mcp__ssh-hetzner__exec (non-root) and the Supabase MCP (PostgREST + tunnel-routed direct queries). Any sudo-level audit step requires per-invocation approval via mcp__ssh-hetzner__sudo-exec per the agent-security model. The Q2 2026 internal audit Methodology section documents the read-only posture and the absence of any audit-time write access. No external auditor has yet had access to production; when one does, the same read-only constraints will apply via scoped temporary credentials. |
/compliance/isms-scope-statement.html#7-review-cadence, /compliance/internal-audit-2026-q2.html, agent-security ruleset (NDA counterpart) | R-04 | 2026-05-01 |
| A.8.4 | Access to source code | Implemented | Source code lives in the private GitHub repository nordscope-fi/portalpilot; visibility is private with founder as sole committer. Branch protection on main requires CI pass + at least one review (self-review acceptable for sole-founder under documented compensating control); merges flow exclusively via Pull Requests using the squash-merge convention. CI workflow runs the full quality gate on every PR. SSH deploy keys are rotated per the security-runbook procedure. |
automated CI workflow, internal security runbook (NDA counterpart), /compliance/internal-audit-2026-q2.html | R-03, R-04 | 2026-05-01 |
| A.8.5 | Secure authentication | Implemented | PortalPilot does not implement password authentication directly. Customer authentication runs through self-hosted Supabase Auth (JWT-based) with secure cookie handling; the HubSpot integration uses the OAuth 2.0 Authorisation Code flow with PKCE. Every authenticated edge function validates the inbound JWT through Supabase before any data access via requireAuth. Operator authentication to the orchestration plane is protected by authenticator-app TOTP per ISMS §4. Tokens stored at rest are AES-256-GCM-encrypted via edge-function shared module (NDA counterpart) — unencrypted tokens are rejected at decrypt time. |
/security, edge-function shared module (NDA counterpart), edge-function shared module (NDA counterpart), security ruleset (NDA counterpart) | R-01, R-03, R-05 | 2026-05-01 |
| A.8.6 | Capacity management | Implemented | Production runs on a single Hetzner Cloud VM in Helsinki with capacity tracked via the Coolify dashboard (CPU, memory, disk, container health) and Hetzner monitoring (network, disk I/O). Edge-function execution latency and worker-eviction patterns are visible via Docker logs (the 150 s idle worker eviction is normal cleanup, documented in edge-function ruleset (NDA counterpart)). Storage capacity is governed by daily backup discipline plus archival pruning. Hetzner provides infrastructure capacity SLA at the IaaS layer; vertical scale-up is a one-step Coolify operation. |
internal architecture documents (NDA counterpart), server-operations ruleset (NDA counterpart), edge-function ruleset (NDA counterpart) | R-08 | 2026-05-01 |
| A.8.7 | Protection against malware | Implemented | Three layers: (1) endpoint — macOS Gatekeeper, System Integrity Protection, and signed-binary enforcement on the founder workstation; (2) infrastructure — Hetzner-managed hardened host images and Supabase official container images for all production services; (3) coding-agent surface — the four-layer agent-security defence model (permission tightening, PreToolUse hooks, canary files, application controls) prevents the local coding agent from being weaponised by prompt-injection content delivered via WebFetch or MCP tool outputs. The Q2 2026 internal audit reviewed and verified all three layers. | agent-security ruleset (NDA counterpart), /compliance/internal-audit-2026-q2.html | R-03, R-06 | 2026-05-01 |
| A.8.8 | Management of technical vulnerabilities | Implemented | Dependency vulnerabilities are surfaced by npm audit running on every PR via the CI quality job; the Q2 2026 internal audit reviewed the full dependency tree, RLS posture, edge-function authentication surface, and agent-surface hooks. Security findings are tracked in the audit document with closure status and Annex-A control mapping. Coolify rebuilds the production container on every push to main, so dependency upgrades reach production within minutes of merge. Mistral substrate version drift is monitored via an automated Mistral alias-check script plus the daily backend-health-check cron (per edge-function ruleset (NDA counterpart)). |
automated CI workflow, /compliance/internal-audit-2026-q2.html, internal security runbook (NDA counterpart) | R-01, R-04, R-07, R-12 | 2026-05-01 |
| A.8.9 | Configuration management | Implemented | All production-affecting configuration is in source control: the CI pipeline (automated CI workflow), the agent-surface engineering rules, the edge-function shared modules, and the application code itself. Coolify drives infrastructure configuration declaratively via service definitions; Hetzner Cloud Firewall rules are managed alongside UFW. Configuration changes follow the standard PR + CI + branch-protection flow; internal contributor guide (NDA counterpart) documents the workflow chain. | automated CI workflow, internal architecture documents (NDA counterpart), internal contributor guide (NDA counterpart) | R-04, R-08 | 2026-05-01 |