Compliance 21 min read Markdown

ISO 27001 for Laravel Applications: Controls, Annex A, and What Developers Must Implement

ISO 27001:2022 defines 93 Annex A controls across four domains. This guide maps the technological controls that directly affect Laravel developers to specific implementations: access control, authentication, logging, cryptography, secure development, and continuous monitoring.

Matt King
Matt King
June 25, 2026
Last updated: June 25, 2026
ISO 27001 for Laravel Applications: Controls, Annex A, and What Developers Must Implement

ISO 27001 certification has shifted from a nice-to-have enterprise signal to a sales prerequisite. If you are a SaaS company selling to enterprise buyers in healthcare, financial services, or government sectors, the security questionnaire will ask for it. Lose enough deals over it and the business case becomes obvious.

But ISO 27001 is an information security management system standard, not a checklist of technical controls. Understanding what it actually requires, and specifically which parts fall on developers rather than executives or compliance officers, is what makes the difference between a certification that sits on a wall and one that reflects how your application is actually built.

This guide maps the ISO 27001:2022 Annex A technological controls to specific Laravel implementations so your engineering team knows exactly what to build.


What ISO 27001 Is

ISO 27001 is an international standard published by the International Organization for Standardization (ISO) and the International Electrotechnical Commission (IEC). The full name is ISO/IEC 27001: Information security, cybersecurity and privacy protection.

The 2022 revision (ISO 27001:2022) replaced the 2013 version. The major changes in 2022 were structural: the 114 controls across 14 domains in the 2013 edition were reorganised and consolidated into 93 controls across 4 domains. The underlying security requirements did not fundamentally change, but new controls were added for threat intelligence, cloud security, ICT readiness, and secure coding.

At its core, ISO 27001 requires you to build, operate, and continually improve an Information Security Management System (ISMS). An ISMS is not a software product. It is a documented framework of policies, processes, risk assessments, and controls that governs how your organisation protects information.

Certification vs compliance. Compliance means you believe you meet the requirements. Certification means an accredited third-party certification body has audited your ISMS and confirmed it meets the requirements. Only certification carries the ISO 27001 mark.

Who needs it. SaaS companies selling to enterprise clients, healthcare organisations handling patient data, fintech companies, managed service providers, and any organisation whose customers contractually require it.


ISO 27001:2022 Structure

The standard is divided into two parts that serve different purposes.

Clauses 4 to 10 define the mandatory ISMS requirements. Every organisation seeking certification must comply with all of them:

  • Clause 4: Understanding the organisation and its context
  • Clause 5: Leadership and commitment
  • Clause 6: Planning (risk assessment, risk treatment, objectives)
  • Clause 7: Support (resources, competence, documentation)
  • Clause 8: Operation (executing the risk treatment plan)
  • Clause 9: Performance evaluation (internal audits, management review)
  • Clause 10: Improvement (nonconformities, corrective action)

These clauses deal with governance, risk management, and process. They are primarily the responsibility of leadership and the ISMS owner, not individual developers.

Annex A contains the 93 security controls organised into four domains:

  • Organisational controls (37 controls): Policies, roles, supplier relationships, incident management
  • People controls (8 controls): Screening, terms of employment, security awareness training
  • Physical controls (14 controls): Physical access, equipment security, media disposal
  • Technological controls (34 controls): Access control, authentication, cryptography, logging, monitoring, secure development

Developers spend most of their time in the Technological controls. These controls describe specific technical requirements that must be implemented in your applications and infrastructure.


Annex A Technological Controls that Affect Laravel Applications

A.8.2 — Privileged Access Rights

This control requires that privileged access rights be restricted, managed, and reviewed. In a Laravel application, privilege management is implemented through Gates, Policies, and role-based access control (RBAC).

The principle is that users should only have the access they need for their specific job function. A customer service user should not have access to billing data. A read-only analyst role should not have write permissions.

// app/Policies/OrderPolicy.php
public function update(User $user, Order $order): bool
{
    return $user->hasRole('admin') || $user->hasRole('account-manager');
}

