Skip to content
Back to skills

Container Security

DSecurity

Expert in container and Kubernetes security - scanning, runtime protection, and compliance. Use when performing security analysis, auditing, or hardening with container security.

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 8, 2026
securitypythongoshellbashreactdockerkubernetesgitapici/cd

Works with

  • api

Security analysis

D51/100
  • criticalAccesses sensitive system or user directories
  • criticalAccesses sensitive system or user directories
  • highPerforms destructive filesystem operations
  • criticalReads or references SSH private keys
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill container-security --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Container Security?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Container Security
[![Security: D — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-container-security/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-container-security)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: container-security
description: Expert in container and Kubernetes security - scanning, runtime protection, and compliance. Use when performing security analysis, auditing, or hardening with container security.
license: CC-BY-NC-SA-4.0
metadata:
  risk: unknown
  source: community
  kind: mode
  category: security
  tags: [container-security, kubernetes, docker, trivy, falco, opa, runtime-security]
---

# Container Security Expert Mode

You are an expert in container security, covering image scanning, runtime protection, Kubernetes security, and compliance for containerized workloads.

## Core Expertise

### Security Layers

- **Image Scanning**: Vulnerability detection in images
- **Registry Security**: Secure image storage
- **Runtime Security**: Container behavior monitoring
- **Network Security**: Pod-to-pod communication
- **Secrets Management**: Secure credential handling

### Key Tools

- **Trivy**: Vulnerability scanner
- **Falco**: Runtime security
- **OPA/Gatekeeper**: Policy enforcement
- **Kyverno**: Kubernetes native policies
- **Cosign**: Image signing

## Code Standards

```yaml
# Trivy Image Scanning in CI/CD
# .github/workflows/security-scan.yml
name: Container Security Scan

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build image
        run: docker build -t myapp:${{ github.sha }} .

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: "myapp:${{ github.sha }}"
          format: "sarif"
          output: "trivy-results.sarif"
          severity: "CRITICAL,HIGH"
          exit-code: "1"
          ignore-unfixed: true

      - name: Upload Trivy scan results
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: "trivy-results.sarif"

      - name: Run Trivy config scanner
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: "config"
          scan-ref: "."
          format: "table"
          exit-code: "1"
          severity: "CRITICAL,HIGH"

      - name: Scan for secrets
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: "fs"
          scan-ref: "."
          scanners: "secret"
          format: "table"
          exit-code: "1"
```

```dockerfile
# Secure Dockerfile Best Practices
# Use specific version, not latest
FROM python:3.12-slim-bookworm AS builder

# Create non-root user early
RUN groupadd -r appgroup && useradd -r -g appgroup appuser

# Set working directory
WORKDIR /app

# Copy only requirements first (layer caching)
COPY requirements.txt .

# Install dependencies with no cache
RUN pip install --no-cache-dir --user -r requirements.txt

# --- Production Stage ---
FROM python:3.12-slim-bookworm

# Security labels
LABEL org.opencontainers.image.source="https://github.com/org/repo"
LABEL org.opencontainers.image.description="Secure application image"

# Install security updates
RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y --no-install-recommends \
        ca-certificates \
        dumb-init && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Create non-root user
RUN groupadd -r appgroup && useradd -r -g appgroup appuser

# Copy dependencies from builder
COPY --from=builder /root/.local /home/appuser/.local
ENV PATH=/home/appuser/.local/bin:$PATH

# Set working directory
WORKDIR /app

# Copy application code with correct ownership
COPY --chown=appuser:appgroup . .

# Security configurations
# Drop all capabilities
# Read-only root filesystem
# No new privileges
USER appuser

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8080/health')"

# Use dumb-init as PID 1
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["python", "app.py"]
```

```yaml
# Kubernetes Pod Security Standards
# Restricted Pod Security Policy
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
  namespace: production
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 1000
    seccompProfile:
      type: RuntimeDefault

  containers:
    - name: app
      image: myapp:v1.0.0@sha256:abc123... # Use digest
      imagePullPolicy: Always

      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        runAsNonRoot: true
        runAsUser: 1000
        capabilities:
          drop:
            - ALL
        seccompProfile:
          type: RuntimeDefault

      resources:
        limits:
          cpu: "500m"
          memory: "512Mi"
          ephemeral-storage: "1Gi"
        requests:
          cpu: "100m"
          memory: "128Mi"

      ports:
        - containerPort: 8080
          protocol: TCP

      volumeMounts:
        - name: tmp
          mountPath: /tmp
        - name: cache
          mountPath: /app/cache

      livenessProbe:
        httpGet:
          path: /health
          port: 8080
        initialDelaySeconds: 10
        periodSeconds: 10

      readinessProbe:
        httpGet:
          path: /ready
          port: 8080
        initialDelaySeconds: 5
        periodSeconds: 5

  volumes:
    - name: tmp
      emptyDir:
        sizeLimit: 100Mi
    - name: cache
      emptyDir:
        sizeLimit: 500Mi

  automountServiceAccountToken: false

  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchLabels:
                app: myapp
            topologyKey: kubernetes.io/hostname
```

```yaml
# Kyverno Security Policies
# Require non-root containers
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-run-as-non-root
spec:
  validationFailureAction: Enforce
  background: true
  rules:
    - name: check-containers
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Containers must run as non-root"
        pattern:
          spec:
            containers:
              - securityContext:
                  runAsNonRoot: true
                  allowPrivilegeEscalation: false
---
# Require resource limits
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-resource-limits
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-limits
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Resource limits are required"
        pattern:
          spec:
            containers:
              - resources:
                  limits:
                    memory: "?*"
                    cpu: "?*"
---
# Require image from approved registries
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: restrict-image-registries
spec:
  validationFailureAction: Enforce
  rules:
    - name: validate-registries
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Images must be from approved registries"
        pattern:
          spec:
            containers:
              - image: "gcr.io/myproject/* | docker.io/myorg/*"
---
# Require image signatures
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signatures
spec:
  validationFailureAction: Enforce
  rules:
    - name: verify-signature
      match:
        any:
          - resources:
              kinds:
                - Pod
      verifyImages:
        - imageReferences:
            - "gcr.io/myproject/*"
          attestors:
            - entries:
                - keys:
                    publicKeys: |-
                      -----BEGIN PUBLIC KEY-----
                      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
                      -----END PUBLIC KEY-----
```

```yaml
# Falco Runtime Security Rules
# /etc/falco/rules.d/custom-rules.yaml
- rule: Detect Crypto Mining
  desc: Detect crypto mining processes
  condition: >
    spawned_process and
    (proc.name in (crypto_mining_binaries) or
     proc.cmdline contains "stratum+tcp" or
     proc.cmdline contains "xmr" or
     proc.cmdline contains "monero")
  output: >
    Crypto mining detected (user=%user.name container=%container.name
    image=%container.image.repository command=%proc.cmdline)
  priority: CRITICAL
  tags: [crypto, mining]

- rule: Detect Shell in Container
  desc: Detect shell spawned in container
  condition: >
    container and
    spawned_process and
    shell_procs and
    not shell_in_container_allowed
  output: >
    Shell spawned in container (user=%user.name container=%container.name
    image=%container.image.repository shell=%proc.name parent=%proc.pname)
  priority: WARNING
  tags: [shell, container]

- rule: Sensitive File Access
  desc: Detect access to sensitive files
  condition: >
    open_read and
    (fd.name startswith /etc/shadow or
     fd.name startswith /etc/passwd or
     fd.name startswith /root/.ssh or
     fd.name contains id_rsa)
  output: >
    Sensitive file accessed (user=%user.name file=%fd.name
    container=%container.name image=%container.image.repository)
  priority: WARNING
  tags: [filesystem, sensitive]

- rule: Container Escape Attempt
  desc: Detect container escape attempts
  condition: >
    container and
    (evt.type = ptrace or
     proc.name = nsenter or
     proc.cmdline contains "docker.sock" or
     fd.name = /proc/1/ns/*)
  output: >
    Container escape attempt detected (user=%user.name
    container=%container.name command=%proc.cmdline)
  priority: CRITICAL
  tags: [escape, container]

- rule: Unauthorized Network Connection
  desc: Detect outbound connections to suspicious IPs
  condition: >
    container and
    outbound and
    not (fd.sip in (allowed_outbound_ips))
  output: >
    Unauthorized outbound connection (container=%container.name
    connection=%fd.name image=%container.image.repository)
  priority: WARNING
  tags: [network, outbound]

- list: crypto_mining_binaries
  items: [xmrig, minerd, cpuminer, cgminer, bfgminer]

- list: shell_procs
  items: [bash, sh, zsh, ksh, csh, dash]

- macro: shell_in_container_allowed
  condition: >
    (container.image.repository = "debug-container" or
     k8s.ns.name = "debug")
```

```python
# Container Security Scanner
import subprocess
import json
from dataclasses import dataclass
from typing import List, Dict, Optional
from enum import Enum
import logging

logger = logging.getLogger(__name__)


class Severity(str, Enum):
    CRITICAL = "CRITICAL"
    HIGH = "HIGH"
    MEDIUM = "MEDIUM"
    LOW = "LOW"
    UNKNOWN = "UNKNOWN"


@dataclass
class Vulnerability:
    id: str
    package: str
    version: str
    fixed_version: Optional[str]
    severity: Severity
    title: str
    description: str


@dataclass
class ScanResult:
    image: str
    vulnerabilities: List[Vulnerability]
    passed: bool
    summary: Dict[str, int]


class ContainerSecurityScanner:
    """Container security scanning using Trivy."""

    def __init__(self, severity_threshold: Severity = Severity.HIGH):
        self.severity_threshold = severity_threshold
        self.failing_severities = self._get_failing_severities()

    def _get_failing_severities(self) -> List[str]:
        """Get severities that should fail the scan."""
        severities = [Severity.CRITICAL, Severity.HIGH, Severity.MEDIUM, Severity.LOW]
        threshold_index = severities.index(self.severity_threshold)
        return [s.value for s in severities[:threshold_index + 1]]

    def scan_image(self, image: str) -> ScanResult:
        """Scan container image for vulnerabilities."""
        cmd = [
            "trivy", "image",
            "--format", "json",
            "--severity", ",".join(self.failing_severities),
            image,
        ]

        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
        )

        scan_data = json.loads(result.stdout)
        vulnerabilities = self._parse_vulnerabilities(scan_data)
        summary = self._create_summary(vulnerabilities)

        passed = not any(
            v.severity.value in self.failing_severities
            for v in vulnerabilities
        )

        return ScanResult(
            image=image,
            vulnerabilities=vulnerabilities,
            passed=passed,
            summary=summary,
        )

    def scan_filesystem(self, path: str) -> ScanResult:
        """Scan filesystem for vulnerabilities and misconfigs."""
        cmd = [
            "trivy", "fs",
            "--format", "json",
            "--scanners", "vuln,secret,config",
            path,
        ]

        result = subprocess.run(cmd, capture_output=True, text=True)
        scan_data = json.loads(result.stdout)

        return self._parse_fs_scan(scan_data)

    def _parse_vulnerabilities(self, data: Dict) -> List[Vulnerability]:
        """Parse Trivy JSON output."""
        vulnerabilities = []

        for result in data.get("Results", []):
            for vuln in result.get("Vulnerabilities", []):
                vulnerabilities.append(Vulnerability(
                    id=vuln["VulnerabilityID"],
                    package=vuln["PkgName"],
                    version=vuln["InstalledVersion"],
                    fixed_version=vuln.get("FixedVersion"),
                    severity=Severity(vuln["Severity"]),
                    title=vuln.get("Title", ""),
                    description=vuln.get("Description", ""),
                ))

        return vulnerabilities

    def _create_summary(self, vulns: List[Vulnerability]) -> Dict[str, int]:
        """Create vulnerability summary by severity."""
        summary = {s.value: 0 for s in Severity}
        for vuln in vulns:
            summary[vuln.severity.value] += 1
        return summary

    def generate_report(self, result: ScanResult) -> str:
        """Generate human-readable report."""
        lines = [
            f"Security Scan Report: {result.image}",
            "=" * 50,
            f"Status: {'PASSED' if result.passed else 'FAILED'}",
            "",
            "Summary:",
        ]

        for severity, count in result.summary.items():
            if count > 0:
                lines.append(f"  {severity}: {count}")

        if not result.passed:
            lines.extend(["", "Critical/High Vulnerabilities:"])
            for vuln in result.vulnerabilities:
                if vuln.severity in [Severity.CRITICAL, Severity.HIGH]:
                    lines.append(
                        f"  - {vuln.id}: {vuln.package} ({vuln.version})"
                        f" -> {vuln.fixed_version or 'No fix'}"
                    )

        return "\n".join(lines)
```

## Best Practices

### Image Security

- Use minimal base images (distroless, Alpine)
- Scan images in CI/CD pipeline
- Sign images with Cosign/Notary
- Use image digests, not tags

### Runtime Security

- Deploy Falco for behavior monitoring
- Use read-only root filesystems
- Drop all capabilities
- Enable seccomp profiles

### Kubernetes Security

- Enforce Pod Security Standards
- Use Network Policies
- Enable audit logging
- Implement RBAC properly

### Compliance

- Run CIS benchmarks regularly
- Document security controls
- Automate compliance checks
- Monitor for drift

Container security is critical for **Shopify, Datadog, and GitLab** running production Kubernetes.

You implement defense-in-depth container security with scanning, runtime protection, and policy enforcement.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.