Secure Software Development Lifecycle: SSDLC Implementation Guide
A Secure Software Development Lifecycle (SSDLC) integrates security practices into every phase of development. This guide covers practical implementation of security activities from requirements through deployment.
SSDLC Framework Overview
Security Gate Implementation
from dataclasses import dataclass, field
from datetime import datetime
from typing import List, Dict, Optional, Callable
from enum import Enum
import json
class SDLCPhase(Enum):
REQUIREMENTS = "requirements"
DESIGN = "design"
IMPLEMENTATION = "implementation"
VERIFICATION = "verification"
RELEASE = "release"
MAINTENANCE = "maintenance"
class GateStatus(Enum):
PENDING = "pending"
PASSED = "passed"
FAILED = "failed"
WAIVED = "waived"
@dataclass
class SecurityRequirement:
id: str
phase: SDLCPhase
title: str
description: str
verification_method: str
priority: str # critical, high, medium, low
automated: bool = False
tool: Optional[str] = None
@dataclass
class GateResult:
gate_id: str
phase: SDLCPhase
status: GateStatus
requirements_checked: int
requirements_passed: int
requirements_failed: int
critical_failures: List[str]
findings: List[Dict]
evaluated_at: datetime
evaluated_by: str
waiver: Optional[Dict] = None
class SSDLCGateManager:
def __init__(self, project_id: str):
self.project_id = project_id
self.gates: Dict[SDLCPhase, List[SecurityRequirement]] = {}
self.results: Dict[str, GateResult] = {}
self.validators: Dict[str, Callable] = {}
self._initialize_default_gates()
self._register_validators()
def _initialize_default_gates(self):
"""Initialize default security gates for each phase."""
self.gates = {
SDLCPhase.REQUIREMENTS: [
SecurityRequirement(
id="REQ-001",
phase=SDLCPhase.REQUIREMENTS,
title="Security Requirements Documented",
description="All security requirements are documented and reviewed",
verification_method="document_review",
priority="critical"
),
SecurityRequirement(
id="REQ-002",
phase=SDLCPhase.REQUIREMENTS,
title="Data Classification Complete",
description="All data types are classified by sensitivity",
verification_method="document_review",
priority="critical"
),
SecurityRequirement(
id="REQ-003",
phase=SDLCPhase.REQUIREMENTS,
title="Compliance Requirements Identified",
description="Applicable compliance requirements documented",
verification_method="document_review",
priority="high"
),
SecurityRequirement(
id="REQ-004",
phase=SDLCPhase.REQUIREMENTS,
title="Risk Assessment Complete",
description="Initial risk assessment performed",
verification_method="document_review",
priority="high"
)
],
SDLCPhase.DESIGN: [
SecurityRequirement(
id="DES-001",
phase=SDLCPhase.DESIGN,
title="Threat Model Complete",
description="Threat model created and reviewed",
verification_method="document_review",
priority="critical"
),
SecurityRequirement(
id="DES-002",
phase=SDLCPhase.DESIGN,
title="Security Architecture Review",
description="Security architecture reviewed and approved",
verification_method="expert_review",
priority="critical"
),
SecurityRequirement(
id="DES-003",
phase=SDLCPhase.DESIGN,
title="Authentication Design",
description="Authentication mechanism designed per standards",
verification_method="design_review",
priority="critical"
),
SecurityRequirement(
id="DES-004",
phase=SDLCPhase.DESIGN,
title="Authorization Design",
description="Authorization model designed with least privilege",
verification_method="design_review",
priority="critical"
),
SecurityRequirement(
id="DES-005",
phase=SDLCPhase.DESIGN,
title="Cryptography Design",
description="Cryptographic controls designed per standards",
verification_method="expert_review",
priority="high"
)
],
SDLCPhase.IMPLEMENTATION: [
SecurityRequirement(
id="IMP-001",
phase=SDLCPhase.IMPLEMENTATION,
title="SAST Scan Passed",
description="Static analysis completed with no critical findings",
verification_method="automated_scan",
priority="critical",
automated=True,
tool="semgrep"
),
SecurityRequirement(
id="IMP-002",
phase=SDLCPhase.IMPLEMENTATION,
title="Dependency Scan Passed",
description="No critical vulnerabilities in dependencies",
verification_method="automated_scan",
priority="critical",
automated=True,
tool="snyk"
),
SecurityRequirement(
id="IMP-003",
phase=SDLCPhase.IMPLEMENTATION,
title="Secrets Scan Passed",
description="No secrets detected in codebase",
verification_method="automated_scan",
priority="critical",
automated=True,
tool="gitleaks"
),
SecurityRequirement(
id="IMP-004",
phase=SDLCPhase.IMPLEMENTATION,
title="Security Code Review",
description="Security-focused code review completed",
verification_method="peer_review",
priority="high"
),
SecurityRequirement(
id="IMP-005",
phase=SDLCPhase.IMPLEMENTATION,
title="Secure Coding Standards",
description="Code follows secure coding standards",
verification_method="automated_scan",
priority="high",
automated=True,
tool="eslint-security"
)
],
SDLCPhase.VERIFICATION: [
SecurityRequirement(
id="VER-001",
phase=SDLCPhase.VERIFICATION,
title="DAST Scan Passed",
description="Dynamic testing completed with no critical findings",
verification_method="automated_scan",
priority="critical",
automated=True,
tool="zap"
),
SecurityRequirement(
id="VER-002",
phase=SDLCPhase.VERIFICATION,
title="Penetration Testing",
description="Penetration testing completed for critical features",
verification_method="expert_testing",
priority="critical"
),
SecurityRequirement(
id="VER-003",
phase=SDLCPhase.VERIFICATION,
title="Security Unit Tests",
description="Security unit tests pass",
verification_method="automated_test",
priority="high",
automated=True,
tool="pytest"
),
SecurityRequirement(
id="VER-004",
phase=SDLCPhase.VERIFICATION,
title="API Security Testing",
description="API security testing completed",
verification_method="automated_scan",
priority="high",
automated=True,
tool="burp"
)
],
SDLCPhase.RELEASE: [
SecurityRequirement(
id="REL-001",
phase=SDLCPhase.RELEASE,
title="Security Sign-off",
description="Security team sign-off obtained",
verification_method="approval",
priority="critical"
),
SecurityRequirement(
id="REL-002",
phase=SDLCPhase.RELEASE,
title="All Critical Findings Resolved",
description="No open critical security findings",
verification_method="finding_review",
priority="critical"
),
SecurityRequirement(
id="REL-003",
phase=SDLCPhase.RELEASE,
title="Security Documentation",
description="Security documentation complete",
verification_method="document_review",
priority="high"
),
SecurityRequirement(
id="REL-004",
phase=SDLCPhase.RELEASE,
title="Incident Response Plan",
description="Incident response plan documented",
verification_method="document_review",
priority="high"
)
]
}
def _register_validators(self):
"""Register validation functions for automated checks."""
self.validators = {
"semgrep": self._validate_sast,
"snyk": self._validate_dependencies,
"gitleaks": self._validate_secrets,
"zap": self._validate_dast,
"eslint-security": self._validate_linting,
"pytest": self._validate_tests
}
def evaluate_gate(self,
phase: SDLCPhase,
evaluator: str,
scan_results: Dict = None,
manual_checks: Dict = None) -> GateResult:
"""Evaluate security gate for a phase."""
requirements = self.gates.get(phase, [])
findings = []
passed = 0
failed = 0
critical_failures = []
for req in requirements:
result = self._evaluate_requirement(req, scan_results, manual_checks)
findings.append({
"requirement_id": req.id,
"title": req.title,
"status": result["status"],
"details": result.get("details", ""),
"priority": req.priority
})
if result["status"] == "passed":
passed += 1
else:
failed += 1
if req.priority == "critical":
critical_failures.append(req.id)
# Determine overall gate status
status = GateStatus.PASSED if failed == 0 else GateStatus.FAILED
if failed > 0 and len(critical_failures) == 0:
# Only non-critical failures - can potentially proceed with waiver
status = GateStatus.FAILED
gate_result = GateResult(
gate_id=f"{self.project_id}_{phase.value}_{datetime.utcnow().strftime('%Y%m%d%H%M%S')}",
phase=phase,
status=status,
requirements_checked=len(requirements),
requirements_passed=passed,
requirements_failed=failed,
critical_failures=critical_failures,
findings=findings,
evaluated_at=datetime.utcnow(),
evaluated_by=evaluator
)
self.results[gate_result.gate_id] = gate_result
return gate_result
def _evaluate_requirement(self,
req: SecurityRequirement,
scan_results: Dict,
manual_checks: Dict) -> Dict:
"""Evaluate a single requirement."""
if req.automated and req.tool:
# Use automated validation
validator = self.validators.get(req.tool)
if validator and scan_results:
tool_results = scan_results.get(req.tool, {})
return validator(tool_results, req)
# Manual check
if manual_checks and req.id in manual_checks:
check = manual_checks[req.id]
return {
"status": "passed" if check.get("passed") else "failed",
"details": check.get("notes", "")
}
return {"status": "pending", "details": "Not evaluated"}
def _validate_sast(self, results: Dict, req: SecurityRequirement) -> Dict:
"""Validate SAST scan results."""
critical_count = results.get("critical", 0)
high_count = results.get("high", 0)
if critical_count > 0:
return {
"status": "failed",
"details": f"Found {critical_count} critical issues"
}
return {"status": "passed", "details": f"No critical issues, {high_count} high"}
def _validate_dependencies(self, results: Dict, req: SecurityRequirement) -> Dict:
"""Validate dependency scan results."""
critical_vulns = results.get("vulnerabilities", {}).get("critical", 0)
if critical_vulns > 0:
return {
"status": "failed",
"details": f"Found {critical_vulns} critical vulnerabilities"
}
return {"status": "passed", "details": "No critical vulnerabilities"}
def _validate_secrets(self, results: Dict, req: SecurityRequirement) -> Dict:
"""Validate secrets scan results."""
secrets_found = results.get("secrets_count", 0)
if secrets_found > 0:
return {
"status": "failed",
"details": f"Found {secrets_found} potential secrets"
}
return {"status": "passed", "details": "No secrets detected"}
def _validate_dast(self, results: Dict, req: SecurityRequirement) -> Dict:
"""Validate DAST scan results."""
high_risks = results.get("high", 0)
critical_risks = results.get("critical", 0)
if critical_risks > 0 or high_risks > 0:
return {
"status": "failed",
"details": f"Critical: {critical_risks}, High: {high_risks}"
}
return {"status": "passed", "details": "No high/critical risks"}
def _validate_linting(self, results: Dict, req: SecurityRequirement) -> Dict:
"""Validate security linting results."""
errors = results.get("errors", 0)
if errors > 0:
return {
"status": "failed",
"details": f"Found {errors} security lint errors"
}
return {"status": "passed", "details": "All security lint rules pass"}
def _validate_tests(self, results: Dict, req: SecurityRequirement) -> Dict:
"""Validate security test results."""
failed_tests = results.get("failed", 0)
passed_tests = results.get("passed", 0)
if failed_tests > 0:
return {
"status": "failed",
"details": f"{failed_tests} security tests failed"
}
return {"status": "passed", "details": f"All {passed_tests} security tests pass"}
def request_waiver(self,
gate_id: str,
requirement_ids: List[str],
justification: str,
requestor: str,
risk_acceptance: str) -> Dict:
"""Request waiver for failed requirements."""
gate_result = self.results.get(gate_id)
if not gate_result:
return {"success": False, "error": "Gate not found"}
# Check if requirements are waivable (non-critical)
non_waivable = [r for r in requirement_ids if r in gate_result.critical_failures]
if non_waivable:
return {
"success": False,
"error": f"Cannot waive critical requirements: {non_waivable}"
}
waiver = {
"waiver_id": f"waiver_{gate_id}_{datetime.utcnow().strftime('%Y%m%d%H%M%S')}",
"gate_id": gate_id,
"requirement_ids": requirement_ids,
"justification": justification,
"risk_acceptance": risk_acceptance,
"requested_by": requestor,
"requested_at": datetime.utcnow().isoformat(),
"status": "pending_approval",
"approvals": []
}
return {"success": True, "waiver": waiver}
def generate_compliance_report(self) -> Dict:
"""Generate SSDLC compliance report."""
report = {
"project_id": self.project_id,
"generated_at": datetime.utcnow().isoformat(),
"phases": {},
"summary": {
"total_requirements": 0,
"passed": 0,
"failed": 0,
"waived": 0,
"pending": 0
}
}
for phase in SDLCPhase:
phase_results = [r for r in self.results.values() if r.phase == phase]
if phase_results:
latest = max(phase_results, key=lambda x: x.evaluated_at)
report["phases"][phase.value] = {
"status": latest.status.value,
"evaluated_at": latest.evaluated_at.isoformat(),
"findings": latest.findings
}
report["summary"]["total_requirements"] += latest.requirements_checked
report["summary"]["passed"] += latest.requirements_passed
report["summary"]["failed"] += latest.requirements_failed
return reportSecurity Requirements Engineering
class SecurityRequirementsManager:
def __init__(self):
self.requirements: Dict[str, Dict] = {}
self.templates = self._load_requirement_templates()
def _load_requirement_templates(self) -> Dict:
"""Load security requirement templates by category."""
return {
"authentication": [
{
"id_prefix": "AUTH",
"title": "Multi-Factor Authentication",
"description": "System shall support multi-factor authentication for privileged users",
"category": "authentication",
"priority": "critical",
"compliance": ["SOC2", "NIST"]
},
{
"id_prefix": "AUTH",
"title": "Password Policy",
"description": "System shall enforce strong password requirements",
"category": "authentication",
"priority": "high",
"compliance": ["SOC2", "PCI-DSS"]
},
{
"id_prefix": "AUTH",
"title": "Session Management",
"description": "System shall implement secure session management with timeouts",
"category": "authentication",
"priority": "high",
"compliance": ["OWASP"]
},
{
"id_prefix": "AUTH",
"title": "Account Lockout",
"description": "System shall lock accounts after failed authentication attempts",
"category": "authentication",
"priority": "medium",
"compliance": ["NIST"]
}
],
"authorization": [
{
"id_prefix": "AUTHZ",
"title": "Role-Based Access Control",
"description": "System shall implement RBAC with least privilege principle",
"category": "authorization",
"priority": "critical",
"compliance": ["SOC2", "NIST"]
},
{
"id_prefix": "AUTHZ",
"title": "Resource Authorization",
"description": "System shall verify authorization for every resource access",
"category": "authorization",
"priority": "critical",
"compliance": ["OWASP"]
}
],
"data_protection": [
{
"id_prefix": "DATA",
"title": "Encryption at Rest",
"description": "System shall encrypt sensitive data at rest using AES-256",
"category": "data_protection",
"priority": "critical",
"compliance": ["SOC2", "GDPR", "PCI-DSS"]
},
{
"id_prefix": "DATA",
"title": "Encryption in Transit",
"description": "System shall encrypt all data in transit using TLS 1.2+",
"category": "data_protection",
"priority": "critical",
"compliance": ["SOC2", "PCI-DSS"]
},
{
"id_prefix": "DATA",
"title": "Data Classification",
"description": "System shall classify and label data by sensitivity level",
"category": "data_protection",
"priority": "high",
"compliance": ["GDPR"]
},
{
"id_prefix": "DATA",
"title": "Data Retention",
"description": "System shall enforce data retention policies",
"category": "data_protection",
"priority": "high",
"compliance": ["GDPR", "CCPA"]
}
],
"logging": [
{
"id_prefix": "LOG",
"title": "Security Event Logging",
"description": "System shall log all security-relevant events",
"category": "logging",
"priority": "critical",
"compliance": ["SOC2", "PCI-DSS"]
},
{
"id_prefix": "LOG",
"title": "Audit Trail",
"description": "System shall maintain tamper-evident audit trails",
"category": "logging",
"priority": "high",
"compliance": ["SOX", "HIPAA"]
},
{
"id_prefix": "LOG",
"title": "Log Protection",
"description": "System shall protect logs from unauthorized modification",
"category": "logging",
"priority": "high",
"compliance": ["SOC2"]
}
],
"input_validation": [
{
"id_prefix": "INPUT",
"title": "Input Validation",
"description": "System shall validate all user input against expected formats",
"category": "input_validation",
"priority": "critical",
"compliance": ["OWASP"]
},
{
"id_prefix": "INPUT",
"title": "Output Encoding",
"description": "System shall encode output to prevent injection attacks",
"category": "input_validation",
"priority": "critical",
"compliance": ["OWASP"]
}
]
}
def generate_requirements(self,
data_classification: str,
compliance_frameworks: List[str],
features: List[str]) -> List[Dict]:
"""Generate security requirements based on context."""
requirements = []
req_counter = {}
# Determine applicable categories
categories = self._determine_categories(features)
for category in categories:
templates = self.templates.get(category, [])
for template in templates:
# Check if requirement is applicable based on compliance
applicable_compliance = set(template.get("compliance", [])) & set(compliance_frameworks)
if not applicable_compliance and compliance_frameworks:
continue
# Adjust priority based on data classification
priority = self._adjust_priority(
template["priority"],
data_classification
)
# Generate unique ID
prefix = template["id_prefix"]
req_counter[prefix] = req_counter.get(prefix, 0) + 1
req_id = f"{prefix}-{req_counter[prefix]:03d}"
requirement = {
"id": req_id,
"title": template["title"],
"description": template["description"],
"category": category,
"priority": priority,
"compliance_mapping": list(applicable_compliance),
"verification_criteria": self._generate_verification_criteria(template),
"status": "draft"
}
requirements.append(requirement)
return requirements
def _determine_categories(self, features: List[str]) -> List[str]:
"""Determine applicable security categories based on features."""
categories = set()
feature_mapping = {
"user_login": ["authentication", "logging"],
"api": ["authentication", "authorization", "input_validation", "logging"],
"database": ["data_protection", "authorization", "logging"],
"file_upload": ["input_validation", "data_protection"],
"payment": ["data_protection", "logging", "authorization"],
"user_data": ["data_protection", "logging"]
}
for feature in features:
feature_lower = feature.lower()
for key, cats in feature_mapping.items():
if key in feature_lower:
categories.update(cats)
# Always include basic categories
categories.update(["logging", "input_validation"])
return list(categories)
def _adjust_priority(self, base_priority: str, data_classification: str) -> str:
"""Adjust priority based on data classification."""
classification_boost = {
"restricted": 2,
"confidential": 1,
"internal": 0,
"public": -1
}
priority_levels = ["low", "medium", "high", "critical"]
current_index = priority_levels.index(base_priority)
boost = classification_boost.get(data_classification, 0)
new_index = min(len(priority_levels) - 1, max(0, current_index + boost))
return priority_levels[new_index]
def _generate_verification_criteria(self, template: Dict) -> List[str]:
"""Generate verification criteria for a requirement."""
criteria = []
# Add standard verification criteria based on category
category_criteria = {
"authentication": [
"Authentication mechanism tested with valid and invalid credentials",
"Session tokens are cryptographically random",
"Password hashing uses approved algorithm (bcrypt, Argon2)"
],
"authorization": [
"Access control tested for horizontal and vertical privilege escalation",
"All API endpoints enforce authorization checks",
"Negative testing performed for unauthorized access"
],
"data_protection": [
"Encryption algorithms verified against standards",
"Key management procedures documented and tested",
"Data at rest and in transit encryption verified"
],
"logging": [
"Security events are logged with required fields",
"Log tampering protection verified",
"Log retention meets compliance requirements"
],
"input_validation": [
"Input validation tested with malicious payloads",
"SQL injection testing completed",
"XSS testing completed"
]
}
criteria = category_criteria.get(template.get("category"), [])
return criteriaSecure Code Review
class SecureCodeReviewChecklist:
def __init__(self):
self.checklists = self._initialize_checklists()
def _initialize_checklists(self) -> Dict:
"""Initialize code review checklists by language/framework."""
return {
"general": [
{
"category": "Input Validation",
"items": [
"All user input is validated before use",
"Input validation uses allowlists rather than blocklists",
"File uploads validate file type, size, and content",
"URL redirects validate against allowed destinations"
]
},
{
"category": "Authentication",
"items": [
"Passwords are hashed using strong algorithms (bcrypt, Argon2)",
"Password reset tokens are cryptographically random",
"Session tokens are invalidated on logout",
"Authentication failures do not leak user existence"
]
},
{
"category": "Authorization",
"items": [
"Authorization checks performed on every request",
"Direct object references are validated",
"Function-level access control implemented",
"Sensitive actions require re-authentication"
]
},
{
"category": "Data Protection",
"items": [
"Sensitive data encrypted at rest",
"PII not logged or masked in logs",
"Cryptographic keys not hardcoded",
"Secure random number generation used"
]
},
{
"category": "Error Handling",
"items": [
"Exceptions do not leak sensitive information",
"Generic error messages returned to users",
"Errors are logged with sufficient context",
"Application fails securely (fail-closed)"
]
}
],
"python": [
{
"category": "Python-Specific",
"items": [
"No use of eval(), exec() with user input",
"Pickle used only with trusted data",
"Template injection prevented (Jinja2 autoescape)",
"SQL queries use parameterized statements",
"subprocess calls avoid shell=True with user input"
]
}
],
"javascript": [
{
"category": "JavaScript-Specific",
"items": [
"No use of eval() or Function() with user input",
"DOM manipulation uses safe methods",
"Content Security Policy implemented",
"Third-party libraries from trusted sources",
"No sensitive data in client-side storage"
]
}
],
"api": [
{
"category": "API Security",
"items": [
"Rate limiting implemented",
"API versioning strategy in place",
"CORS policy properly configured",
"Request size limits enforced",
"API keys/tokens not in URLs"
]
}
]
}
def get_checklist(self, languages: List[str], includes_api: bool = False) -> Dict:
"""Get combined checklist for review."""
combined = {
"categories": [],
"total_items": 0
}
# Always include general checklist
combined["categories"].extend(self.checklists["general"])
# Add language-specific checklists
for lang in languages:
if lang.lower() in self.checklists:
combined["categories"].extend(self.checklists[lang.lower()])
# Add API checklist if applicable
if includes_api:
combined["categories"].extend(self.checklists["api"])
# Calculate total
for cat in combined["categories"]:
combined["total_items"] += len(cat["items"])
return combined
def create_review_form(self, checklist: Dict, reviewer: str, commit_hash: str) -> Dict:
"""Create a code review form."""
form = {
"review_id": f"review_{commit_hash[:8]}_{datetime.utcnow().strftime('%Y%m%d')}",
"reviewer": reviewer,
"commit_hash": commit_hash,
"created_at": datetime.utcnow().isoformat(),
"status": "in_progress",
"categories": []
}
for category in checklist["categories"]:
cat_form = {
"name": category["category"],
"items": []
}
for item in category["items"]:
cat_form["items"].append({
"description": item,
"status": "not_checked", # not_checked, pass, fail, na
"notes": "",
"finding_id": None
})
form["categories"].append(cat_form)
return formCI/CD Security Integration
# .github/workflows/ssdlc-pipeline.yml
name: SSDLC Security Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
SECURITY_GATE_THRESHOLD: high
jobs:
implementation-gate:
name: Implementation Security Gate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: SAST Scan (Semgrep)
id: sast
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/security-audit
p/secrets
p/owasp-top-ten
- name: Dependency Scan (Snyk)
id: deps
uses: snyk/actions/python@master
continue-on-error: true
with:
args: --severity-threshold=high
- name: Secrets Scan (Gitleaks)
id: secrets
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Security Linting
id: lint
run: |
npm install -g eslint eslint-plugin-security
eslint --plugin security --ext .js,.ts src/ || true
- name: Aggregate Results
run: |
echo "SAST: ${{ steps.sast.outcome }}"
echo "Dependencies: ${{ steps.deps.outcome }}"
echo "Secrets: ${{ steps.secrets.outcome }}"
- name: Evaluate Implementation Gate
uses: ./.github/actions/security-gate
with:
phase: implementation
sast_results: ${{ steps.sast.outputs.results }}
dependency_results: ${{ steps.deps.outputs.results }}
secrets_results: ${{ steps.secrets.outputs.results }}
verification-gate:
name: Verification Security Gate
needs: implementation-gate
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Start Application
run: docker-compose up -d
- name: DAST Scan (OWASP ZAP)
uses: zaproxy/action-full-scan@v0.9.0
with:
target: 'http://localhost:8080'
rules_file_name: 'zap-rules.tsv'
- name: API Security Tests
run: |
npm run test:security:api
- name: Security Unit Tests
run: |
npm run test:security:unit
- name: Evaluate Verification Gate
uses: ./.github/actions/security-gate
with:
phase: verification
dast_results: ${{ steps.dast.outputs.results }}
test_results: ${{ steps.tests.outputs.results }}Best Practices
SSDLC Implementation
- Start early: Integrate security from requirements phase
- Automate gates: Use CI/CD for automated security checks
- Define clear criteria: Establish measurable pass/fail criteria
- Track metrics: Monitor security gate effectiveness over time
Security Gates
- Critical findings should always block progression
- Implement waiver process for non-critical findings
- Require documented justification and risk acceptance
- Regular review of waiver decisions
Continuous Improvement
- Conduct post-mortems on security incidents
- Update requirements based on emerging threats
- Refine automated tools based on false positive rates
- Train developers on secure coding practices
Implementing SSDLC ensures security is built into software from the beginning rather than bolted on at the end.