Product team testing a smart-speaker-style device with microphones in an anechoic chamber

Cyber Resilience Act

security.txt for product makers: RFC 9116 fields, placement, signing and CRA fit

Last updated:

security.txt for product makers is the RFC 9116 file, published by the IETF in April 2022, that a device or firmware maker serves at /.well-known/security.txt on its own domains so that anyone who finds a flaw in a product can reach the security team. It needs two fields, Contact and Expires; a product maker should add Policy, Encryption, Preferred-Languages, Canonical and, if it publishes machine-readable advisories, CSAF. The file is a signpost: the disclosure policy, the contact behind it and the CRA single point of contact still have to exist.

This page covers the product-maker side: which hosts get the file, what to do about the device's own web interface, signing, the CSAF pointer, and how the file fits the Cyber Resilience Act and ETSI EN 303 645. For the policy text itself, use the vulnerability disclosure policy template; for the triage process behind the mailbox, see the CVD process under ISO/IEC 29147 and 30111.

Key takeaways

  • This page covers the product-maker side: which hosts get the file, what to do about the device's own web interface, signing, the CSAF pointer, and how the file fits the Cyber Resilience Act and ETSI EN 303 645.
  • A product maker's file needs Contact and Expires, plus a Policy link to the disclosure policy.
  • Put the file on every vendor-run domain where a report might start, and keep it off the device itself unless you can keep it current.
  • Sign it with an OpenPGP cleartext signature and list every serving URL in Canonical.

What must a product maker's security.txt contain?

A product maker's file needs Contact and Expires, plus a Policy link to the disclosure policy. RFC 9116 says Contact "MUST always be present", and that Expires must be present and must not appear more than once. Every other field is optional, but several do real work for a hardware company.

Field RFC 9116 or registry rule What a product maker puts there
Contact Required, may repeat, listed in order of preference; web URIs must start with https://; email and phone use mailto: and tel: A shared PSIRT mailbox first, then a web form; never a single person's address
Expires Required, exactly once, RFC 3339 date; recommended less than a year ahead A date about 11 months out, owned by a named person
Encryption URI of a key, never the key itself The PSIRT OpenPGP key on the vendor domain
Policy URI of the disclosure policy The policy page that names products, firmware, apps and cloud services in scope
Acknowledgments URI of a page that credits researchers The hall-of-thanks page linked from advisories
Preferred-Languages Once only; comma-separated language tags; without it, reporters may assume English en plus the languages your PSIRT can answer in
Canonical URIs where the file lives; if the URI you fetched is not listed, the file should not be trusted Every exact URL that serves this file
Hiring URI of security job openings Optional
CSAF Registry field, change controller OASIS Open; points to provider-metadata.json Your CSAF provider metadata, if you publish CSAF advisories or VEX
Bug-Bounty Registry field, once only, True or False False unless you pay rewards

The IANA security.txt Fields registry (last updated 7 March 2026) is the authoritative list; RFC 9116 created it so that fields such as CSAF and Bug-Bounty could be added without a new RFC. Field names are case-insensitive, each field sits on its own line, and lines starting with # are comments.

Example file for a device maker

The example below is synthetic: example.com stands for the vendor domain, and every address and date is invented. The comment lines are allowed by RFC 9116 and help the next person who edits the file.

# security.txt for example.com (vendor of the X-series cameras)
# Owner: PSIRT, renew before Expires. Signed with the PSIRT signing key.
Contact: mailto:[email protected]
Contact: https://example.com/security/report
Expires: 2027-10-31T23:59:00Z
Encryption: https://example.com/.well-known/psirt-key.asc
Policy: https://example.com/security/disclosure-policy
Acknowledgments: https://example.com/security/thanks
Preferred-Languages: en, de
Canonical: https://example.com/.well-known/security.txt
CSAF: https://example.com/.well-known/csaf/provider-metadata.json
Bug-Bounty: False

The free security.txt generator builds the required and common optional lines in your browser; add the CSAF line by hand if you need it.

