You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ISO compliance for Laravel applications: the engineer's field guide
A file per standard, mapping every control theme that has an application layer to concrete Laravel implementations: packages, config, code patterns, tests, and the evidence an auditor or enterprise security questionnaire actually asks for.
File
Standard
One-liner
1-iso-27001-laravel.md
ISO/IEC 27001:2022
Information security management; the Annex A control-by-control Laravel mapping
2-iso-27701-privacy-laravel.md
ISO/IEC 27701:2025
Privacy information management, standalone since the 2025 revision; DSAR, retention, PII engineering
3-iso-42001-ai-laravel.md
ISO/IEC 42001:2023
AI management systems; what to build when your Laravel app ships AI features
No composer package makes you compliant. Every management-system standard (the "-MS" in ISMS/PIMS/AIMS) certifies an organisation running a process: scope, risk assessment, treatment decisions, management review, internal audit, continual improvement. Code delivers the technical controls and, just as important, the evidence.
The app layer is roughly a third of the work. Policies, people (joiner/mover/leaver, training), suppliers (DPAs, terms, reviews), physical/hosting, and incident process are the rest. These files cover the third you can ship as PRs, and name the rest so nobody pretends a middleware closed it.
Evidence beats intention. Auditors and enterprise buyers want artifacts: an audit-log row, a restore-drill document with timestamps, a green CI run, a pruning schedule. Every control below states its evidence artifact.
Build once, reuse everywhere. One honest control set feeds ISO 27001, SOC 2, ISO 27701, GDPR Art. 32, CRA technical files, and every security questionnaire. Do not build per-framework silos.
The Laravel baseline you already own
Before adding anything, document what the framework gives you; these count as implemented controls in any mapping:
Capability
Where
Password hashing (bcrypt/argon2id)
config/hashing.php
Encrypted values + encrypted casts
Crypt, encrypted cast, APP_KEY
CSRF protection
VerifyCsrfToken middleware
SQL injection resistance
Eloquent/query builder bindings
XSS resistance
Blade {{ }} escaping
Session hardening
config/session.php (secure, http_only, same_site)
Signed + temporary URLs
URL::signedRoute()
Rate limiting
RateLimiter + throttle middleware
Authorisation
Policies, gates
Password strength + breach check
Password::min()->uncompromised()
Native 2FA/passkeys/verification flows
Fortify (or Breeze/Jetstream variants)
Scheduled data pruning
model:prune, scheduler
Maintenance + destructive-command guard
DB::prohibitDestructiveCommands()
Disclaimer
Educational engineering notes, not legal advice and not a certification guarantee. Standards texts are copyrighted; buy the current editions (ISO 27001:2022 + Amd 1, 27701:2025, 42001:2023) before an actual certification project.
27001 has two halves. Clauses 4 to 10 define the management system (scope, leadership, risk assessment, objectives, competence, operation, performance evaluation, improvement); they are organisational and no code closes them. Annex A lists 93 controls in 4 themes (organisational, people, physical, technological); you select applicable ones via a Statement of Applicability (SoA) driven by your risk assessment. This file maps every Annex A control with an application layer to a Laravel implementation and its evidence artifact.
Part 1: the management system (no code, know it anyway)
Clause
What the auditor wants
Engineer's contribution
4 Context + scope
One-page scope naming systems, people, suppliers
System inventory, data-flow diagram
5 Leadership + policy
Signed infosec policy, roles
none
6 Risk assessment + SoA
Risk register with treatments; SoA over all 93 controls
Feed real technical risks (dependency compromise, key leak, runner compromise)
7 Support
Training records, docs
Runbooks
8 Operation
Risk treatment executed
The PRs below
9 Performance
Internal audit, mgmt review minutes
Metrics from health/log tooling
10 Improvement
Nonconformity + corrective action log
Incident postmortems
Part 2: Annex A, control by control
Legend: App = implement in Laravel; Infra = hosting/platform; Org = policy/process only. Controls that are purely Org/Physical are listed compressed at the end so your SoA can still cite this mapping.
A.5 Organisational controls with app hooks
Control
Laravel implementation
Evidence
5.15 Access control
Policies + gates for every non-public resource; deny-by-default: register a Gate::before only for super-admin, never a permissive fallback. Route middleware groups (auth, verified, custom team/tenant middleware).
php artisan route:list export showing middleware per route; policy test suite
5.16 Identity management
One identity per human; no shared accounts: enforce unique emails, log admin grants. Machine identities = Passport clients / Sanctum tokens with named scopes.
users + oauth_clients inventory query
5.17 Authentication information
Password::defaults() with min(12)->mixedCase()->numbers()->symbols()->uncompromised(); Fortify 2FA (TOTP + recovery codes) and passkeys; force password confirmation (password.confirm middleware) before sensitive actions.
config diff + feature tests
5.18 Access rights
Provisioning/deprovisioning path: model events revoking tokens/sessions on role change; scheduled report of dormant accounts.
listener code + monthly access-review artifact
5.23 Cloud services security
Supplier register row per cloud service the app calls; keys scoped least-privilege.
register document
5.28 Collection of evidence
Never truncate audit tables casually; document retention of activity_log.
retention schedule
5.33 Protection of records
Backups (8.13) + restrict who can delete audit rows (no delete policy on the log model).
policy test asserting deletion forbidden
5.34 Privacy/PII
Hand off to ISO 27701 file.
cross-ref
A.8 Technological controls (the core of the app work)
8.2 Privileged access rights.
Admin ability behind explicit role + 2FA-required + password.confirm on destructive routes. Log every privileged action (see 8.15).
Evidence: route list + activity log rows for admin actions.
8.3 Information access restriction.
Multi-tenant isolation as code, not convention: global scopes or explicit tenant middleware; policies test the tenant edge (user from team A requesting team B's resource gets 403, proven by a test per resource).
Evidence: the cross-tenant test file.
8.5 Secure authentication.
Fortify (or equivalent) with: email verification, 2FA confirm-before-enable, passkeys where possible, session regeneration on login (framework default), remember-me cookie rotation, and layered rate limits. Rate limits belong at ROUTE registration, dual-keyed:
Hard-won gotchas: attach throttles at route definition (post-hoc Route::getRoutes()->getByName(...)->middleware(...) in a booted callback silently no-ops and breaks under route:cache); clear identity buckets on successful login via a Login event listener or legitimate users lock themselves out; write an HTTP test per throttled endpoint plus a gatherMiddleware() assertion so a silently detached throttle fails CI.
Evidence: the throttle test suite; route:list --json middleware dump.
8.6 Capacity management. Queue workers monitored (Horizon or health checks), scheduled-task overlap prevention (withoutOverlapping), DB connection limits documented.
Evidence: health-check output (see 8.16).
8.7 Malware protection. For uploads: validate mime + extension allow-list, store outside webroot or on object storage, never execute, randomized names; consider clamav via queue for high-risk intake.
Evidence: upload FormRequest rules + test with a disguised payload.
8.8 Technical vulnerability management.
composer audit --locked # CI step, fails on known CVEs
npm audit --omit=dev --audit-level=high
Plus Dependabot/Renovate and a supply-chain gate (Socket or similar) on PRs. Patch SLA in policy (e.g. critical 72h).
Evidence: CI config + a merged security-bump PR trail.
8.9 Configuration management. All config through config/ + env; config:cache in prod; no env() outside config files (add a phpstan rule or grep gate); document prod-vs-dev divergences (debug off, secure cookies on).
Evidence: deploy script + a CI grep asserting env( only under config/.
8.10 Information deletion.model:prune / scheduled jobs per retention schedule; erasure service for user data (see 27701 file for the full pattern).
Evidence: schedule table + pruner tests.
8.11 Data masking. Non-prod uses factories/seeders, never prod dumps; if a prod copy is unavoidable, a scrubbing command rewrites PII columns before restore.
Evidence: the seeding policy + scrub command.
8.12 Data leakage prevention.
Log hygiene: never log request bodies wholesale; redact via Str::mask in log context; set $hidden on models (password, tokens, secrets) so accidental serialization leaks nothing; APP_DEBUG=false in prod (assert in a deploy check).
Evidence: grep audit of log calls; a test asserting a serialized User exposes no secret fields.
8.13 Information backup.spatie/laravel-backup (DB + selected storage to off-site disk, encrypted, with notifications) or platform-native snapshots; either way the control is the tested restore, not the backup:
Evidence: backup config + a dated restore-drill document (quarterly).
8.15 Logging.
Two layers. (1) Security events: listeners on Login, Logout, Failed, Lockout, PasswordReset, token issuance/revocation, writing structured log or audit rows. (2) Data-change audit: spatie/laravel-activitylog (or owen-it/laravel-auditing) on security-relevant models: users, roles, billing state, entitlements:
class User extends Authenticatable
{
use LogsActivity;
publicfunctiongetActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['name', 'email']) // never secrets
->logOnlyDirty()->dontSubmitEmptyLogs();
}
}
Include actor id, ip, ua via a tap/causer resolver. Protect the log (no update/delete policy), prune per schedule (5.28/5.33 tension: keep long enough for forensics).
Evidence: audit rows asserted in feature tests; retention entry.
8.16 Monitoring activities.spatie/laravel-health checks (db, cache/redis, queue heartbeat, scheduler heartbeat, disk, backup freshness) exposed on an authenticated or token-gated endpoint; external uptime monitor pointed at it; alert channel named.
Evidence: monitor screenshots/alert history.
8.17 Clock synchronisation. Infra (NTP); in-app, always store UTC (CarbonImmutable, Date::use).
8.18 Privileged utility programs. Tinker in production is a privileged utility: forbid or gate it (deployment image without tinker, or documented break-glass with logging). Same for artisan db.
Evidence: prod image manifest or policy statement.
8.24 Cryptography.
Key inventory: APP_KEY (rotation procedure that re-encrypts encrypted casts; test it in staging), OAuth keys (Passport keys custody + rotation), webhook secrets, any KMS keys. Field-level: encrypted casts for sensitive columns; blind indexes (ciphersweet) only if you must query them.
Evidence: key inventory doc + one executed rotation drill.
8.25/8.27/8.28 Secure development lifecycle, architecture, coding.
The pipeline is the control: static analysis (PHPStan/Larastan at a pinned level), style (Pint), refactoring safety (Rector dry-run), tests with a coverage floor (and a type-coverage floor if you use Pest), all enforced pre-push and in CI. Document it once as your "secure development procedure": the doc mostly screenshots the pipeline.
Evidence: CI config + a red-then-green PR showing the gate biting.
8.26 Application security requirements. Every input through FormRequests/validated Livewire properties; authorisation in the request (authorize()) or controller policy call; output escaping by default (no {!! !!} without a sanitizer note).
Evidence: a grep gate for {!! occurrences with justifications.
8.29 Security testing. Beyond unit tests: per-surface abuse tests (throttle exhaustion, cross-tenant access, IDOR probes on route-model-binding endpoints, webhook signature failure paths). Schedule an external pentest when customer count justifies it; fix-verify loop recorded.
Evidence: the abuse-test files + pentest report/actions.
Separate keys/secrets per env, no shared DB, .env.production never in repo, staging data synthetic (8.33).
Evidence: env inventory.
8.32 Change management. PRs only, protected main (required green checks, no force push), squash with traceable messages, release/rollback runbook.
Evidence: branch-protection settings export + PR history.
8.34 Protection during audit testing. Auditor/pentest access via time-boxed accounts on staging with synthetic data.
Controls with no app layer (SoA still needs a line each)
ISO/IEC 27701:2025 (privacy / PIMS) for Laravel applications
The 2025 revision (published 2025-10-14) made 27701 a standalone certifiable Privacy Information Management System: you no longer need an ISO 27001 certificate first. It absorbs the security controls it depends on and adds privacy-specific controls for PII controllers and processors. If your legal driver is GDPR and your buyers are European, this is arguably the first certificate worth holding: it attests the privacy programme directly.
Mental model: GDPR tells you what must be true; 27701 is the management system proving you keep it true; Laravel is where half the "keeping" happens.
Part 1: scoping questions that change the build
Controller, processor, or both? A SaaS holding user accounts is a controller for account data and often a processor for customer-content data. Controls differ (consent + purposes vs instructions + subprocessor register). Most Laravel SaaS: both.
PII inventory before code. You cannot minimize, retain, or export what you have not enumerated. Deliverable: a table of every column/log/queue payload holding PII, its purpose, lawful basis, retention, recipients.
One privacy config as the machine-readable record. Keep controller identity, processor list, retention numbers in config/privacy.php (or gdpr.php) and render the human documents from it, so notice, export payload, and code never drift.
Part 2: controller controls mapped to Laravel
Purpose limitation + lawful basis (in code, not just in a doc)
Ship the purposes table inside the app and include it in every data export:
publicfunctionprocessingPurposes(): array
{
return [
['purpose' => 'Account registration and authentication',
'legal_basis' => 'Contract (Art. 6(1)(b))',
'categories' => 'Identity, credentials, security factors'],
['purpose' => 'Security, fraud prevention, service integrity',
'legal_basis' => 'Legitimate interests (Art. 6(1)(f))',
'categories' => 'IP address, user agent, security logs'],
// one row per real purpose; adding a purpose = a PR = a reviewable event
];
}
Evidence: the export payload containing it; a drift test asserting notice page and config agree.
Consent (only where consent is actually the basis)
Do not consent-wash contract-based processing. Where consent applies (marketing, non-essential cookies, optional telemetry): store granular, timestamped, revocable records:
Schema::create('consents', function (Blueprint$t) {
$t->id(); $t->foreignId('user_id')->constrained()->cascadeOnDelete();
$t->string('purpose'); // 'marketing_email', 'product_telemetry'$t->timestamp('granted_at')->nullable();
$t->timestamp('withdrawn_at')->nullable();
$t->string('notice_version'); // which text they saw$t->string('ip')->nullable(); $t->timestamps();
});
Withdrawal must be as easy as granting (a toggle, no email tennis). Evidence: consent rows + the toggle test.
Data subject rights: the DSAR engine
Build one audited pipeline; every right is a request type flowing through it:
enum PrivacyRequestType: string {
case Access = 'access'; case Export = 'export'; case Erasure = 'erasure';
case Rectification = 'rectification'; case Restriction = 'restriction';
case Objection = 'objection';
}
Request log table: type, status (pending/completed/failed), hashed subject email (hash('sha256', $email) so the trail survives erasure without retaining the address), ip, ua, due date (30 days), completion note.
Export (portability). A service that loads every relation and emits versioned JSON: subject profile, memberships, invitations, billing mirrors, tokens/passkey metadata, plus the purposes table and processor list. Rate-limit it (RateLimiter per user per hour). Self-service download beats email delivery (no misdelivery risk).
Erasure. Transactional, complete, verified:
DB::transaction(function () use ($user) {
// 1. access artifacts: oauth tokens + refresh tokens, auth codes,// device codes, personal access tokens, passkeys// 2. billing mirrors (local copies; merchant-of-record keeps its own// records under its legal duties: say so in the confirmation UX)// 3. owned personal teams + invitations; detach memberships// 4. sessions + password reset tokens// 5. null the FK on the request-log row, then delete the user row// 6. assert the row is gone; throw if not
});
Backups: erased data ages out with rotation; document the window in the notice. Evidence: erasure feature test asserting every table, plus the runbook for out-of-band requests (verify identity via a challenge to the account email, never act on a bare inbound address).
Rectification/restriction/objection. Rectification = profile edit paths (document them as the mechanism); restriction = a restricted_at flag honored by outbound processing (mail, telemetry) via a global check; objection = consent withdrawal or a tracked manual request.
Privacy by design defaults
Principle
Laravel pattern
Minimisation
Migration review question "why this column"; nullable analytics FKs; no full request-body logging
Storage limitation
Prunable models + scheduler per the retention schedule; prune ip/ua columns off audit rows after N months while keeping the row
Accuracy
Email re-verification on change (MustVerifyEmail + change flow)
Confidentiality
encrypted casts on sensitive columns; $hidden everywhere secrets live; TLS + secure cookies
Pseudonymisation
Hashed identifiers in logs/analytics (hash('sha256', $id.$pepper)); ciphersweet blind indexes when you must search encrypted PII
Transparency
Notice rendered from config; changelog section in the notice
Incident runbook includes per-tenant notification step with contractual clocks
Part 4: breach support (Art. 33/34 shape)
The app's contribution to the 72-hour clock is detectability and forensics: security-event logging (auth failures, lockouts, token anomalies), audit trail integrity, and an incident register template. Prewrite the assessment form: what data, whose, how many, risk level, notify-or-not rationale.
ISO/IEC 42001:2023 (AI management / AIMS) for Laravel applications
42001 certifies an organisation's AI management system: governance of how AI systems are developed, deployed, and operated responsibly. Companion documents: ISO/IEC 42005 (AI system impact assessment method), ISO/IEC 23894 (AI risk management, the ISO 31000 extension), ISO/IEC 42006 (requirements for the bodies that audit you). None of them are code; all of them dictate code you should have.
Part 0: are you even in scope?
Your Laravel app is AIMS-relevant when it does any of: calls LLM/model APIs (chat, summarisation, extraction, embeddings/RAG), hosts agentic behavior (model output triggers tool/function execution), makes or supports automated decisions about people, or ships AI features customers rely on. A billing portal with zero model calls is a supporting asset, not an AI system; say exactly that in your scope statement and move the AIMS boundary to the products that are.
Part 1: the AI system inventory (the artifact everything else hangs on)
Keep it in code so it cannot rot. A config-driven registry doubles as a runtime gate:
// config/ai.phpreturn [
'systems' => [
'support-summarizer' => [
'purpose' => 'Summarize support threads for staff',
'provider' => 'anthropic', 'model' => 'claude-sonnet-5',
'data_in' => ['ticket bodies (may contain PII)'],
'data_out' => ['summary shown to staff only'],
'autonomy' => 'assistive', // assistive | supervised | autonomous'decision_about_people' => false,
'human_oversight' => 'staff reads before acting',
'enabled' => env('AI_SUPPORT_SUMMARIZER', false),
],
// one entry per AI feature: adding a feature = a PR touching this file
],
];
Rules that make this a control: every model call goes through a service that requires a registry key; unknown key throws; enabled false kills the feature (pair with a feature-flag system like Pennant for gradual rollout and instant kill-switch). Evidence: the registry file's git history is your AI change log.
Part 2: 42001 control themes mapped to Laravel
Governance + policy
Org writes the AI policy (approved uses, prohibited uses, autonomy defaults, egress rules). App enforces the enforceable subset: the registry above, plus provider allow-list:
One assessment per registry entry before first enable, re-run on capability change: affected parties, benefits, harms (wrong output, bias, privacy, security), likelihood, mitigations, residual risk, sign-off. Store them versioned in the repo (docs/ai-impact/<system>.md); a CI check can require the file to exist for every registry key:
test('every AI system has an impact assessment', function () {
foreach (array_keys(config('ai.systems')) as$key) {
expect(file_exists(base_path("docs/ai-impact/{$key}.md")))->toBeTrue();
}
});
AI risk management (ISO 23894 method)
The risks worth engineering controls in a Laravel context:
Risk
Control in code
Prompt injection via user content
Treat model output as untrusted input: never pipe it into {!! !!}, shell, SQL, or Eloquent without validation; strip/deny tool-call syntax from user-supplied text where feasible; system prompts server-side only
Output acted on without review
Autonomy tiers in the registry; supervised tier requires an approval record before side effects (an ai_approvals table: who approved which output, when)
PII leaking to model suppliers
Pre-call redaction pass for known PII fields; registry data_in documents what may flow; suppliers become processor rows in your privacy register (27701 file)
Cost/abuse runaway
Budget guards: per-user and global rate limits on AI routes (RateLimiter), monthly spend counter in cache with a hard cutoff, alerting at 80%
Model/provider drift
Pin model versions in the registry; a canary eval (below) runs on version bumps
Hallucinated references shown as fact
UI labeling (see transparency) + retrieval-grounded responses where accuracy matters, with source links rendered from your own data
Data governance
For RAG/embeddings: document the corpus (what, whose, lawful basis), respect tenant boundaries in vector queries (tenant id in metadata filters, tested like any cross-tenant control), re-embed on erasure (a user's erased content must leave the vector store too: hook the erasure service).
Logging + traceability of AI interactions
Every call through the gateway writes an interaction record: system key, model + version, hashed user id, token counts, latency, refusal/error class, and (policy decision) prompt/response bodies or only hashes. If bodies are stored: they are PII-bearing, so retention + access control + inclusion in DSAR export/erasure all apply (27701 file patterns).
Make oversight a state machine, not a habit: supervised systems produce pending_review artifacts; only a human action transitions them to applied; the transition is audit-logged (activitylog from the 27001 file). Provide the operator an override/disable path that works in seconds (feature flag), and test it.
Transparency
UI labels AI-generated content; docs page lists AI features, providers, and what data leaves your infrastructure (this page is also your GDPR notice input and your sales-questionnaire answer). Registry-rendered so it cannot drift:
Each provider row: terms/DPA link, data-use commitments (training on your inputs? retention?), region, fallback plan. A provider change is a registry PR + impact-assessment delta, not a config hotfix.
Performance evaluation (the AIMS "check" step)
Minimal credible eval loop in a Laravel app: a seeded eval set per system (inputs + expected properties), run as a scheduled job or CI step against the pinned model; failures alert; results retained:
Track over time: refusal rate, error rate, human-override rate from ai_interactions + ai_approvals; that trio is your management-review dashboard.
Incidents + nonconformity
AI-specific incident classes in the runbook: harmful output shipped, data sent to a wrong provider, injection exploited, cost blowout. Same register as security incidents, extra fields: system key, model version, eval added afterward (every AI incident should mint a regression eval).
Part 3: agentic systems (tool-calling) extras
If model output can trigger actions (function calls, MCP tools, code execution):
Capability allow-list per system: the executable tool set is declared next to the registry entry; the executor refuses anything else.
Blast-radius tiers: read-only tools auto-run; mutating tools require the approval state machine; destructive tools are never model-triggerable.
Sandboxing: execution in throwaway environments (containers/workspaces), never the production runtime user.
Full action audit: every tool invocation logged with arguments (redacted per policy) and outcome; the audit stream is append-only.
Deterministic gates: after any judge/validator model, a plain-code check (grep, schema validation, threshold) makes the final accept/reject; a model never solely approves its own work.
Part 4: evidence pack checklist
AI system registry (config) + gateway enforcing it, with tests
Impact assessment file per system (42005-shaped) + the CI existence test
Interaction + approval tables with retention entries
Provider register with data-use terms
Transparency page rendered from the registry
Eval job + result history; override/disable drill (flip the flag, screenshot)
AI incident register (even if empty) + one tabletop exercise note
No package delivers 42001. The registry, the assessments, and the oversight state machine are the certificate-shaped part; they are all small Laravel code.
The rest of the alphabet: other ISO standards and the EU laws that outrank them
ISO/IEC 27017 (cloud security) and 27018 (PII in public cloud)
Written primarily for cloud providers. As a Laravel shop you are usually a cloud customer; your duties collapse into: pick providers holding these certificates (check their trust pages), configure your side correctly (bucket privacy, key scoping, region pinning), and record shared-responsibility per service in your supplier register. Get certified against these yourself only if you operate a multi-tenant platform marketed as cloud infrastructure. App-layer touchpoints: encrypt before upload for sensitive objects (Storage::put of Crypt-ed payloads or SSE settings), signed temporary URLs over public buckets, per-tenant path prefixes with authorisation tests.
ISO 22301 (business continuity)
A full BCMS certificate is overkill below serious enterprise scale; the substance for a Laravel product is four artifacts: (1) RTO/RPO declared per system; (2) tested backups (restore drill with timestamps, quarterly); (3) a degraded-mode story (queue backlog handling, maintenance mode with php artisan down --secret=... for staff access, feature flags to shed load); (4) a dependency-outage playbook per critical supplier (payment provider down, mail down, model provider down). Fold these into the 27001 evidence; cite 22301 alignment in questionnaires.
ISO 9001 (quality) and ISO/IEC 20000-1 (service management)
RFP-driven only. If forced: 9001 maps onto your existing SDLC (PRs, reviews, CI gates, release notes, defect tracking = "quality records"); 20000-1 maps onto support/SLA process. Neither has meaningful Laravel-specific controls beyond what 27001's 8.25 to 8.32 already produced. Do not pursue speculatively.
The EU laws (these are not optional and not certificates)
GDPR
Law, applies now to any EU-relevant processing of personal data. The entire 27701 file doubles as your GDPR technical implementation guide: DSAR engine, retention, consent where applicable, processor register, breach support. Legal deliverables no framework provides: the notice text, the roles analysis (controller/processor per flow), DPAs with every processor, transfer mechanisms for non-EEA suppliers (DPF/SCCs).
Applies to products with digital elements placed on the EU market: shipped binaries, installable software, and (nuance) the remote services integral to the product's function can be pulled into the product boundary. Pure SaaS is largely out; a downloadable CLI/agent/desktop app is in.
Date
Duty
2026-09-11
Report actively exploited vulnerabilities: early warning 24h, notification 72h, report 14d, to your national CSIRT + ENISA; applies to products already on the market
2027-12-11
Full essential requirements, conformity assessment (self-assessment for default-category products), CE marking, technical documentation
Laravel/product-adjacent work: coordinated vulnerability disclosure policy (SECURITY.md + contact), SBOM per release (composer licenses/CycloneDX generators, cyclonedx/cyclonedx-php-composer), signed update channels with rollback, declared support period, secure defaults. If you only run SaaS, you still meet CRA indirectly when your customers ask for your components' SBOMs.
NIS2
Sector + size thresholds (generally 50+ staff or 10M+ EUR revenue in listed sectors, with carve-ins for some digital providers). Most small SaaS vendors: out of scope; write the one-line applicability decision down, revisit at each size jump or if you become a managed/cloud/DNS service provider.
EU AI Act
Risk-tiered law, phased 2025 to 2027. Selling developer tooling or embedding LLM features rarely lands in high-risk Annex III; general-purpose model duties sit with model providers, not integrators. Integrator duties that do reach a Laravel app: transparency (users must know they interact with AI or AI-generated content: the labeling + disclosure page from the 42001 file), and avoiding prohibited practices (no emotion recognition at work, no social scoring). Track the harmonised standards as they land; your 42001-shaped registry + impact assessments are exactly the preparation.
Priority order for a small EU Laravel SaaS/product vendor
GDPR: law, now (27701 file patterns).
CRA: law with hard dates if you ship product binaries (2026-09-11 reporting readiness first).
27001-shaped controls without certification: evidence for every questionnaire.
27701:2025 certification: first certificate if buyers need paper and privacy is your story.
42001: registry + impact assessments now if you ship AI features; certificate only on buyer demand.