The problem it solves
Someone finds a flaw in your site. They want to tell you. Now what?
They try the contact form and it goes to sales. They try info@ and nobody answers. They try social media and get ignored. Some give up. Some post it publicly. Some sell it.
security.txt is the boring fix. It is a plain text file in a known location with an address to send things to. A researcher checks one place, finds a real contact, and tells you. That is the whole idea, and it is defined properly in RFC 9116.
The rules that are not optional
The spec is short but it is strict. Getting these wrong means you technically do not have a security.txt.
- →It MUST live at /.well-known/security.txt. Not at the root, not in a folder you like better.
- →It MUST be served over https.
- →It MUST be served with Content-Type: text/plain; charset=utf-8.
- →Contact: is mandatory. The spec says this field must always be present.
- →Expires: is mandatory too, and must not appear more than once.
The minimal valid file
You can genuinely stop here. Two lines is a complete, valid security.txt.
Contact: mailto:[email protected]
Expires: 2027-01-01T00:00:00.000ZServing this as an HTML page from your CMS does not count. A page comes back as text/html, and the spec requires text/plain, so a well-formed file at the right URL still fails on the content type.
Expires is the field everyone misses
Expires was added in RFC 9116, later than the rest. Most of the guides, generators and examples floating around predate it, so a huge number of files in the wild are missing it entirely and are therefore invalid.
The spec also recommends the date be less than a year in the future. That is deliberate. It forces the file to be looked at again. A contact address that was accurate in 2023 is worth very little in 2026, and the whole point is that someone can actually reach you.
So this is a file with an upkeep cost. Put a reminder in the calendar. And be clear: an expired security.txt is a finding in its own right. It is not neutral. It is a signed statement that your own contact details are stale.
The optional fields
Once the two required fields are in place, the spec offers a few extras. None are required, and a short honest file beats a long aspirational one.
- →Encryption points to a key so reports can be sent to you privately.
- →Canonical states the URL this file is meant to live at.
- →Policy links to your disclosure policy, so researchers know the rules before they start.
- →Preferred-Languages saves everyone a translation round trip.
- →Acknowledgments credits the people who have reported things before.
- →Hiring links to security roles, which is oddly effective given who reads this file.
- →CSAF points to machine-readable advisories, if you publish them.
Whether you can even do this
This is where it gets frustrating. Hosting the file needs the ability to serve a real file at a real path, and some platforms simply do not give you that.
At the time of writing, Shopify, Wix and Squarespace do not let you host it. On those platforms the path is handled by the platform before your site ever sees the request, and no amount of clever routing displaces it. That is not your fault and it is worth saying plainly.
BigCommerce, Webflow, WordPress and any custom server can all do it, each with their own method and their own gotchas.
One warning that applies everywhere: never blanket-block or blanket-redirect the whole /.well-known/ directory to force this to work. Certificate renewal uses that same directory, and you will break your SSL certificate instead.
Run a free check to see whether yours is present, valid and in date.
We have step by step instructions for every major platform, including the ones that will not let you.
See how to add security.txt on your platform