Skip to main content
🎀 Speaking at KubeCon EU 2026 Lessons Learned Orchestrating Multi-Tenant GPUs on OpenShift AI View Session
🎀 Speaking at Red Hat Summit 2026 GPUs take flight: Safety-first multi-tenant Platform Engineering with NVIDIA and OpenShift AI Learn More
Security by Design Under the CRA: Practical Engineering Practices
DevOps

Security by Design Under the CRA

Implement security by design practices required by the EU Cyber Resilience Act. From threat modeling to secure defaults and vulnerability disclosure.

LB
Luca Berton
Β· 1 min read

The CRA mandates β€œsecurity by design and by default.” But what does that actually mean in daily engineering work? Here are the concrete practices that satisfy this requirement.

Threat Modeling

Every product must have a documented threat model:

# STRIDE threat model for a web application
threats = {
    "Spoofing": [
        "Attacker impersonates legitimate user via stolen credentials",
        "Mitigation: MFA, session management, credential rotation",
    ],
    "Tampering": [
        "Attacker modifies API requests in transit",
        "Mitigation: TLS everywhere, request signing, integrity checks",
    ],
    "Repudiation": [
        "User denies performing an action",
        "Mitigation: Immutable audit logs, request logging",
    ],
    "Information Disclosure": [
        "Sensitive data exposed through error messages or logs",
        "Mitigation: Error sanitization, log redaction, encryption at rest",
    ],
    "Denial of Service": [
        "Attacker overwhelms service with requests",
        "Mitigation: Rate limiting, autoscaling, circuit breakers",
    ],
    "Elevation of Privilege": [
        "Attacker gains admin access through vulnerability",
        "Mitigation: Least privilege, RBAC, input validation",
    ],
}

Secure Defaults

Every configuration choice must default to the secure option:

# Bad: Insecure defaults
server:
  tls: false  # Disabled by default
  auth: optional  # No auth required
  cors: "*"  # Allow all origins

# Good: Secure defaults (CRA compliant)
server:
  tls: true  # Enabled by default
  auth: required  # Authentication mandatory
  cors: []  # No origins allowed by default
  headers:
    X-Content-Type-Options: nosniff
    X-Frame-Options: DENY
    Strict-Transport-Security: max-age=31536000

Automated Security Testing

# CI/CD security gates
stages:
  - lint
  - sast
  - build
  - dast
  - sbom
  - sign

sast:
  stage: sast
  script:
    - semgrep --config auto --error --json > sast-results.json

dependency-check:
  stage: sast
  script:
    - trivy fs --severity HIGH,CRITICAL --exit-code 1 .

container-scan:
  stage: build
  script:
    - trivy image --severity HIGH,CRITICAL myapp:$CI_COMMIT_SHA

dast:
  stage: dast
  script:
    - zap-baseline.py -t https://staging.example.com -r dast-report.html

sbom-generate:
  stage: sbom
  script:
    - syft . -o cyclonedx-json > sbom.json
    - grype sbom:sbom.json --fail-on critical

sign-artifacts:
  stage: sign
  script:
    - cosign sign --key cosign.key myapp:$CI_COMMIT_SHA
    - cosign attach sbom --sbom sbom.json myapp:$CI_COMMIT_SHA

Key Practices

  1. Threat model before coding β€” document threats and mitigations for every new feature
  2. Default deny β€” no access, no connectivity, no permissions unless explicitly granted
  3. Automate security testing β€” SAST, DAST, dependency scanning in every pipeline
  4. Minimize attack surface β€” remove unused features, close unnecessary ports
  5. Document security decisions β€” CRA requires technical documentation of security rationale

Security by design isn’t a one-time activity β€” it’s embedded in every sprint, every PR, every deployment.


Implementing security by design for CRA compliance? I help teams build secure development processes. Get in touch.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens TechMeOut