For ISO 27001 evidence, you need to document your role definitions, demonstrate that roles are reviewed periodically (typically quarterly), and show that access is revoked when employees leave or change roles. Your ISMS should include an access control policy that references these technical controls.

A.8.5 — Secure Authentication

This control requires that secure authentication technologies and procedures be implemented to control access to information systems. For Laravel applications, this means:

Multi-factor authentication. Laravel Fortify provides built-in MFA support using time-based one-time passwords (TOTP). For applications handling sensitive data, MFA for administrative accounts is typically required to satisfy this control.

// config/fortify.php
'features' => [
    Features::twoFactorAuthentication([
        'confirm' => true,
        'confirmPassword' => true,
    ]),
],

Session timeout. ISO 27001 auditors expect idle session timeouts. Configure this in config/session.php:

// config/session.php
'lifetime' => 30, // minutes
'expire_on_close' => false,

Password policy. Enforce minimum complexity requirements using Laravel's Password rule:

use Illuminate\Validation\Rules\Password;

Password::min(12)
    ->mixedCase()
    ->numbers()
    ->symbols()
    ->uncompromised()

The uncompromised() check queries the Have I Been Pwned API to reject passwords from known breach datasets.

A.8.7 — Protection Against Malware

This control requires that protection against malware be implemented and supported by appropriate user awareness. For Laravel applications, the primary malware vector is compromised dependencies.

Run composer audit in your CI/CD pipeline to detect known vulnerabilities in PHP dependencies:

composer audit --no-dev --format=json

External attack surface monitoring complements dependency scanning by continuously checking your live application for exposed endpoints, outdated components, and misconfiguration. StackShield provides continuous external monitoring that detects these issues as they emerge, rather than only at deployment time.

A.8.9 — Configuration Management

