security.txt: publishing a security contact under RFC 9116
Someone who spots a flaw on your website first has to work out who to tell. A short text file in a fixed location answers that question for them, as long as someone keeps it current.
Updated: 05 November 2026
Why security.txt exists
Without a published contact, a researcher who finds a vulnerability ends up at the legal notice, a general sales inbox or a contact form. A warning about an exposed database may then be read by whoever handles orders, or never read at all. Some finders give up after the second attempt.
RFC 9116 fixes one location for this: https://example.com/.well-known/security.txt. The file is plain text (text/plain, UTF-8) and must be served over HTTPS. It applies only to the exact host it was fetched from, so shop.example.com needs a file of its own. The old location at /security.txt is still allowed for compatibility, but where both exist, the copy under /.well-known/ wins.
In August 2026 the federal security agency BSI and the Alliance for Cyber Security called on website operators to publish the file, after BSI measurements found one on only 1.8 per cent of German websites. The BSI's own Cyberdome project scans websites and sends what it finds straight to the listed contact.
The two required fields
| Field | Meaning |
|---|---|
Contact: |
where reports go, as a URI: mailto:, https: or tel:; may appear more than once, with the first entry preferred |
Expires: |
the date and time after which the file counts as stale; exactly once, in RFC 3339 format |
RFC 9116 recommends an Expires value less than a year ahead. Anyone reading an expired file is expected to treat it as out of date. A contact written three years ago may lead to a mailbox that was deleted long since.
Optional fields
| Field | Content |
|---|---|
Encryption: |
a link to your public OpenPGP key, never the key itself |
Policy: |
a link to your vulnerability disclosure policy |
Acknowledgments: |
a link to a page thanking past reporters |
Preferred-Languages: |
languages for reports, such as en, de; English is assumed if absent |
Canonical: |
the official URL or URLs of the file |
Hiring: |
security job openings |
CSAF: |
a link to your provider-metadata.json if you publish advisories in CSAF format; not part of RFC 9116, though securitytxt.org lists it |
Every link has to start with https://. Lines beginning with # are comments.
The RFC recommends an OpenPGP cleartext signature over the file. Combined with Canonical, it lets a reporter confirm the file is yours and sits where it should. A small company without a maintained PGP key can safely skip this.
A complete example
# Security contact for example.com
Contact: mailto:security@example.com
Contact: https://example.com/security/report
Expires: 2027-10-31T23:00:00Z
Encryption: https://example.com/.well-known/pgp-key.asc
Preferred-Languages: en, de
Canonical: https://example.com/.well-known/security.txt
Policy: https://example.com/security/policy
Acknowledgments: https://example.com/security/thanks
Write the trailing Z in upper case. RFC 3339 accepts a lower-case one as well, but not every parser does.
Keeping it useful
- Use a role address.
security@example.comsurvives holidays and resignations;j.smith@example.comdoes not. Expireswill lapse whether you remember it or not. A calendar reminder two months ahead is enough; a deployment that writes a fresh date each time is even less work.- A contact that nobody reads is worse than none. The reporter waits, keeps quiet and may end up publishing without ever hearing from you. Decide who looks after the mailbox and how soon a first reply goes out.
- Point
Policyat a short disclosure policy covering which systems are in scope, what reporters may do and when you will respond. The file on its own grants nobody permission to test your systems, and RFC 9116 says so explicitly. - Some content management systems answer every unknown path with an HTML page and status 200. Request the URL once with
curl -Iand confirm thattext/plaincomes back.
Checking security.txt
For this check ZwoWebCheck requests one additional URL: /.well-known/security.txt on the host you entered, over HTTPS only. It follows one redirect if that stays on HTTPS within the same domain, for example from example.com to www.example.com. The file counts only if it arrives as plain text with at least one Contact line. Your report shows the first contact and the expiry date. An expired file earns a warning, while a missing Expires field or a missing file gets a note listing what the file needs at minimum.