Where should the file live: vendor domain, support portal or the device?

Put the file on every vendor-run domain where a report might start, and keep it off the device itself unless you can keep it current. RFC 9116 section 3.1 says a file "MUST only apply to the domain or IP address in the URI used to retrieve it, not to any of its subdomains or parent domains", and adds that it "MAY also apply to products and services provided by the organization publishing the file". That second sentence is what lets one file on the vendor domain cover a whole product line.

Host Publish security.txt? Note
Main vendor domain, bare and www Yes, on both They are two scopes under RFC 9116; serve the same file and list both URLs in Canonical
Support or download portal Yes Firmware images and release notes live here, so researchers land here
Cloud API and device-management domains Yes The companion app and the cloud back end are in most device reports
Third-party shop or documentation platform Only if the platform lets you reserve the path Section 5.6 asks you to reserve the security.txt names so no other tenant can claim them
The device's local web interface Usually no See below

The device is the hard case. A file built into firmware ships with an Expires date that will pass on every unit that is never updated, and section 5.3 of the RFC says that having no file may be preferable to having one with stale information. The local interface also often runs on a self-signed certificate, and section 5.7 asks for extra human validation in that case. The practical pattern is a short line on the device's About or Support page: "Report a security issue: example.com/security". That text can stay correct for the life of the product, because the vendor page behind it can change.

If you do serve the file from the device, generate it at runtime from a value you can update with configuration rather than firmware, and treat the Expires date as part of your support-period planning.

How do you sign security.txt, and with which key?

Sign it with an OpenPGP cleartext signature and list every serving URL in Canonical. Section 2.3 of RFC 9116 recommends both, so that the signature also authenticates the location of the file. The threat is concrete: section 5.1 notes that an attacker who has compromised a website can change the file or redirect it, which "can result in security reports not being received by the organization or being sent to the attacker".

# write the unsigned file, then clear-sign it with the PSIRT signing key
gpg --local-user [email protected] --clearsign security.txt.unsigned
mv security.txt.unsigned.asc security.txt
# verify before you upload
gpg --verify security.txt

Three practical rules for a product company:

  • Use a dedicated PSIRT key whose fingerprint appears on your policy page and in advisories. The RFC tells researchers not to assume that the Encryption key is the signing key, so say which key signs.
  • Re-sign after every edit. A signed file edited by hand fails verification.
  • Track key expiry with file expiry. An expired signing key makes a valid file look suspicious; renew both on the same calendar entry.

How does security.txt support the CRA single point of contact and CVD duties?

security.txt makes the contact the CRA requires easy to find; it does not replace it. Article 13(17) of the Cyber Resilience Act requires manufacturers to "designate a single point of contact to enable users to communicate directly and rapidly with them, including in order to facilitate reporting on vulnerabilities". The same paragraph says users must be able to choose their preferred means of communication, which must not be limited to automated tools.

CRA provision What security.txt does What else you need
Article 13(17): single point of contact, easy to identify Machine-readable pointer that researchers and scanners check first A monitored human channel: Contact lines for email and a form, never an automated tool alone
Annex I Part II (5): put in place and enforce a CVD policy Policy links to it The policy itself, and evidence that you follow it
Annex I Part II (6): a contact address for reporting vulnerabilities, including in third-party components Contact publishes it A policy scope that names firmware, SDK and open-source components
Annex II point 2: user information names the single point of contact and where the CVD policy is found Gives the URL to print The URL in the manual, quick-start sheet or app
Article 14: report actively exploited vulnerabilities Brings reports in The 24-hour route described in the CRA reporting guide

The Commission's CRA FAQ version 1.4 (4 September 2026, question 5.1, footnote 9) restates that Annex I Part II requires "a single point of contact where vulnerabilities can be reported". The same answer lists researchers, customers and government agencies among the ways a manufacturer becomes aware of an exploited vulnerability, which is why the inbox behind Contact needs an owner on every working day.

