TechLead
Lesson 21 of 22
5 min read
Cybersecurity

DevSecOps

Integrate security into every phase of the software development lifecycle with DevSecOps practices and culture

What is DevSecOps?

DevSecOps is the practice of integrating security into every phase of the software development lifecycle (SDLC), rather than treating it as an afterthought or a separate phase. The traditional approach of "build it, then secure it" creates friction between development speed and security — DevSecOps eliminates this friction by making security a shared responsibility and automating security testing throughout the pipeline.

The core philosophy of DevSecOps is "shift left" — move security testing and practices as early as possible in the development process. A vulnerability found during code review costs a fraction of what it costs to fix after deployment. By embedding security into design, coding, testing, and deployment phases, you catch issues early and reduce the overall cost of security.

DevSecOps vs Traditional Security

Aspect Traditional DevSecOps
TimingSecurity tested at the endSecurity at every stage
ResponsibilitySecurity team onlyEveryone's responsibility
TestingManual, periodicAutomated, continuous
SpeedSlow, blocks releasesFast, integrated into workflow
Cost of fixesExpensive (found late)Cheap (found early)

Security in the Development Phase

// Pre-commit hooks for security
// .husky/pre-commit
/*
#!/bin/sh
# Run secret scanning before every commit
npx secretlint "**/*"

# Run security-focused linting
npx eslint --config .eslintrc.security.js --quiet .
*/

// ESLint security configuration
// .eslintrc.security.js
module.exports = {
  plugins: ["security", "no-unsanitized"],
  extends: ["plugin:security/recommended"],
  rules: {
    // Detect potential SQL injection
    "security/detect-object-injection": "warn",
    // Detect unsafe regex
    "security/detect-unsafe-regex": "error",
    // Detect eval() usage
    "security/detect-eval-with-expression": "error",
    // Detect non-literal filesystem calls
    "security/detect-non-literal-fs-filename": "warn",
    // Detect non-literal require
    "security/detect-non-literal-require": "warn",
    // Detect possible timing attacks
    "security/detect-possible-timing-attacks": "warn",
    // Detect innerHTML usage
    "no-unsanitized/method": "error",
    "no-unsanitized/property": "error",
  },
};

// Threat modeling as code
// Define security requirements for each feature
interface SecurityRequirements {
  feature: string;
  dataClassification: "public" | "internal" | "confidential" | "restricted";
  authRequired: boolean;
  rbacRoles: string[];
  inputValidation: string[];
  outputEncoding: string[];
  rateLimit: { requests: number; window: string };
  auditLogging: boolean;
  encryptionAtRest: boolean;
  encryptionInTransit: boolean;
}

const featureSecurityReqs: SecurityRequirements = {
  feature: "User Profile API",
  dataClassification: "confidential",
  authRequired: true,
  rbacRoles: ["user", "admin"],
  inputValidation: ["email", "name", "avatar_url"],
  outputEncoding: ["html_escape"],
  rateLimit: { requests: 100, window: "1m" },
  auditLogging: true,
  encryptionAtRest: true,
  encryptionInTransit: true,
};

Security Champions Program

A Security Champions program designates one or more developers on each team as the security point person. They receive additional security training, stay current on vulnerabilities, review security-sensitive code changes, and serve as the bridge between the security team and the development team. This scales security knowledge across the organization.

// Security review checklist (as code, for automation)
interface SecurityReview {
  prNumber: number;
  reviewer: string;
  checks: Record<string, boolean>;
  approved: boolean;
  notes: string[];
}

const securityChecklist = {
  authentication: "Does the change affect authentication? Are auth checks in place?",
  authorization: "Are authorization checks applied to all new endpoints?",
  inputValidation: "Is all user input validated and sanitized?",
  outputEncoding: "Is output properly encoded for the context (HTML, JSON, URL)?",
  sqlInjection: "Are all database queries parameterized?",
  secretsExposure: "Are any secrets, keys, or tokens hardcoded or logged?",
  errorHandling: "Do error responses avoid leaking internal details?",
  logging: "Are security-relevant events logged (login, access control)?",
  dependencies: "Were new dependencies reviewed for security?",
  dataExposure: "Does the API response include only necessary fields?",
};

// Automated PR labeling for security review
async function labelSecurityPRs(prFiles: string[]): Promise<string[]> {
  const securityPatterns = [
    { pattern: /auth|login|session|password|token/i, label: "security-review-required" },
    { pattern: /encrypt|decrypt|hash|crypto/i, label: "crypto-review" },
    { pattern: /.env|secret|credential|key/i, label: "secrets-check" },
    { pattern: /middleware|guard|interceptor/i, label: "access-control-review" },
    { pattern: /package.json|package-lock/i, label: "dependency-review" },
  ];

  const labels: Set<string> = new Set();

  for (const file of prFiles) {
    for (const { pattern, label } of securityPatterns) {
      if (pattern.test(file)) {
        labels.add(label);
      }
    }
  }

  return Array.from(labels);
}

Security Metrics and Dashboards

You cannot improve what you do not measure. Track security metrics to understand your security posture and identify trends. Key metrics include mean time to remediate vulnerabilities, number of open vulnerabilities by severity, percentage of deployments passing security gates, and security test coverage.

// Security metrics tracking
interface SecurityMetrics {
  timestamp: Date;
  vulnerabilities: {
    critical: number;
    high: number;
    medium: number;
    low: number;
  };
  mttr: { // Mean Time to Remediate (in hours)
    critical: number;
    high: number;
  };
  coverage: {
    sastEnabled: boolean;
    dastEnabled: boolean;
    scaEnabled: boolean;
    secretScanEnabled: boolean;
    containerScanEnabled: boolean;
  };
  compliance: {
    securityHeaderScore: number; // 0-100
    dependencyUpToDate: number; // percentage
    secretsInCode: number; // should be 0
    mfaAdoption: number; // percentage of users with MFA
  };
}

async function collectSecurityMetrics(): Promise<SecurityMetrics> {
  const [auditResult, headerScore, mfaStats] = await Promise.all([
    runSecurityAudit(),
    checkSecurityHeaders("https://myapp.com"),
    getMFAAdoptionStats(),
  ]);

  return {
    timestamp: new Date(),
    vulnerabilities: auditResult.vulnerabilities,
    mttr: await calculateMTTR(),
    coverage: {
      sastEnabled: true,
      dastEnabled: true,
      scaEnabled: true,
      secretScanEnabled: true,
      containerScanEnabled: true,
    },
    compliance: {
      securityHeaderScore: headerScore,
      dependencyUpToDate: await getDependencyFreshness(),
      secretsInCode: await countSecretsInCode(),
      mfaAdoption: mfaStats.percentage,
    },
  };
}

DevSecOps Implementation Roadmap

  1. Start with awareness: Train developers on OWASP Top 10 and secure coding practices.
  2. Add automated scanning: Integrate SAST, SCA, and secret scanning into CI/CD.
  3. Establish security champions: Designate security-focused developers on each team.
  4. Create security gates: Block deployments that fail security checks.
  5. Measure and improve: Track security metrics and set improvement targets.
  6. Threat model new features: Include security requirements in design documents.
  7. Continuous improvement: Regularly update tools, training, and processes.

Continue Learning