ISO 27001: Implementing Information Security Management Systems
A practical guide to implementing ISO 27001 in technology organisations. From gap analysis to certification, with focus on integrating ISMS into DevOps practices.
ISO 27001: Implementing Information Security Management Systems
ISO 27001 is the international standard for information security management. For technology organisations, implementing an ISMS isn't just about compliance—it's about building systematic, risk-based security that scales with your business.
Understanding ISO 27001
What ISO 27001 Covers
ISO 27001 Framework:
├── Context of the Organisation
│ ├── Understanding the organisation
│ ├── Understanding stakeholder needs
│ ├── Scope of ISMS
│ └── Information security management system
├── Leadership
│ ├── Leadership commitment
│ ├── Information security policy
│ └── Roles and responsibilities
├── Planning
│ ├── Risk assessment
│ ├── Risk treatment
│ └── Information security objectives
├── Support
│ ├── Resources
│ ├── Competence
│ ├── Awareness
│ ├── Communication
│ └── Documented information
├── Operation
│ ├── Operational planning
│ ├── Risk assessment execution
│ └── Risk treatment implementation
├── Performance Evaluation
│ ├── Monitoring and measurement
│ ├── Internal audit
│ └── Management review
└── Improvement
├── Nonconformity handling
└── Continual improvementAnnex A Controls (ISO 27001:2022)
The 2022 version reorganised controls into four themes:
| Theme | Controls | Examples |
|---|---|---|
| Organisational (37) | Policies, roles, supplier relationships | Information security policies, segregation of duties |
| People (8) | HR security, awareness | Screening, terms of employment, awareness training |
| Physical (14) | Secure areas, equipment | Physical entry controls, equipment maintenance |
| Technological (34) | Access, cryptography, operations | Access rights, encryption, malware protection |
Phase 1: Gap Analysis
Current State Assessment
// gap-analysis-framework.ts
interface ControlAssessment {
controlId: string;
controlName: string;
currentState: 'not_implemented' | 'partial' | 'implemented' | 'not_applicable';
maturityLevel: 1 | 2 | 3 | 4 | 5;
gaps: string[];
evidence: string[];
remediation: RemediationItem[];
}
interface RemediationItem {
action: string;
priority: 'critical' | 'high' | 'medium' | 'low';
owner: string;
targetDate: Date;
estimatedEffort: string;
}
const assessControl = (
controlId: string,
requirements: string[],
currentPractices: string[]
): ControlAssessment => {
const gaps = requirements.filter(
req => !currentPractices.some(practice =>
practice.toLowerCase().includes(req.toLowerCase())
)
);
const coverage = (requirements.length - gaps.length) / requirements.length;
let currentState: ControlAssessment['currentState'];
if (coverage === 0) currentState = 'not_implemented';
else if (coverage < 0.7) currentState = 'partial';
else currentState = 'implemented';
return {
controlId,
controlName: getControlName(controlId),
currentState,
maturityLevel: calculateMaturity(coverage),
gaps,
evidence: currentPractices,
remediation: generateRemediationPlan(gaps)
};
};Gap Analysis Checklist
# gap-analysis-checklist.yml
organisational_controls:
A.5.1_policies:
requirements:
- Information security policy document exists
- Policy approved by management
- Policy communicated to employees
- Regular policy review process
evidence_sources:
- Policy documents
- Approval records
- Communication logs
- Review meeting minutes
A.5.2_roles:
requirements:
- Information security roles defined
- Responsibilities documented
- Segregation of duties implemented
- Role assignments current
evidence_sources:
- Job descriptions
- Organisation charts
- Access control matrices
- HR records
A.5.15_access_control:
requirements:
- Access control policy exists
- Business requirements documented
- Access provisioning process defined
- Regular access reviews conducted
evidence_sources:
- Access control policy
- Access request forms
- Review records
- System access logs
technological_controls:
A.8.2_privileged_access:
requirements:
- Privileged access policy exists
- Privileged accounts identified
- Access restricted and monitored
- Regular privileged access review
evidence_sources:
- PAM solution logs
- Admin account inventory
- Access review records
- Monitoring dashboards
A.8.24_cryptography:
requirements:
- Cryptographic policy exists
- Key management procedures
- Approved algorithms defined
- Certificate management process
evidence_sources:
- Cryptography policy
- Key inventory
- Certificate records
- Algorithm standardsPhase 2: Risk Assessment
Risk Assessment Methodology
// risk-assessment.ts
interface Asset {
id: string;
name: string;
type: 'information' | 'software' | 'hardware' | 'service' | 'people';
owner: string;
classification: 'public' | 'internal' | 'confidential' | 'restricted';
businessValue: 1 | 2 | 3 | 4 | 5;
}
interface Threat {
id: string;
name: string;
category: 'natural' | 'human_deliberate' | 'human_accidental' | 'technical';
likelihood: 1 | 2 | 3 | 4 | 5;
}
interface Vulnerability {
id: string;
description: string;
exploitability: 1 | 2 | 3 | 4 | 5;
}
interface Risk {
id: string;
asset: Asset;
threat: Threat;
vulnerability: Vulnerability;
impact: {
confidentiality: 1 | 2 | 3 | 4 | 5;
integrity: 1 | 2 | 3 | 4 | 5;
availability: 1 | 2 | 3 | 4 | 5;
};
inherentRisk: number;
controls: Control[];
residualRisk: number;
riskTreatment: 'mitigate' | 'accept' | 'transfer' | 'avoid';
}
const calculateRiskScore = (risk: Risk): number => {
const impactScore = Math.max(
risk.impact.confidentiality,
risk.impact.integrity,
risk.impact.availability
);
const likelihoodScore = risk.threat.likelihood *
risk.vulnerability.exploitability / 5;
return Math.round(impactScore * likelihoodScore * risk.asset.businessValue / 5);
};
const assessResidualRisk = (
inherentRisk: number,
controls: Control[]
): number => {
const controlEffectiveness = controls.reduce((acc, control) => {
return acc * (1 - control.effectiveness / 100);
}, 1);
return Math.round(inherentRisk * controlEffectiveness);
};Risk Register Template
# risk-register.yml
risks:
- id: RISK-001
title: Unauthorised access to customer data
asset: Customer Database
threat: External attacker exploiting weak authentication
vulnerability: Legacy authentication without MFA
impact:
confidentiality: 5
integrity: 3
availability: 2
likelihood: 4
inherent_risk: 20
existing_controls:
- Firewall restrictions
- Password policy
control_effectiveness: 40%
residual_risk: 12
risk_appetite: 8
treatment: mitigate
planned_controls:
- Implement MFA
- Deploy SIEM monitoring
risk_owner: CISO
review_date: 2025-03-01
- id: RISK-002
title: Data loss from ransomware attack
asset: File servers
threat: Ransomware infection via phishing
vulnerability: Insufficient backup isolation
impact:
confidentiality: 3
integrity: 5
availability: 5
likelihood: 3
inherent_risk: 15
existing_controls:
- Antivirus software
- Email filtering
- Daily backups
control_effectiveness: 50%
residual_risk: 8
risk_appetite: 8
treatment: accept
risk_owner: IT Director
review_date: 2025-03-01Phase 3: Policy Development
Information Security Policy Structure
# Information Security Policy Framework
## Tier 1: Information Security Policy
- Management commitment
- Security objectives
- Scope and applicability
- Compliance requirements
- Review and update process
## Tier 2: Topic-Specific Policies
├── Access Control Policy
├── Acceptable Use Policy
├── Data Classification Policy
├── Cryptography Policy
├── Physical Security Policy
├── Incident Management Policy
├── Business Continuity Policy
├── Supplier Security Policy
└── Human Resources Security Policy
## Tier 3: Procedures and Standards
├── Password Standard
├── Encryption Standard
├── Secure Development Procedures
├── Backup Procedures
├── Incident Response Procedures
└── Access Review ProceduresSample Access Control Policy
// access-control-policy.ts
interface AccessControlPolicy {
version: string;
effectiveDate: Date;
owner: string;
approver: string;
principles: {
leastPrivilege: string;
needToKnow: string;
segregationOfDuties: string;
defaultDeny: string;
};
accessTypes: {
physical: PhysicalAccessRules;
logical: LogicalAccessRules;
remote: RemoteAccessRules;
};
lifecycle: {
provisioning: ProvisioningProcess;
review: ReviewProcess;
deprovisioning: DeprovisioningProcess;
};
}
const accessControlPolicy: AccessControlPolicy = {
version: '2.0',
effectiveDate: new Date('2025-01-01'),
owner: 'CISO',
approver: 'CTO',
principles: {
leastPrivilege: 'Users shall be granted minimum access required for their role',
needToKnow: 'Access to information based on legitimate business need',
segregationOfDuties: 'Critical functions require multiple approvals',
defaultDeny: 'Access denied unless explicitly granted'
},
accessTypes: {
physical: {
areas: ['public', 'restricted', 'secure', 'highly_secure'],
controls: ['badge', 'biometric', 'escort', 'dual_control'],
reviewFrequency: 'quarterly'
},
logical: {
authentication: ['password', 'mfa', 'certificate'],
authorisation: ['rbac', 'abac'],
reviewFrequency: 'quarterly'
},
remote: {
methods: ['vpn', 'zero_trust'],
requirements: ['mfa', 'device_compliance'],
monitoring: 'continuous'
}
},
lifecycle: {
provisioning: {
approval: 'manager_and_data_owner',
sla: '24_hours',
documentation: 'ticket_system'
},
review: {
frequency: 'quarterly',
scope: 'all_access_rights',
owner: 'system_owners'
},
deprovisioning: {
trigger: 'termination_or_transfer',
sla: '4_hours',
verification: 'security_team'
}
}
};Phase 4: Control Implementation
Technical Controls Implementation
# control-implementation-plan.yml
A.8.2_privileged_access:
objective: Restrict and monitor privileged access
implementation:
phase_1_discovery:
- Inventory all privileged accounts
- Map privileged access to systems
- Identify service accounts
- Document current access patterns
phase_2_tooling:
- Deploy PAM solution (CyberArk/HashiCorp Vault)
- Configure session recording
- Implement just-in-time access
- Set up monitoring and alerting
phase_3_process:
- Define privileged access request workflow
- Create emergency access procedures
- Establish review cadence
- Document escalation paths
phase_4_operation:
- Migrate accounts to PAM
- Enable continuous monitoring
- Conduct access reviews
- Generate compliance reports
success_criteria:
- All privileged accounts in PAM
- Session recording for all admin access
- Quarterly access reviews completed
- No shared admin credentials
A.8.24_cryptography:
objective: Ensure proper use of cryptography
implementation:
phase_1_inventory:
- Catalogue encryption usage
- Identify key management practices
- Map certificate landscape
- Document cryptographic standards
phase_2_standards:
- Define approved algorithms
- Establish key lengths
- Create key lifecycle procedures
- Set certificate policies
phase_3_tooling:
- Deploy key management system
- Implement certificate management
- Configure automated rotation
- Set up expiry monitoring
phase_4_migration:
- Upgrade weak encryption
- Migrate to approved algorithms
- Implement automated rotation
- Enable compliance reporting
approved_algorithms:
symmetric: [AES-256-GCM, ChaCha20-Poly1305]
asymmetric: [RSA-4096, ECDSA-P384]
hashing: [SHA-256, SHA-384, SHA-512]
key_exchange: [ECDH-P384, X25519]Integrating with DevOps
# .github/workflows/iso27001-controls.yml
name: ISO 27001 Control Validation
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
# A.8.4 - Access to source code
access-control:
runs-on: ubuntu-latest
steps:
- name: Verify branch protection
run: |
gh api repos/${{ github.repository }}/branches/main/protection \
--jq '.required_pull_request_reviews.required_approving_review_count'
- name: Check CODEOWNERS
run: |
if [[ ! -f .github/CODEOWNERS ]]; then
echo "CODEOWNERS file required for A.8.4 compliance"
exit 1
fi
# A.8.9 - Configuration management
configuration-management:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate infrastructure as code
run: |
terraform fmt -check -recursive
terraform validate
- name: Check for hardcoded secrets
uses: gitleaks/gitleaks-action@v2
# A.8.25 - Secure development lifecycle
secure-development:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: SAST scan
uses: semgrep/semgrep-action@v1
with:
config: p/owasp-top-ten
- name: Dependency vulnerability scan
run: npm audit --audit-level=high
- name: Container security scan
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
severity: 'CRITICAL,HIGH'
# A.8.16 - Monitoring activities
monitoring-validation:
runs-on: ubuntu-latest
steps:
- name: Verify logging configuration
run: |
# Check application logging config
grep -r "logging" src/ --include="*.ts" | grep -q "level"
- name: Validate audit trail
run: |
# Ensure audit events are captured
grep -r "audit" src/ --include="*.ts" | wc -lPhase 5: Documentation and Evidence
Documentation Requirements
ISMS Documentation Structure:
├── Mandatory Documents
│ ├── Scope of ISMS (4.3)
│ ├── Information Security Policy (5.2)
│ ├── Risk Assessment Process (6.1.2)
│ ├── Risk Treatment Process (6.1.3)
│ ├── Statement of Applicability (6.1.3d)
│ ├── Information Security Objectives (6.2)
│ ├── Evidence of Competence (7.2)
│ ├── Operational Planning Documents (8.1)
│ ├── Risk Assessment Results (8.2)
│ ├── Risk Treatment Results (8.3)
│ ├── Monitoring Results (9.1)
│ ├── Internal Audit Programme (9.2)
│ ├── Internal Audit Results (9.2)
│ ├── Management Review Results (9.3)
│ └── Nonconformities and Corrections (10.1)
│
└── Supporting Documents (based on SoA)
├── Asset Inventory
├── Access Control Procedures
├── Incident Response Plan
├── Business Continuity Plan
├── Supplier Security Requirements
└── Training RecordsEvidence Collection Automation
// evidence-collector.ts
interface EvidenceItem {
controlId: string;
evidenceType: 'document' | 'screenshot' | 'log' | 'report' | 'configuration';
description: string;
collectionDate: Date;
validUntil: Date;
location: string;
hash: string;
}
interface EvidencePackage {
auditPeriod: { start: Date; end: Date };
preparedBy: string;
preparedDate: Date;
evidence: EvidenceItem[];
}
const collectEvidence = async (controls: string[]): Promise<EvidencePackage> => {
const evidence: EvidenceItem[] = [];
for (const controlId of controls) {
switch (controlId) {
case 'A.8.2':
// Privileged access evidence
evidence.push(
await collectPAMReport(),
await collectAccessReviewRecords(),
await collectAdminAccountInventory()
);
break;
case 'A.8.9':
// Configuration management evidence
evidence.push(
await collectInfrastructureAsCode(),
await collectChangeRecords(),
await collectConfigurationBaselines()
);
break;
case 'A.8.16':
// Monitoring evidence
evidence.push(
await collectSIEMAlerts(),
await collectSecurityDashboards(),
await collectIncidentReports()
);
break;
}
}
return {
auditPeriod: {
start: new Date(Date.now() - 365 * 24 * 60 * 60 * 1000),
end: new Date()
},
preparedBy: 'Security Team',
preparedDate: new Date(),
evidence
};
};
const collectPAMReport = async (): Promise<EvidenceItem> => {
// Export from PAM solution
const report = await pamClient.generateAccessReport({
period: 'last_quarter',
includeSessionRecordings: true
});
return {
controlId: 'A.8.2',
evidenceType: 'report',
description: 'Privileged Access Management quarterly report',
collectionDate: new Date(),
validUntil: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000),
location: `/evidence/pam-report-${Date.now()}.pdf`,
hash: calculateHash(report)
};
};Phase 6: Internal Audit
Audit Programme
# internal-audit-programme.yml
audit_programme:
year: 2025
objective: Verify ISMS effectiveness and compliance
schedule:
Q1:
- scope: Access Control (A.5.15-A.5.18)
auditor: Internal Audit Team
date: 2025-02-15
- scope: Cryptography (A.8.24)
auditor: External Specialist
date: 2025-03-01
Q2:
- scope: Operations Security (A.8.1-A.8.14)
auditor: Internal Audit Team
date: 2025-05-15
- scope: Supplier Relationships (A.5.19-A.5.23)
auditor: Internal Audit Team
date: 2025-06-01
Q3:
- scope: HR Security (A.6.1-A.6.8)
auditor: Internal Audit Team
date: 2025-08-15
- scope: Physical Security (A.7.1-A.7.14)
auditor: External Specialist
date: 2025-09-01
Q4:
- scope: Full ISMS Review
auditor: Internal Audit Team + External
date: 2025-11-15
audit_criteria:
- ISO 27001:2022 requirements
- Organisation policies and procedures
- Regulatory requirements
- Contractual obligations
reporting:
findings_classification:
- major_nonconformity
- minor_nonconformity
- observation
- opportunity_for_improvement
report_distribution:
- Management representative
- Process owners
- CISO
- Senior managementAudit Checklist Example
// audit-checklist.ts
interface AuditQuestion {
id: string;
control: string;
question: string;
evidenceRequired: string[];
interviewees: string[];
}
const accessControlAudit: AuditQuestion[] = [
{
id: 'AC-001',
control: 'A.5.15',
question: 'How is the access control policy documented and communicated?',
evidenceRequired: [
'Access control policy document',
'Communication records',
'Training attendance'
],
interviewees: ['CISO', 'IT Manager', 'Sample of users']
},
{
id: 'AC-002',
control: 'A.5.16',
question: 'How are identities managed throughout their lifecycle?',
evidenceRequired: [
'Identity management procedures',
'Joiner/mover/leaver records',
'IAM system logs'
],
interviewees: ['HR Manager', 'IT Service Desk', 'IAM Administrator']
},
{
id: 'AC-003',
control: 'A.5.17',
question: 'How is authentication information managed securely?',
evidenceRequired: [
'Password policy',
'MFA implementation records',
'Authentication logs'
],
interviewees: ['Security Architect', 'System Administrators']
},
{
id: 'AC-004',
control: 'A.5.18',
question: 'How are access rights reviewed and removed when no longer needed?',
evidenceRequired: [
'Access review records',
'Recertification reports',
'Termination checklists'
],
interviewees: ['System Owners', 'HR Representative', 'IT Manager']
}
];Phase 7: Certification
Certification Timeline
Typical ISO 27001 Certification Journey:
Month 1-3: Gap Analysis & Planning
├── Conduct gap assessment
├── Define ISMS scope
├── Secure management commitment
└── Develop implementation plan
Month 4-8: Implementation
├── Develop policies and procedures
├── Implement controls
├── Conduct risk assessment
├── Deploy technical controls
└── Train staff
Month 9-10: Internal Audit & Improvement
├── Conduct internal audit
├── Address findings
├── Management review
└── Continual improvement
Month 11-12: Certification Audit
├── Stage 1: Documentation review
├── Address Stage 1 findings
├── Stage 2: Implementation audit
└── Certification decision
Ongoing: Surveillance & Recertification
├── Year 1: Surveillance audit
├── Year 2: Surveillance audit
└── Year 3: Recertification auditCertification Readiness Checklist
# certification-readiness.yml
stage_1_documentation:
mandatory:
- scope_statement: true
- information_security_policy: true
- risk_assessment_methodology: true
- statement_of_applicability: true
- risk_treatment_plan: true
- security_objectives: true
supporting:
- asset_inventory: true
- roles_responsibilities: true
- competency_matrix: true
- internal_audit_programme: true
stage_2_implementation:
leadership:
- management_commitment_demonstrated: true
- resources_allocated: true
- regular_reviews_conducted: true
risk_management:
- risk_assessment_completed: true
- risks_within_appetite: true
- treatment_plans_implemented: true
controls:
- all_soa_controls_addressed: true
- evidence_available: true
- effectiveness_measured: true
operations:
- processes_documented: true
- staff_trained: true
- incidents_managed: true
monitoring:
- metrics_defined: true
- internal_audit_completed: true
- management_review_completed: true
- improvements_tracked: trueMaintaining Certification
Continuous Improvement
// isms-improvement.ts
interface ImprovementItem {
id: string;
source: 'audit' | 'incident' | 'risk_review' | 'suggestion' | 'management_review';
description: string;
controlsAffected: string[];
priority: 'critical' | 'high' | 'medium' | 'low';
status: 'identified' | 'planned' | 'in_progress' | 'completed' | 'verified';
owner: string;
targetDate: Date;
completionDate?: Date;
effectivenessReview?: {
date: Date;
result: 'effective' | 'partially_effective' | 'ineffective';
evidence: string;
};
}
const trackImprovement = async (item: ImprovementItem): Promise<void> => {
// Log to improvement register
await improvementRegister.add(item);
// Create tasks if needed
if (item.priority === 'critical' || item.priority === 'high') {
await createUrgentTask(item);
await notifyStakeholders(item);
}
// Schedule effectiveness review
await scheduleReview({
itemId: item.id,
reviewDate: new Date(item.targetDate.getTime() + 30 * 24 * 60 * 60 * 1000),
reviewer: item.owner
});
};
const measureISMSEffectiveness = async (): Promise<EffectivenessReport> => {
const metrics = await collectMetrics();
return {
period: getCurrentPeriod(),
kpis: {
incidentReductionRate: calculateTrend(metrics.incidents),
riskPostureScore: calculateRiskScore(metrics.risks),
controlEffectiveness: calculateControlEffectiveness(metrics.controls),
auditFindingsTrend: calculateTrend(metrics.auditFindings),
trainingCompletion: metrics.training.completionRate,
policyCompliance: metrics.compliance.adherenceRate
},
recommendations: generateRecommendations(metrics)
};
};Key Takeaways
-
Start with scope: Define clear boundaries for your ISMS before implementation
-
Risk-based approach: Let risk assessment drive your control selection and priorities
-
Management commitment: Without leadership buy-in, certification efforts will struggle
-
Document everything: If it's not documented, it doesn't exist for auditors
-
Integrate with DevOps: Embed security controls into CI/CD pipelines for continuous compliance
-
Evidence automation: Automate evidence collection to reduce audit preparation burden
-
Continuous improvement: ISO 27001 is a journey, not a destination—embrace the PDCA cycle
-
Culture matters: Technical controls fail without security-aware people
ISO 27001 certification demonstrates your organisation's commitment to protecting information assets. More importantly, a well-implemented ISMS reduces real security risks and builds trust with customers and partners.