Security Testing & Next Steps

Security Checklists

2 min read

Checklists ensure nothing gets missed in the rush to deploy. This lesson provides comprehensive security checklists for development and pre-deployment verification.

Development Phase Checklist

┌─────────────────────────────────────────────────────────────┐
│                 Development Security Checklist               │
│                                                             │
│ ☐ Input Validation                                          │
│   ☐ Length limits enforced                                  │
│   ☐ Pattern detection for injection attempts                │
│   ☐ Content classification enabled                          │
│   ☐ Rate limiting implemented                               │
│                                                             │
│ ☐ Output Handling                                           │
│   ☐ HTML/XSS sanitization                                   │
│   ☐ PII detection and redaction                             │
│   ☐ Content moderation active                               │
│   ☐ Response length limits                                  │
│                                                             │
│ ☐ System Prompt Protection                                  │
│   ☐ No sensitive data in prompts                            │
│   ☐ Leak detection implemented                              │
│   ☐ Prompt boundaries clearly marked                        │
└─────────────────────────────────────────────────────────────┘

Automated Checklist Verification

from dataclasses import dataclass
from typing import List, Optional, Callable
from enum import Enum

class CheckStatus(Enum):
    PASS = "pass"
    FAIL = "fail"
    WARN = "warn"
    SKIP = "skip"

@dataclass
class CheckItem:
    id: str
    name: str
    description: str
    category: str
    check_function: Optional[Callable[[], bool]] = None
    severity: str = "high"  # high, medium, low

@dataclass
class CheckResult:
    item: CheckItem
    status: CheckStatus
    message: str

class SecurityChecklist:
    """Automated security checklist verification."""

    def __init__(self):
        self.items: List[CheckItem] = []
        self.results: List[CheckResult] = []

    def add_item(self, item: CheckItem):
        """Add a check item to the list."""
        self.items.append(item)

    def run_all_checks(self) -> List[CheckResult]:
        """Run all security checks."""
        self.results = []

        for item in self.items:
            result = self._run_check(item)
            self.results.append(result)

        return self.results

    def _run_check(self, item: CheckItem) -> CheckResult:
        """Run a single check."""
        if item.check_function is None:
            return CheckResult(
                item=item,
                status=CheckStatus.SKIP,
                message="No automated check available"
            )

        try:
            passed = item.check_function()
            return CheckResult(
                item=item,
                status=CheckStatus.PASS if passed else CheckStatus.FAIL,
                message="Check passed" if passed else "Check failed"
            )
        except Exception as e:
            return CheckResult(
                item=item,
                status=CheckStatus.FAIL,
                message=f"Error during check: {str(e)}"
            )

    def get_summary(self) -> dict:
        """Get check results summary."""
        return {
            "total": len(self.results),
            "passed": sum(1 for r in self.results if r.status == CheckStatus.PASS),
            "failed": sum(1 for r in self.results if r.status == CheckStatus.FAIL),
            "warnings": sum(1 for r in self.results if r.status == CheckStatus.WARN),
            "skipped": sum(1 for r in self.results if r.status == CheckStatus.SKIP),
        }

    def generate_report(self) -> str:
        """Generate markdown report."""
        lines = ["# Security Checklist Report\n"]

        # Group by category
        by_category = {}
        for result in self.results:
            cat = result.item.category
            if cat not in by_category:
                by_category[cat] = []
            by_category[cat].append(result)

        for category, results in by_category.items():
            lines.append(f"\n## {category}\n")
            for result in results:
                icon = {
                    CheckStatus.PASS: "✅",
                    CheckStatus.FAIL: "❌",
                    CheckStatus.WARN: "⚠️",
                    CheckStatus.SKIP: "⏭️",
                }[result.status]

                lines.append(f"- {icon} **{result.item.name}**")
                lines.append(f"  - {result.message}")

        # Summary
        summary = self.get_summary()
        lines.append(f"\n## Summary\n")
        lines.append(f"- Total: {summary['total']}")
        lines.append(f"- Passed: {summary['passed']}")
        lines.append(f"- Failed: {summary['failed']}")
        lines.append(f"- Warnings: {summary['warnings']}")

        return "\n".join(lines)

Pre-Deployment Checklist

