CRA Art.10: Security Obligations During the Product Lifecycle — Updates, Vulnerability Handling, and End-of-Life (Developer Guide 2026)
Post #460 in the sota.io EU Cyber Compliance Series
The EU Cyber Resilience Act (Regulation (EU) 2024/2847, "CRA") entered into force on 10 December 2024. Most developer guides focus on pre-market obligations: what you must build before releasing a product. Article 10 is different. It governs what you must keep doing after release — for the entire supported lifetime of your product.
This is the obligation that most software teams underestimate. You can complete a conformity assessment, draft an SBOM, and attach a CE marking. But Article 10 requires that you maintain a functioning security-update pipeline, respond to vulnerabilities in a coordinated way, and formally notify users when you intend to stop providing security support — and you must do this continuously, for years.
This guide explains:
- The structure of Article 10 and how it relates to Article 13 (pre-market) and Article 16 (vulnerability reporting)
- Every obligation Article 10 imposes, clause by clause
- The "expected product lifetime" concept and the 5-year minimum
- Security update requirements — free, automatic, separable from features
- SBOM maintenance obligations after the initial release
- End-of-life notification requirements
- Implementation patterns and code examples
- What happens when you violate Article 10 post-market
Where Article 10 Fits in the CRA Structure
The CRA structures manufacturer obligations across several articles. It helps to understand where Article 10 sits before reading it in detail.
| Article | What It Covers | When It Applies |
|---|---|---|
| Art.6 | Essential cybersecurity requirements (Annex I) — security-by-design, vulnerability handling processes, secure configuration | Before market placement |
| Art.13 | Manufacturer obligations — conduct risk assessment, maintain technical documentation, draw up declaration of conformity, affix CE marking | Before market placement |
| Art.10 | Ongoing security obligations after release — updates, SBOM maintenance, end-of-life | After market placement, throughout supported lifetime |
| Art.14 | Reporting obligations — notify ENISA within 24h of actively exploited vulnerability discovery | Ongoing, event-triggered |
| Art.16 | Coordinated vulnerability disclosure — publish a CVD policy, handle incoming vulnerability reports | Ongoing |
Article 10 is the post-release pillar. A product that passes its conformity assessment but lacks a functioning update pipeline is non-compliant from the moment Article 10 obligations begin to apply — which, for the update and vulnerability-handling provisions, is 11 September 2026.
Article 10 Obligations — Clause by Clause
10(1): Manufacturers Shall Make Security Updates Available
"Manufacturers shall ensure that vulnerabilities of the product with digital elements are handled effectively throughout the expected product lifetime or for a period of five years from the date when the product is placed on the market, whichever is shorter, or for a period of at least five years if the expected product lifetime is longer."
This is the core commitment. You must handle vulnerabilities and provide security updates for:
- The expected product lifetime — if shorter than 5 years (e.g., a software tool with a 2-year planned lifecycle)
- At least 5 years — if the expected lifetime is 5 years or longer, or if you haven't defined a shorter expected lifetime
The "expected product lifetime" is determined by you at the time of conformity assessment and must be documented in your technical documentation (Art.13). If you sell software-as-a-product with a perpetual licence model and no defined end-of-life, the regulator will likely interpret this as a lifetime of at least 5 years.
Practical implication: If you release a product in September 2026, you are committing to security update support until at least September 2031. You cannot release a product and then quietly stop patching it 18 months later.
10(2): Updates Must Be Free of Charge
"Manufacturers shall ensure that security updates are provided to users free of charge."
Security updates cannot be paywalled. This applies to the security update itself — not to paid support contracts, priority response times, or feature releases. You may still charge for:
- New major versions with feature additions
- Professional support SLAs
- Installation assistance services
But the update that fixes the CVE in your software must be available to every user, regardless of whether they are on a free or paid tier. Gating critical security fixes behind a subscription is explicitly prohibited.
Implementation note: If your product uses a subscription model where some features are paid-tier only, you need to architect your update pipeline so that security patches are applied to all licence tiers. This affects how you structure version branches and release channels.
10(3): Security Updates Must Be Separable from Feature Updates
"Manufacturers shall ensure that security updates are provided separately from non-security updates, unless joint provision is technically necessary."
You cannot bundle security fixes exclusively into major feature releases. If a CVE is fixed in your codebase today, users must be able to receive that fix without also taking on the regression risk of every new feature you developed in the same release.
The "unless technically necessary" exception is narrow. You cannot claim technical necessity simply because your architecture makes separate releases inconvenient. The exception covers genuine technical dependencies where the security fix cannot be backported to an older stable branch.
What this means for your release process:
✓ Maintain a stable security-patch branch (e.g., v2.3.x) alongside main
✓ Backport CVE fixes to the stable branch and release independently
✓ Users on v2.3.x receive security patches without being forced to v3.x
✗ "Please upgrade to v3 to get the security fix" — non-compliant
✗ "Our next quarterly release will include the fix" — potentially non-compliant
10(4): Automatic Updates — Default On
"Manufacturers shall ensure that automatic security updates are enabled by default, unless the user has explicitly opted out, and inform the user thereof."
This is one of the most operationally challenging requirements. Your product must:
- Check for security updates automatically (on a schedule or via notification push)
- Apply security updates automatically — without requiring the user to manually initiate installation
- Default to this behaviour — the user does not need to opt in, they need to opt out
- Inform the user that automatic updates are enabled and how to disable them
The requirement to inform users covers both the initial disclosure (at installation or first use) and each time an automatic update is applied. Users must be able to see what changed.
Platform-specific implementation considerations:
| Platform | Mechanism | Challenge |
|---|---|---|
| Web SaaS | Server-side deployment — update is automatic by nature | Lower burden: update happens before user interaction |
| Desktop app | OS-level auto-updater (Sparkle, Squirrel, Electron updater) | Must be enabled by default; admin privilege complications |
| CLI tool | Package manager update notifications | Harder: user must invoke update; consider auto-check with prompt |
| Firmware / embedded | OTA update infrastructure | Significant engineering investment; connectivity assumptions |
| Docker image | Tag pinning defeats auto-update; digest tracking required | Notify users when a new security-patched digest is available |
For server-deployed products, the auto-update requirement is most naturally met by keeping your users on a managed service where you control deployments. Self-hosted installations require an active update mechanism.
10(5): Vulnerability Handling Throughout the Lifecycle
"Manufacturers shall put in place and enforce a policy for coordinated vulnerability disclosure."
The Art.16 obligation (CVD policy) applies at market placement, but Article 10 reinforces that the CVD process must remain operational for the full supported lifetime. A CVD policy that exists in a document but is not enforced — no one monitors the security@ inbox, reports go unacknowledged — violates this provision.
Ongoing CVD obligations include:
- Maintaining a publicly accessible mechanism to receive vulnerability reports (email, web form, or a VDP hosted on a recognised platform)
- Acknowledging receipt of reports within a reasonable timeframe (ENISA guidance suggests 72 hours)
- Publishing CVEs for confirmed vulnerabilities in your products (using the CVE programme or equivalent)
- Providing remediation advice alongside any public disclosure
10(6): SBOM Maintenance After Release
"Manufacturers shall document and keep up to date information necessary to assess the cybersecurity of the products with digital elements, including by maintaining a software bill of materials."
The SBOM is not a one-time document you generate at release. Every time you release a security update, your SBOM must be updated to reflect:
- Removed vulnerable components
- Updated component versions
- New third-party dependencies introduced in the patch
- Changed transitive dependency versions
The SBOM must be maintained in a machine-readable format (SPDX 2.3 or CycloneDX 1.4+ are the de facto standard formats accepted by European market surveillance authorities).
Automated SBOM update pipeline:
# sbom_updater.py — called after each security release
import json
import subprocess
from datetime import datetime, timezone
def generate_updated_sbom(project_root: str, version: str) -> dict:
"""Generate updated CycloneDX SBOM after a security patch release."""
# Run your preferred SBOM generator
result = subprocess.run(
["cyclonedx-py", "environment", "--output-format", "json"],
cwd=project_root,
capture_output=True,
text=True,
check=True
)
sbom = json.loads(result.stdout)
# Update metadata
sbom["metadata"]["timestamp"] = datetime.now(timezone.utc).isoformat()
sbom["metadata"]["component"]["version"] = version
# Add security-patch annotation
sbom["metadata"]["properties"] = sbom["metadata"].get("properties", [])
sbom["metadata"]["properties"].append({
"name": "cra:update-type",
"value": "security-patch"
})
return sbom
def verify_sbom_completeness(sbom: dict) -> list[str]:
"""Check that all components have PURL and known-vulnerability status."""
issues = []
for component in sbom.get("components", []):
if not component.get("purl"):
issues.append(f"Missing PURL: {component.get('name', 'unknown')}")
if not component.get("licenses"):
issues.append(f"Missing license: {component.get('name', 'unknown')}")
return issues
10(7): Network of CSIRTs Notification
Article 10 cross-references the Art.14 notification obligations. When you discover an actively exploited vulnerability in your product:
- Within 24 hours: Submit an early warning to the relevant ENISA single reporting platform
- Within 72 hours: Submit a vulnerability notification with severity, affected versions, and preliminary mitigation
- Within 14 days: Submit a final report with root cause analysis and remediation confirmation
The 24-hour clock starts when you become aware that exploitation is active — not when you become aware that a vulnerability exists. A vulnerability you discover through internal code review does not trigger the 24-hour clock until you have evidence of active exploitation.
10(8): User Notification of Updates
"Manufacturers shall inform users about security updates that are available or have been automatically applied."
Every security update must be accompanied by a notification to affected users. The notification must include:
- The fact that a security update has been applied (or is available)
- The nature of the vulnerability addressed (at minimum: severity level and affected component)
- Instructions for verifying the update was applied
- Where to find the full CVE or security advisory
The notification channel can be in-product (a dashboard alert, a release notes page) or out-of-band (email, RSS feed, security mailing list). The key requirement is that users have a reliable mechanism to learn about security changes without having to proactively poll your website.
Minimum viable notification template:
Subject: [SECURITY] YourProduct v2.3.7 — Critical Security Update
A security update for YourProduct has been released.
Severity: Critical (CVSS 9.1)
CVE: CVE-2026-12345
Affected versions: 2.0.0 – 2.3.6
Fixed in: 2.3.7
What was fixed: A remote code execution vulnerability in the YAML
parser allowed unauthenticated attackers to execute arbitrary code
via a crafted configuration file.
Update action: [automatic update has been applied / please update via...]
Full advisory: https://yourdomain.com/security/advisories/2026-001
The End-of-Life Obligation
Article 10's end-of-life provisions are among the most operationally novel requirements for software teams.
You Must Define an End of Support Date
If your product has a finite support lifetime, you must state what it is. This information must appear in:
- Your product's technical documentation (Art.13)
- Your security update policy (Art.16 CVD policy)
- Communications to users (Art.10 notification obligations)
You Must Notify Users Before EoL
"Manufacturers shall inform users, as early as possible, and no later than 14 days before the end of the support period, about the end of the support period."
Fourteen days is the legal minimum. In practice, responsible disclosure of end-of-life requires substantially more notice — at least 12 months for enterprise software, and ideally longer for products embedded in critical infrastructure or where migration is complex.
The notification must explain:
- The precise date when security updates will cease
- The final version that will receive security patches
- What happens to existing users after EoL (are they still licensed? is there a migration path?)
- Whether an extended support option is available (at any price)
After EoL: Residual Obligations
Once the support period ends and you have notified users in advance, you are no longer obligated to provide new security updates. However:
- You must not actively make the product less secure (e.g., you cannot revoke access to existing patches users have already applied)
- If the product is still being actively placed on the market (new sales), you may need to reassess your support commitments
- Market surveillance authorities retain the right to require action if an end-of-life product becomes involved in large-scale security incidents
Implementation Roadmap for Article 10 Compliance
Stage 1: Lifecycle Documentation (Complete Before September 2026)
# product-lifecycle.yaml — commit this to your compliance repository
product:
name: "YourProduct"
version_series: "2.x"
initial_market_date: "2026-09-01"
expected_product_lifetime_years: 5
end_of_security_support_date: "2031-09-01"
security_update_policy:
updates_free: true
updates_automatic_by_default: true
updates_separable_from_features: true
separate_security_branch: "v2-security"
notification_channels:
in_product: true
security_mailing_list: "security-announce@yourdomain.com"
rss_feed: "https://yourdomain.com/security/feed.xml"
cvd_policy_url: "https://yourdomain.com/security/cvd"
sbom_format: "CycloneDX 1.6"
sbom_location: "https://yourdomain.com/security/sbom/v2-latest.json"
Stage 2: Security Branch Infrastructure
Set up a dedicated security-patch branch in your version control:
# Establish a security-patch branch from the current stable release
git checkout -b v2-security v2.3.6
# Pin this branch — only security patches, no feature commits
# Protect with branch rules: require PR + security team review
git push origin v2-security
# Configure CI to build and release from this branch independently
# of your main development branch
Stage 3: Automated Update Distribution
Configure your update delivery pipeline so that security patches from v2-security are automatically picked up by deployed instances:
# .github/workflows/security-release.yml
name: Security Patch Release
on:
push:
branches: [v2-security]
tags: ['v2.*-security*']
jobs:
release:
name: Build and Distribute Security Patch
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build security-patched artifact
run: make build-security-patch
- name: Update SBOM
run: |
cyclonedx-py environment --output-format json > sbom-v2-latest.json
# Validate completeness
python3 scripts/validate_sbom.py sbom-v2-latest.json
- name: Publish to update server
run: |
# Push to your update distribution endpoint
# This is what auto-update clients will poll
./scripts/publish-security-update.sh
- name: Notify users
run: |
# Send to security mailing list
./scripts/notify-security-update.sh \
--version "${{ github.ref_name }}" \
--advisory-url "https://yourdomain.com/security/advisories/"
- name: Publish updated SBOM
run: |
aws s3 cp sbom-v2-latest.json \
s3://your-bucket/security/sbom/v2-latest.json \
--content-type application/json
Stage 4: Monitoring and Alerting
You cannot fulfil Article 10 without knowing when vulnerabilities appear in your dependencies. Set up dependency vulnerability monitoring:
# vulnerability_monitor.py — run daily in CI
import subprocess
import json
def check_dependencies_for_vulnerabilities(requirements_file: str) -> list[dict]:
"""Check if any current dependencies have known CVEs."""
result = subprocess.run(
["pip-audit", "--format", "json", "-r", requirements_file],
capture_output=True,
text=True
)
if result.returncode != 0:
data = json.loads(result.stdout)
vulns = []
for dep in data.get("dependencies", []):
for vuln in dep.get("vulns", []):
vulns.append({
"package": dep["name"],
"installed_version": dep["version"],
"vuln_id": vuln["id"],
"fix_versions": vuln.get("fix_versions", []),
"description": vuln.get("description", ""),
})
return vulns
return []
def alert_if_critical(vulnerabilities: list[dict]) -> None:
"""Send PagerDuty/Slack alert for critical CVEs requiring immediate patch."""
critical = [v for v in vulnerabilities if "CRITICAL" in v.get("description", "").upper()
or any("critical" in str(fv).lower() for fv in v.get("fix_versions", []))]
if critical:
# Your alert mechanism here
print(f"CRITICAL: {len(critical)} critical CVEs require immediate security patch")
for v in critical:
print(f" {v['package']} {v['installed_version']}: {v['vuln_id']}")
Article 10 vs. Article 13: What Happens When?
A common source of confusion is the distinction between pre-market obligations (Art.13) and post-market obligations (Art.10). Here is the clearest way to think about it:
| Question | Article 13 (Pre-Market) | Article 10 (Post-Market) |
|---|---|---|
| When does it apply? | Before you place the product on the EU market | After the product is on the market |
| What does it require? | Risk assessment, technical documentation, conformity assessment, CE marking, SBOM at release | Security updates, SBOM maintenance, EoL notification, ongoing vulnerability handling |
| Who enforces it? | Notified bodies (conformity assessment) + market surveillance at point of placement | Market surveillance authorities throughout the product lifetime |
| What triggers enforcement? | Placing the product on the market without compliance | A security incident, complaint, or routine market surveillance audit |
| Penalty for violation? | Cannot legally sell in the EU | Withdrawal order, fine up to €15M or 2.5% global revenue |
Both articles carry the same maximum financial penalties under Article 64. The difference is when enforcement can occur. Article 10 violations can emerge years after a product was initially compliant — if you stop maintaining it while it is still on the market.
Common Mistakes and How to Avoid Them
Mistake 1: Treating the SBOM as a Static Artifact
What happens: A team generates an SBOM at the time of their first conformity assessment, commits it to the repo, and never updates it again.
Why it's a violation: Article 10(6) requires that you "keep up to date information necessary to assess the cybersecurity of the products with digital elements." Every security update that changes component versions invalidates an unchanged SBOM.
Fix: Automate SBOM regeneration as part of your security release pipeline. Never check in a manually edited SBOM.
Mistake 2: Gating Security Patches Behind Paid Upgrades
What happens: A vulnerability is fixed in v3.0 (paid upgrade) but not backported to v2.x (the version most existing users are on).
Why it's a violation: Article 10(2) requires that security updates are provided free of charge. If fixing a CVE requires purchasing a new major version, the security update is not free.
Fix: Maintain a security-patch branch for each supported version series. Backport security fixes even when feature development has moved on.
Mistake 3: Bundling Security Fixes with Feature Updates
What happens: A team packages 60 days of feature development together with three CVE fixes in a quarterly release. Users on an older version cannot get the security fixes without taking the full feature upgrade.
Why it's a violation: Article 10(3) requires security updates to be separately available unless technically necessary.
Fix: Release security patches on the security-patch branch independently. Users on a supported version series can apply the patch without feature migration.
Mistake 4: No Formal EoL Process
What happens: A product's support quietly lapses. No announcement is made. Users continue running unsupported software believing it is still receiving patches.
Why it's a violation: Article 10 requires advance notification of the end of the support period, not less than 14 days (and in practice, responsible vendors give 12+ months notice).
Fix: Include the end-of-support date in your technical documentation from the moment the product is placed on the market. Schedule the EoL communication campaign in advance.
Mistake 5: Auto-Updates Off by Default
What happens: An installer presents the user with "Check for updates: ☐ Enable" unchecked by default.
Why it's a violation: Article 10(4) requires automatic security updates to be enabled by default. The user must explicitly opt out, not opt in.
Fix: Audit all installer defaults. Auto-update must be active from the first launch unless the user has explicitly deselected it during setup.
CRA Implementation Timeline
| Date | Obligation |
|---|---|
| 10 December 2024 | CRA enters into force |
| 11 September 2026 | Art.14 reporting obligations apply (ENISA vulnerability notifications) |
| 11 December 2027 | Full CRA application — Art.10 obligations apply to all products placed on the market |
| From market placement | Art.10 commitments attach to each product at the moment it is placed on the EU market |
Note: the "from market placement" row matters for products placed on the market after December 2027. If you sell a product from January 2028, you are immediately bound by Article 10 obligations for the supported lifetime of that product.
For products placed on the market before December 2027, the obligations apply from December 2027 — you do not get a grace period for existing products simply because they were placed on the market while the CRA was being implemented.
Enforcement and Penalties
Market surveillance authorities (MSAs) can enforce Article 10 violations through the mechanisms in Articles 54–64 of the CRA. Key enforcement tools:
- Corrective measures — requiring you to release a security update within a specified period
- Product withdrawal — requiring you to remove the non-compliant product from the EU market
- Financial penalties — up to €15 million or 2.5% of global annual turnover, whichever is higher
Post-market surveillance is event-driven: most Article 10 investigations will begin after a security incident, a vulnerability disclosure that reveals the manufacturer had no update mechanism, or a complaint from a user who received no end-of-life notification. Proactive audits are also possible but less common in the initial enforcement phase.
MSAs share information through the EU ENISA coordination network, and a finding in one Member State can trigger coordinated action across the EU.
The sota.io Connection
Running software products on sota.io's EU-native infrastructure simplifies several Article 10 compliance patterns:
- Automatic updates for server-side products: When you deploy to sota.io, you control the deployment pipeline. Rolling out a security patch to all running instances is a single deploy command — no user-side update required. This satisfies Art.10(4) for SaaS products by design.
- SBOM hosting: Your updated SBOMs can be served from a persistent URL on your sota.io deployment, with automated updates triggered by your CI pipeline.
- EU data residency: All telemetry, update logs, and vulnerability management data stays within the EU, simplifying your compliance documentation for GDPR interactions with Art.10 records.
- No US-parent cloud risk: CLOUD Act exposure for vulnerability management records is eliminated when your infrastructure is European-native.
Article 10 Compliance Checklist
Pre-market (before placing on EU market):
☐ Defined expected product lifetime in technical documentation
☐ Calculated security update end date (max(5 years, expected lifetime))
☐ Established security-patch branch separate from main development
☐ Configured auto-update mechanism, enabled by default
☐ Set up security mailing list / notification channel
☐ Integrated SBOM generation into release pipeline
☐ Documented EoL communication plan
Ongoing (throughout supported lifetime):
☐ CVD policy publicly accessible and actively monitored
☐ Dependency vulnerability scanning running (daily recommended)
☐ Security patches released on security-patch branch, not bundled in features
☐ SBOM updated with each security release
☐ Users notified of each security update (in-product + out-of-band)
☐ Zero critical CVEs older than 30 days without released patch or timeline
End-of-life (before support ends):
☐ EoL date communicated to all users (≥14 days; recommend ≥12 months)
☐ Final patched version clearly identified
☐ Migration guidance published
☐ EoL date recorded in SBOM metadata
☐ Market surveillance authority notified if required by MSA
Where to Learn More
- CRA Full Text: Regulation (EU) 2024/2847 — eur-lex.europa.eu
- ENISA CRA Guidance: ENISA publishes technical guidelines on conformity assessment and vulnerability reporting
- CVE Programme: cve.org — register as a CNA to publish CVEs for your products
- SPDX Specification: spdx.dev — SBOM standard accepted by EU MSAs
- CycloneDX: cyclonedx.org — alternative SBOM standard, widely used in Java/Node ecosystems
CRA Series Index
| Article | Topic | Post |
|---|---|---|
| Art.2 | Scope — what products are covered | #455 |
| Art.3 | Definitions — manufacturer, distributor, importer | #456 |
| Art.6 | Essential requirements — Annex I obligations | #457 |
| Art.7 | Presumption of conformity via harmonised standards | #458 |
| Art.8 | OSS Steward obligations — foundations and maintainers | #459 |
| Art.9 | Due diligence for third-party components — SBOM, supply chain | #463 |
| Art.10 | Security obligations during product lifecycle | #460 (this post) |
| Art.11 | Vulnerability handling — ban on known bugs, CVD policy | #461 |
| Art.12 | Authorised representative for non-EU manufacturers | #462 |
| Art.13 | Manufacturer obligations at market placement | #400 |
| Art.16 | Vulnerability reporting — ENISA notification obligations | #416 |