Implementing security.txt: A Practical Guide
RFC 9116 standardizes security contact information, but many implementations get the details wrong. Learn what you need to know for proper implementation.
https://responsibledisclosure.io/media/blog/featured_images/security-txt.jpg
RFC 9116 standardizes security contact information, but many implementations get the details wrong. Learn what you need to know for proper implementation.
RFC 9116 standardizes how organizations should publish security contact information. Despite being a simple text file, many implementations get the details wrong. This guide covers what you need to know.
The security.txt standard provides a consistent way for security researchers to find contact information when they discover vulnerabilities. It's a machine-readable file placed at /.well-known/security.txt on your domain.
The specification is intentionally minimal. A basic security.txt file contains just a few fields, but those fields have specific requirements that are often overlooked.
Only one field is strictly required: Contact. Everything else is optional, though recommended. A minimal valid file looks like this:
Contact: mailto:[email protected]
Expires: 2026-12-31T23:59:59Z
The Expires field isn't technically required by the specification, but it's strongly recommended. Without it, researchers don't know if the contact information is still valid.
The Expires field must use RFC 3339 format: YYYY-MM-DDTHH:MM:SSZ. I regularly see formats like 12/31/2026 or 2026-12-31, neither of which are valid. The correct format includes the full timestamp with timezone indicator.
If you use a web form for contact, it must be HTTPS. HTTP URLs are not allowed by the specification. This ensures researchers are contacting you over a secure channel.
The file must be at /.well-known/security.txt. Putting it at /security.txt violates the specification. Both locations are allowed, but the well-known location is required as the primary source.
Beyond the minimum, several optional fields improve usability. The Preferred-Languages field tells researchers which languages your team speaks, like Preferred-Languages: en, de, fr. This helps researchers report issues in a language your team can understand.
The Canonical field specifies where this file should be found: Canonical: https://example.com/.well-known/security.txt. This prevents confusion when your security.txt is mirrored or cached elsewhere.
The Policy field links to your full vulnerability disclosure policy. This is where you explain your disclosure timeline, what's in scope, and any rules researchers should follow. Most organizations find this more useful than cramming everything into security.txt itself.
The specification allows PGP signatures, but in practice they create more problems than they solve. Most researchers don't verify the signatures, and maintaining valid PGP keys requires ongoing work that few security teams prioritize.
If you do sign your security.txt, make sure your key doesn't expire before your security.txt expires. I've seen files where the signature expires six months before the Contact field, which defeats the purpose entirely.
Set your expires date based on how often you can realistically review and update the file. One year is common, but six months is safer if your security contact changes frequently. Corporate email addresses get reassigned, teams reorganize, and security responsibilities shift. Regular review catches these changes before researchers start sending reports to inactive addresses.
When the expires date approaches, update the file with a new date. Don't let it expire. Expired security.txt files are worse than no security.txt file because they signal neglect.
After creating your security.txt, visit https://yourdomain.com/.well-known/security.txt and verify it loads correctly. Check the syntax at https://securitytxt.org/, a community validator that catches common errors. Verify all URLs work and use HTTPS. Confirm the date format is correct. Most importantly, test that email addresses actually reach your security team.
Your web server should serve security.txt with Content-Type: text/plain; charset=utf-8. Most servers do this automatically for .txt files, but verify it with curl -I https://yourdomain.com/.well-known/security.txt. The response should include the correct Content-Type header.
Here's a complete, properly formatted security.txt that includes all recommended fields:
Contact: mailto:[email protected]
Contact: https://example.com/security-report
Expires: 2026-12-31T23:59:59Z
Preferred-Languages: en, de
Canonical: https://example.com/.well-known/security.txt
Policy: https://example.com/security-policy
Acknowledgments: https://example.com/security-acknowledgments
Notice you can specify multiple Contact fields. This gives researchers options if one channel doesn't work for them.
Set a calendar reminder for one month before your expires date. This gives you time to review and update the file before it expires. Check that contact addresses still work, that your policy URL hasn't changed, and that your team still speaks the languages you've listed.
If your security contact changes, update security.txt immediately. Researchers following the specification will use this as their primary contact method. Sending reports into the void because your security.txt is outdated wastes everyone's time.
The specification doesn't define what happens after a researcher contacts you. It doesn't specify response times, disclosure timelines, or bounty payments. Those belong in your full security policy document, linked from the Policy field.
Think of security.txt as a signpost. It tells researchers where to send reports, but the actual vulnerability disclosure process is separate. Don't try to cram your entire security policy into this file.
Major organizations including Google, GitHub, and Amazon have implemented security.txt. Browser vendors are starting to look for it when users report security issues. Some vulnerability scanners now check for its presence as a basic security hygiene indicator.
The implementation cost is minimal. It's literally a text file that takes ten minutes to create and host. The value is clear: researchers know exactly how to reach you when they find problems. In a world where finding the right security contact often involves detective work, this standard solves a real problem.
A technical comparison of vulnerability disclosure approaches from security.txt to full bug bounty platforms. Understanding the security trade-offs at each maturity level.
Clear scope in your vulnerability disclosure policy determines what researchers should test. Get it wrong and you'll discourage valid research or deal with unwanted testing.
GDPR creates obligations around data breaches that intersect with vulnerability management. Understanding this intersection prevents compliance problems.
Get the latest security research insights and vulnerability disclosure best practices delivered to your inbox.