Article 13(17) applies from 11 December 2027, but reporting under Article 14 has applied since 11 September 2026, and a researcher's report is one way a manufacturer learns that a vulnerability is exploited. The CRA checklist for device makers puts the contact and policy in its first phase for that reason. The Annex II user information guide covers how to print the contact in product documentation, and CRA Annex I explained places the vulnerability-handling requirements in context. The Cyber Resilience Act hub has the full timeline.

Does security.txt meet ETSI EN 303 645 provision 5.2-1?

No, not on its own: provision 5.2-1 asks for a published policy, and security.txt only points to it. ETSI EN 303 645 V3.1.3 (2024-09) says the manufacturer "shall make a vulnerability disclosure policy publicly available", with at a minimum contact information, timelines for the initial acknowledgement of a report, and timelines for status updates until resolution.

security.txt covers the first item through Contact and links the other two through Policy. The two timelines have to be written in the policy page. Provision 5.2-1 is mandatory in the standard's conformance table, while 5.2-2 (act on disclosed vulnerabilities in a timely manner) is a recommendation; the standard notes that the process is conventionally completed within 90 days for a software fix. An assessor checking 5.2-1 will follow the Policy link, so the link must resolve and the page must state both timelines.

How does the CSAF field point to your advisories?

The CSAF field tells advisory tools where your provider-metadata.json lives. CSAF 2.0 requirement 8 says the file "MUST" contain at least one CSAF field pointing to it, over https://, when security.txt is your discovery route.

Section 7.3.1 of CSAF 2.0 sets the order in which a retrieving tool looks for your metadata:

  1. The well-known URL /.well-known/csaf/provider-metadata.json on your main domain (requirement 9).
  2. The CSAF field in security.txt (requirement 8).
  3. The DNS path csaf.data.security.<domain> (requirement 10), only if the first two found nothing.

A CSAF provider must meet at least one of requirements 8 to 10. Two details matter to product makers. If one of your CSAF URLs is the requirement 9 well-known path, it must be the first CSAF line. Listing several provider files is allowed after a merger or acquisition, but the standard says this "SHOULD NOT be done" and should be removed as soon as possible. A device maker that publishes VEX statements in CSAF gets them found through the same line; see CSAF and VEX for device makers.

What are the common security.txt mistakes on product sites?

The most common failures are an expired file and a contact nobody reads. Both are worse than they look, because RFC 9116 treats data past Expires as stale and section 5.3 warns that reports may then go to the wrong place.

  • Expired file. Expires passed months ago because the person who set it left. Tools that follow the RFC treat its contents as stale.
  • Dead contact. The mailbox bounces, or lands in a general support queue with a five-day reply target. A researcher who gets no answer goes public or goes to a CSIRT.
  • Wrong content type. A CMS returns its HTML 404 page with status 200 at /.well-known/security.txt. The RFC requires text/plain with charset=utf-8 over HTTPS.
  • File on www only. The bare domain, support portal and API domain have none, and each is its own scope.
  • Canonical mismatch. The file lists a URL other than the one it was fetched from, so the RFC says it should not be trusted.
  • Edited after signing. The signature fails, and a careful researcher stops there.
  • Form-only contact. One Contact line pointing to a web form with a CAPTCHA, which also clashes with the CRA rule against limiting contact to automated tools.
  • Policy link to a PDF on a file share. It breaks at the next site migration.
  • Language list repeated. Preferred-Languages may appear only once; put all tags on one line.

How do you keep the file from going stale?

Give the file an owner, a renewal date and an automated check. RFC 9116 section 5.1 asks organisations to "regularly monitor the file and the referenced resources to detect tampering", which a scheduled job can do for every domain in scope.

A minimal check, run weekly from outside your network, fetches the file, confirms the content type and fails when Expires is less than 30 days away:

