security.txt: Give Researchers a Simple Way to Report Bugs (RFC 9116)
When a researcher finds a bug in your app, they need a way to reach you before it goes public. A security.txt file gives them that path · here is how to add one.
By Paula C · Kraftwire Software
· 7 min readKey takeaway
If a security researcher finds a vulnerability in your app, they need a way to tell you before it goes public. A `security.txt` file · a plain-text file at `/.well-known/security.txt` · gives them that path. It is a small, standardized file defined by RFC 9116, and adding one is one of the cheapest security wins you can ship this week.
The problem: a researcher finds a bug and can't reach you
Picture this. Someone pokes at your app, notices your API leaks user emails, and wants to do the right thing. They look for a "report a security issue" link. There isn't one. Your contact page routes to sales. Your support email auto-replies with a ticket number and silence.
So what happens next? A few things, none of them good. The researcher gives up and the bug stays live. Or they post it publicly to get your attention, which now puts your users at risk. Or they message you on social media and you assume it's spam. The vulnerability was found by a good-faith person who wanted to help, and your lack of a clear channel turned that into a worse outcome.
This is the exact gap `security.txt` closes. It answers one question for the researcher · "where do I send this?" · in a machine-readable, predictable place.
What security.txt actually is
`security.txt` is a standard from RFC 9116. It is a plain-text file that lives at a fixed, well-known location on your site and lists how to contact you about security issues, plus a few optional pointers like your disclosure policy.
That's the whole idea. It isn't code, it isn't a service, and it doesn't scan anything. It's a signpost. Researchers (and automated tools that look for these files) check the well-known path, read your contact method, and use it. Because the format and location are standardized, they don't have to guess.
The fields
RFC 9116 defines a set of fields. Two are required; the rest are recommended and worth including.
`Contact` (required) · how to reach you. A URL (like a report form) or a `mailto:` email address. You can list more than one, in order of preference. This is the one field that makes the file useful, so it's mandatory.
`Expires` (required) · a date and time after which the file's data should be considered stale. RFC 9116 requires this field so that an abandoned file doesn't mislead researchers years later. Keep it in the future and update it before it lapses.
`Encryption` (recommended) · a link to your public encryption key, so a researcher can send you sensitive details securely. Point to the key itself, not just a fingerprint.
`Policy` (recommended) · a link to your vulnerability disclosure policy, so researchers know the rules of engagement before they start.
`Acknowledgments` (recommended) · a link to a page thanking researchers who have reported issues. Recognition is often the only reward good-faith reporters get, and it encourages more.
`Preferred-Languages` (recommended) · the languages you'd like reports written in, as a comma-separated list of language tags. It sets expectations; it doesn't obligate anyone.
`Canonical` (recommended) · the canonical URL where this `security.txt` lives. It tells readers which location is authoritative, which matters if your file gets mirrored.
`Hiring` (optional) · a link to your security-related job openings. A nice touch, unrelated to reporting bugs.
A complete example
Here's a short, valid file with the required fields and the most useful optional ones:
Contact: mailto:security@example.com
Contact: https://example.com/security/report
Expires: 2027-01-01T00:00:00.000Z
Encryption: https://example.com/pgp-key.txt
Policy: https://example.com/security/policy
Acknowledgments: https://example.com/security/thanks
Preferred-Languages: en, pt
Canonical: https://example.com/.well-known/security.txt
Hiring: https://example.com/careers
Swap in your real contact and URLs, drop the fields you don't have yet, and you have a working file. `Contact` and `Expires` are the two you cannot skip.
Where it goes, and how to keep it valid
Location matters, because researchers and tools look in one specific place.
Put the file at `/.well-known/security.txt`. That well-known path is the canonical location defined by the spec. A file at `/security.txt` (site root) is tolerated as a legacy fallback, but the well-known path is the one to use.
Serve it over HTTPS. The file often points to encryption keys and policies; serving it over a secure connection keeps those pointers trustworthy.
Serve it as `text/plain`. It's a text file, not HTML · make sure your host isn't wrapping it in a page template.
Two maintenance habits keep it honest. First, keep `Expires` current. An expired file signals that the data may no longer be accurate, which defeats the purpose · set a reminder to refresh it before the date passes. Second, you can sign the file with an OpenPGP signature so researchers can verify it's genuinely from you; if you do, keep the signature updated whenever you edit the file.
Pair it with a lightweight disclosure policy
`security.txt` tells a researcher how to reach you. A short vulnerability disclosure policy tells them what happens next · what's in scope, that you won't pursue legal action against good-faith research, and roughly how long you'll take to respond. It doesn't need to be a legal epic. A single page is plenty for most indie apps, and your `Policy` field links straight to it. Together, the file and the policy turn "I found something" into a smooth, predictable exchange.
While you're tightening things up, this pairs naturally with a broader [web app security audit checklist](/blog/security-audit-checklist) · the disclosure channel is one item; the rest of the checklist covers the bugs researchers might actually report.
Set realistic expectations
`security.txt` invites good-faith reports. That's its job, and it does it well. What it is not: a bug bounty, a guarantee anyone will look, or a replacement for actually fixing issues. It doesn't pay researchers or promise rewards · if you want that, a bounty program is a separate, bigger commitment. Think of `security.txt` as opening the door and putting up a sign. Whether people walk through depends on your app and your responsiveness, but without the door, the good-faith reports never arrive at all.
Ship it, then check it
Adding `security.txt` takes about ten minutes and removes a real failure mode · silent, unreported, or public vulnerabilities. Write the file, put it at `/.well-known/security.txt`, serve it over HTTPS, and set an `Expires` date you'll actually keep current.
Then confirm it's right. Our free security.txt Validator at [/tools/security-txt](/tools/security-txt) checks that the file is present, in the correct location, has the required fields, and hasn't expired. It's part of our full set of free tools at [/tools](/tools).
And when you're ready to look past this one file, run a full scan of your app at [simplyscan.io](https://simplyscan.io) to catch the security and speed issues that a signpost alone won't find.