def create_pre_deployment_checklist(config: dict) -> SecurityChecklist:
    """Create pre-deployment security checklist."""
    checklist = SecurityChecklist()

    # Input Validation Checks
    checklist.add_item(CheckItem(
        id="input-001",
        name="Input Length Limits",
        description="Maximum input length is enforced",
        category="Input Validation",
        check_function=lambda: config.get("max_input_length", 0) > 0,
        severity="high"
    ))

    checklist.add_item(CheckItem(
        id="input-002",
        name="Injection Pattern Detection",
        description="Patterns for detecting injection attempts are configured",
        category="Input Validation",
        check_function=lambda: len(config.get("injection_patterns", [])) > 0,
        severity="high"
    ))

    checklist.add_item(CheckItem(
        id="input-003",
        name="Rate Limiting",
        description="Rate limiting is enabled and configured",
        category="Input Validation",
        check_function=lambda: config.get("rate_limit_enabled", False),
        severity="high"
    ))

    # Output Security Checks
    checklist.add_item(CheckItem(
        id="output-001",
        name="XSS Sanitization",
        description="Output is sanitized for HTML contexts",
        category="Output Security",
        check_function=lambda: config.get("sanitize_html", False),
        severity="high"
    ))

    checklist.add_item(CheckItem(
        id="output-002",
        name="PII Redaction",
        description="PII patterns are detected and redacted",
        category="Output Security",
        check_function=lambda: config.get("pii_redaction", False),
        severity="high"
    ))

    checklist.add_item(CheckItem(
        id="output-003",
        name="Content Moderation",
        description="Content moderation is active",
        category="Output Security",
        check_function=lambda: config.get("content_moderation", False),
        severity="medium"
    ))

    # Guardrails Checks
    checklist.add_item(CheckItem(
        id="guard-001",
        name="NeMo Guardrails Configured",
        description="Guardrail configuration files exist and are valid",
        category="Guardrails",
        severity="high"
    ))

    checklist.add_item(CheckItem(
        id="guard-002",
        name="Safety Classifier Enabled",
        description="LLaMA Guard or similar classifier is active",
        category="Guardrails",
        check_function=lambda: config.get("safety_classifier", False),
        severity="high"
    ))

    # Monitoring Checks
    checklist.add_item(CheckItem(
        id="monitor-001",
        name="Logging Enabled",
        description="Security events are being logged",
        category="Monitoring",
        check_function=lambda: config.get("logging_enabled", False),
        severity="high"
    ))

    checklist.add_item(CheckItem(
        id="monitor-002",
        name="Alerting Configured",
        description="Alerts are configured for security events",
        category="Monitoring",
        check_function=lambda: config.get("alerting_enabled", False),
        severity="medium"
    ))

    # Authentication Checks
    checklist.add_item(CheckItem(
        id="auth-001",
        name="API Authentication",
        description="API endpoints require authentication",
        category="Authentication",
        check_function=lambda: config.get("require_auth", False),
        severity="high"
    ))

    checklist.add_item(CheckItem(
        id="auth-002",
        name="API Keys Secured",
        description="API keys are stored securely (not in code)",
        category="Authentication",
        severity="high"
    ))

    return checklist

# Usage
app_config = {
    "max_input_length": 4000,
    "injection_patterns": ["ignore.*instructions", "you are now"],
    "rate_limit_enabled": True,
    "sanitize_html": True,
    "pii_redaction": True,
    "content_moderation": True,
    "safety_classifier": True,
    "logging_enabled": True,
    "alerting_enabled": True,
    "require_auth": True,
}

checklist = create_pre_deployment_checklist(app_config)
results = checklist.run_all_checks()
report = checklist.generate_report()
print(report)

Quick Reference Checklist

CategoryCheckPriority
InputLength limits enforcedHigh
InputInjection patterns blockedHigh
InputRate limiting activeHigh
OutputHTML sanitizationHigh
OutputPII redaction enabledHigh
OutputContent moderationMedium
GuardrailsNeMo/LLaMA Guard activeHigh
GuardrailsTopic rails configuredMedium
MonitoringSecurity loggingHigh
MonitoringAlerting configuredMedium
AuthAPI authentication requiredHigh
AuthSecrets managementHigh
AgentLeast privilege permissionsHigh
AgentTool sandboxingHigh
AgentHuman approval for actionsMedium

Key Takeaway: Use checklists before every deployment. Automate checks where possible, but always review critical items manually. :::

Quick check: how does this lesson land for you?

Quiz

Module 6: Security Testing & Next Steps

Take Quiz
FREE WEEKLY NEWSLETTER

Stay on the Nerd Track

One email per week — courses, deep dives, tools, and AI experiments.

No spam. Unsubscribe anytime.