#!/bin/sh
# usage: check-securitytxt.sh example.com
url="https://$1/.well-known/security.txt"
curl -fsS -D /tmp/h.txt -o /tmp/s.txt "$url" || exit 1
grep -qi '^content-type: text/plain' /tmp/h.txt || { echo "bad type"; exit 1; }
exp=$(grep -i '^Expires:' /tmp/s.txt | head -n1 | cut -d' ' -f2)
[ $(( $(date -d "$exp" +%s) - $(date +%s) )) -gt 2592000 ] || { echo "expires soon"; exit 1; }

Extend it to send a test message to each Contact once a quarter and to confirm that Policy, Encryption and CSAF URLs return 200. Renew the file and the signing key together, and record the renewal in your PSIRT log.

Where does AI-assisted analysis fit behind the contact?

security.txt brings reports in; the work starts when a report names a firmware version. SoftWSP's platform unpacks firmware images, detects components and versions into an SBOM, and matches them against NVD, the CISA Known Exploited Vulnerabilities catalog and FIRST EPSS, so a PSIRT can see whether a reported component sits in a given firmware release. It also reads CISA's published CSAF advisories for industrial products. The scoring is deterministic code; an AI step drafts the narrative of the findings with a citation check on every claim, and an engineer reviews it before it is used. In short, the code scores and AI narrates.

To see where your disclosure set-up stands against the rest of the CRA's Annex I, run the free CRA readiness check.

This guide is general information, not legal advice.

Put this guide to work

Frequently asked questions

Which security.txt fields are required?

RFC 9116 makes two fields mandatory: Contact, which may appear several times and is listed in order of preference, and Expires, which must appear exactly once. Encryption, Policy, Acknowledgments, Preferred-Languages, Canonical and Hiring are optional, and the IANA registry adds CSAF and Bug-Bounty. A product maker should also include Policy, because the disclosure policy is where timelines and scope live.

Should a device serve security.txt from its own web interface?

Usually not. A file baked into firmware carries an Expires date that goes stale on devices that are never updated, and RFC 9116 says stale information may be worse than no file. Publish the file on the vendor domains instead, and show a short security contact line with the vendor URL on the device's About or Support page.

Does security.txt satisfy the CRA single point of contact?

Only in part. Article 13(17) of the CRA requires a single point of contact that is easy to identify, lets users choose their means of communication and is not limited to automated tools, and Annex II puts it in the user information. security.txt helps researchers and tools find that contact, but the contact itself, the coordinated vulnerability disclosure policy and the user documentation still have to exist.

Does security.txt meet ETSI EN 303 645 provision 5.2-1?

Not on its own. Provision 5.2-1 requires a public vulnerability disclosure policy with contact information, a timeline for acknowledging a report and a timeline for status updates. security.txt can carry the contact and link to the policy with the Policy field, but the timelines belong in the policy.

Where does the CSAF field go in security.txt?

Add a line such as CSAF: https://example.com/.well-known/csaf/provider-metadata.json. CSAF 2.0 requirement 8 says the field points to your provider-metadata.json over https, and if one of your CSAF URLs is the well-known path from requirement 9, that URL must be the first CSAF entry.

Sources

  1. RFC 9116: A File Format to Aid in Security Vulnerability Disclosure (April 2022; retrieved 13 November 2026)
  2. IANA: security.txt Fields registry (last updated 7 March 2026; retrieved 13 November 2026)
  3. OASIS: Common Security Advisory Framework Version 2.0 (OASIS Standard, 18 November 2022; retrieved 13 November 2026)
  4. Regulation (EU) 2024/2847 (Cyber Resilience Act), Article 13(17), Annex I Part II and Annex II, EUR-Lex (OJ 20 November 2024; retrieved 13 November 2026)
  5. European Commission: FAQs on the Cyber Resilience Act (version 1.4, 4 September 2026; retrieved 13 November 2026)
  6. ETSI EN 303 645 V3.1.3 (2024-09), Cyber Security for Consumer Internet of Things: Baseline Requirements (retrieved 13 November 2026)
Was this guide helpful?

In this cluster

security.txt for product makers: RFC 9116 fields, placement, signing and CRA fit