This control requires that configurations, including security configurations, of hardware, software, services, and networks be established, documented, implemented, monitored, and reviewed. For Laravel:

  • Never commit .env files to version control. Use .gitignore to exclude them
  • Use environment-specific .env files and secrets management tools (AWS Secrets Manager, HashiCorp Vault, Laravel's own encrypted environment files with php artisan env:encrypt)
  • Run php artisan config:cache in production to cache configuration and prevent runtime .env file reads
  • Document your configuration baseline and review it when infrastructure changes
# Deployment pipeline
php artisan config:cache
php artisan route:cache
php artisan view:cache

Treat every configuration change to a production environment as a change management event that is logged, reviewed, and traceable.

A.8.11 — Data Masking

This control requires that data masking be used in accordance with your organisation's data masking policy and relevant regulations. In Laravel, this means preventing sensitive data from appearing in logs.

Configure LOG_LEVEL=error in production to reduce log verbosity. For application logs, use custom processors to redact sensitive fields:

// app/Logging/RedactSensitiveDataProcessor.php
class RedactSensitiveDataProcessor
{
    private array $sensitiveKeys = ['password', 'token', 'api_key', 'credit_card', 'ssn'];

    public function __invoke(array $record): array
    {
        foreach ($this->sensitiveKeys as $key) {
            if (isset($record['context'][$key])) {
                $record['context'][$key] = '[REDACTED]';
            }
        }
        return $record;
    }
}

Register this processor in your config/logging.php channel configuration. ISO 27001 auditors will ask to see evidence that sensitive data cannot appear in your log storage.

A.8.12 — Data Leakage Prevention

This control requires that measures be applied to detect and prevent the unauthorised disclosure of information. Several common Laravel misconfigurations leak data:

Debug mode in production. APP_DEBUG=true in production exposes stack traces containing environment variables, database credentials, and application internals to anyone who triggers an error. Confirm this is disabled:

php artisan about | grep Debug

Telescope in production. Laravel Telescope records every request, query, job, cache hit, and mail sent by your application. If the Telescope dashboard is accessible without authentication in production, it is a data leakage incident waiting to happen. Either disable Telescope in production or enforce strict authentication:

// app/Providers/TelescopeServiceProvider.php
protected function gate(): void
{
    Gate::define('viewTelescope', function (User $user) {
        return in_array($user->email, config('telescope.allowed_emails'));
    });
}

Security headers. Add X-Content-Type-Options, X-Frame-Options, Referrer-Policy, and Content-Security-Policy headers to prevent browsers from leaking information to third parties.

A.8.15 — Logging

This control requires that logs that record activities, exceptions, faults, and other relevant events be produced, stored, protected, and analysed. This is one of the controls where developers have the most direct responsibility.

ISO 27001 auditors expect logs that capture:

  • Authentication events: successful logins, failed logins, logouts
  • Privilege changes: role assignments, permission modifications
  • Data access: reads and writes to sensitive records
  • Configuration changes: changes to application or infrastructure settings
  • Security events: rate limit hits, suspicious input patterns, error spikes

Laravel's Log facade and custom channels make this straightforward:

// Log a security event
Log::channel('security')->info('Authentication success', [
    'user_id' => $user->id,
    'ip' => $request->ip(),
    'user_agent' => $request->userAgent(),
    'timestamp' => now()->toIso8601String(),
]);

Define a dedicated security log channel in config/logging.php that writes to a separate file or log aggregation service. Log retention is a specific requirement: most ISO 27001 implementations require logs to be retained for a minimum of twelve months, with the most recent three months immediately accessible.

A.8.16 — Monitoring Activities

This control requires that networks, systems, and applications be monitored and anomalies evaluated. Continuous external monitoring is the primary way developers satisfy this control.

Internal logging captures events your application knows about. External monitoring captures what your application cannot see: its own availability from the internet, exposed ports and services, SSL certificate expiry, domain security misconfigurations, and changes to your attack surface.

StackShield provides continuous external monitoring for Laravel applications. Each scan generates a timestamped report of your application's security posture from an external attacker's perspective. For ISO 27001, this scan history serves as direct evidence that monitoring was in place and that findings were remediated, exactly the evidence auditors request for A.8.16.

A.8.24 — Use of Cryptography

This control requires that rules for the effective use of cryptography be defined and implemented. For Laravel applications:

Application key. Your APP_KEY must be a cryptographically random 32-byte key. Generate it with php artisan key:generate. Rotate it if compromised. Store it only in environment variables, never in version control.

Password hashing. Laravel uses bcrypt by default with a cost factor of 12. Do not reduce the cost factor below 10. For new applications, consider Argon2id:

// config/hashing.php
'driver' => 'argon2id',
'argon' => [
    'memory' => 65536,
    'threads' => 1,
    'time' => 4,
],

TLS enforcement. All data in transit must use TLS 1.2 or higher. Enforce HTTPS in production by setting FORCE_HTTPS=true or using middleware:

// app/Http/Middleware/ForceHttps.php
if (!$request->secure() && app()->environment('production')) {
    return redirect()->secure($request->getRequestUri());
}

Configure your web server to disable TLS 1.0 and 1.1 at the infrastructure level.

A.8.25 — Secure Development Lifecycle

This control requires that rules for the secure development of software and systems be defined and applied. For Laravel teams, this means integrating security into your CI/CD pipeline rather than treating it as an afterthought:

# .github/workflows/security.yml
- name: Composer security audit
  run: composer audit --no-dev

- name: PHP security checks
  run: ./vendor/bin/phpstan analyse --level=8

- name: Run tests
  run: php artisan test --parallel

Code review processes should include security checklists. Pull requests that introduce new database queries, authentication logic, or external integrations should require explicit security sign-off.

A.8.28 — Secure Coding

This control requires that secure coding principles be applied to software development. For Laravel, this maps directly to OWASP Top 10 mitigations:

SQL Injection. Always use Eloquent or the query builder with parameterised bindings. Never interpolate user input into raw SQL:

// Vulnerable
DB::select("SELECT * FROM users WHERE email = '$email'");

// Safe
DB::select('SELECT * FROM users WHERE email = ?', [$email]);
User::where('email', $email)->first();

Cross-Site Scripting (XSS). Blade's {{ }} syntax escapes output by default. Only use {!! !!} for trusted HTML you control. Validate and sanitise HTML content from users using a library like HTMLPurifier.

Input validation. Validate all request input using Form Requests before it reaches your business logic:

public function rules(): array
{
    return [
        'email' => ['required', 'email:rfc,dns', 'max:255'],
        'amount' => ['required', 'integer', 'min:1', 'max:1000000'],
    ];
}

Mass assignment. Define $fillable on every Eloquent model. Never use $guarded = [] in production models that handle user-supplied data.


Risk Assessment for a Laravel Application

ISO 27001 requires you to maintain a risk register. This is not optional and it is not theoretical. The risk register is one of the first documents an auditor requests.

For a Laravel SaaS application, your information assets typically include:

  • User PII and application data stored in your database
  • API keys and credentials in your environment files and secrets manager
  • Application source code in your version control system
  • Infrastructure configuration including server settings, DNS records, and cloud IAM policies
  • Backup archives containing historical data

For each asset, you identify realistic threats:

  • External attackers exploiting vulnerabilities in your application or dependencies
  • Misconfiguration by developers deploying changes without security review
  • Dependency vulnerabilities introduced through composer update without auditing
  • Insider threats including developers with excessive database access
  • Third-party breach where a SaaS tool you use is compromised and leaks your data

You document each risk with a likelihood score (typically 1-5) and an impact score (typically 1-5), producing a risk rating. High-rated risks require controls. Low-rated risks can be accepted and monitored. The risk register must be reviewed and updated at least annually, and after any significant change to your application, infrastructure, or threat landscape.

The risk treatment plan documents what you are doing about each risk: implement a control, transfer the risk (insurance), avoid the risk (stop doing the thing), or accept it. Every Annex A control you implement should trace back to a risk in your register.


Evidence Collection for ISO 27001 Audit

ISO 27001 auditors do not take your word for it. They request evidence that your controls exist, are operational, and are effective. For a technical ISO 27001 audit, expect requests for:

Access control evidence. Your role definitions, a list of who has access to what, records of access reviews, and evidence of access revocation when employees leave.

Change management logs. Git commit history, deployment logs, and records of changes to production configuration. Untracked .env changes are a gap auditors frequently flag.

Vulnerability scan reports. Results from composer audit, static analysis tools, and external security scans. The auditor wants to see not just that scans ran, but that findings were reviewed and remediated within a defined timeframe.

Incident log. A record of every security incident or near-miss, including the date discovered, severity, actions taken, and resolution. An empty incident log does not mean you had no incidents. It often means you have no detection capability.

Monitoring evidence. Logs showing that your application was monitored continuously during the audit period. This is where StackShield's scan history directly serves your audit. Each completed scan is a timestamped record showing what your external attack surface looked like and whether issues were remediated. Auditors assessing A.8.16 want to see exactly this kind of continuous monitoring evidence.

Penetration test report. While not mandated by name in the standard, most auditors expect at least one penetration test report as evidence that controls are effective against realistic attacks.


Common Gaps Laravel Teams Fail on in ISO 27001 Audits

After working with multiple SaaS companies through their first ISO 27001 audit, the same gaps appear repeatedly.

No log retention policy. Security logs exist, but no one documented how long they are retained or where they are stored. The answer "we keep logs until the disk fills up" fails the audit.

No formal vulnerability disclosure process. When a vulnerability is found (through composer audit, an external scan, or a bug report), there is no documented procedure for how it is triaged, assigned, and resolved within a defined SLA. ISO 27001 requires this process to be documented, not just practised informally.

Developers with direct production database access. Several team members have credentials that allow direct mysql access to the production database. There is no record of who accessed what data or when. This fails A.8.2 (privileged access) and A.8.15 (logging) simultaneously.

No change management for .env modifications. Changes to production environment variables are made directly on the server by whoever has SSH access, with no record of what changed, when, or why. This is a configuration management failure under A.8.9.

Telescope accessible in production. Laravel Telescope is installed and accessible at /telescope without authentication in production. This is a data leakage incident and a direct failure of A.8.12.

Missing asset inventory. The risk register references "the database" without specifying which database, what data it contains, where it is hosted, and who has access. Auditors reject asset registers that are not specific.


Conclusion

ISO 27001 is achievable for Laravel teams. Most of the Annex A technological controls map directly to configurations and patterns you already know: Gates and Policies for access control, Fortify for authentication, the Log facade for security event logging, composer audit for dependency scanning, and environment variable management for secrets.

The gap between "we do this informally" and "we have documented evidence that we do this" is what the certification process surfaces and closes. The documentation is not bureaucracy for its own sake. It is the forcing function that turns good intentions into verified, audited practice.

If you are preparing for ISO 27001 certification, start with a free security scan of your Laravel application at StackShield's free scan tool. The report identifies misconfiguration, exposed endpoints, and missing controls that are directly relevant to Annex A Technological controls, and gives you a baseline you can reference in your risk register and present to auditors as evidence of external monitoring.

Free security check

Is your Laravel app exposed right now?

34% of Laravel apps we scan have at least one critical issue. Most teams don't find out until something breaks. Our free scan checks your live application in under 60 seconds.

18% have debug mode on
72% missing security headers
12% have exposed .env
Scan My App Free No signup required. Results in 60 seconds.

Frequently Asked Questions

Is ISO 27001 certification required or optional?

ISO 27001 certification is voluntary under most jurisdictions. No law mandates it directly. However, it becomes practically required when enterprise customers, government procurement processes, or regulated industry partners make it a contractual condition. A growing number of enterprise procurement teams and partner security questionnaires treat ISO 27001 certification as a baseline requirement rather than a differentiator. If you sell SaaS to healthcare, financial services, or government sectors, certification is often expected before a contract is signed.

How long does ISO 27001 certification take for a SaaS company?

Most SaaS companies take six to eighteen months from starting their ISMS implementation to receiving certification. The timeline depends on your starting point. If you have mature security controls already documented and practised, you can compress the timeline to six months. If you are starting from scratch with no formal policies, no risk register, and no documented controls, twelve to eighteen months is realistic. The certification audit itself consists of a Stage 1 document review and a Stage 2 evidence audit, typically conducted over several days by an accredited certification body.

What is the difference between ISO 27001 and SOC 2?

ISO 27001 and SOC 2 are both information security frameworks but they differ in origin, structure, and audience. ISO 27001 is an international standard published by ISO and IEC. Certification is binary: you are certified or you are not. The standard requires an ISMS with defined scope, risk assessment, risk treatment, and implementation of applicable Annex A controls. SOC 2 is a US-based attestation framework from the AICPA based on Trust Service Criteria. It produces an audit report rather than a certificate. SOC 2 is more common for US customers, ISO 27001 for European and enterprise-global customers. Many SaaS companies pursue both. The controls overlap significantly, so building one often accelerates the other.

Does ISO 27001 require penetration testing?

ISO 27001 does not explicitly mandate penetration testing as an annual requirement in the same way PCI DSS does. However, Annex A control A.8.8 (Management of technical vulnerabilities) and A.8.25 (Secure development life cycle) strongly imply that you test your controls, which auditors interpret as requiring evidence of vulnerability assessments and penetration testing. Most certification bodies expect to see at least one penetration test report as evidence that your ISMS controls are effective. Continuous external monitoring, as provided by tools like StackShield, supplements penetration testing by providing ongoing vulnerability detection between point-in-time tests.

Can a small Laravel team achieve ISO 27001 certification?

Yes. ISO 27001 scales to any organisation size. The standard explicitly allows you to scope your ISMS narrowly, covering only the systems and processes relevant to your product. A five-person Laravel SaaS team can define a scope limited to the application itself, its infrastructure, and the data it processes. The documentation burden is real but manageable. Many small teams use ISMS platforms like Vanta, Drata, or Sprinto to automate evidence collection and policy management. The key is proportionality: your controls and documentation should match the risks you face, not the controls of a 10,000-person enterprise.

Stay Updated on Laravel Security

Get actionable security tips, vulnerability alerts, and best practices for Laravel apps.