DEV Community

Cover image for How to Add a security.txt File to Your Website in 5 Minutes (With a Generator)
Roxroy
Roxroy

Posted on

How to Add a security.txt File to Your Website in 5 Minutes (With a Generator)

If you’re running a website in 2026, you probably care about security.

You might have HTTPS, HSTS, CSP, maybe even a bug bounty program. But there’s a tiny text file most sites still miss:

/.well-known/security.txt

It’s a simple file that tells security researchers how to contact you if they find vulnerabilities on your site.

In this post, I’ll explain:

  • What security.txt is (in human words)
  • Why it matters even if you don’t run a big security team
  • What goes inside the file
  • How to generate one in a couple of minutes using a browser-based tool
  • How to deploy it on common setups (static site, Laravel/PHP, .NET/IIS, etc.)

No security team required. Just you, a text file, and a few minutes.


What is security.txt?

security.txt is a proposed standard (RFC 9116) for publishing security contact information for your website.

The idea is similar to robots.txt:

  • robots.txt → tells search engines how to crawl your site
  • security.txt → tells security researchers how to report vulnerabilities

It normally lives at:

/.well-known/security.txt
Enter fullscreen mode Exit fullscreen mode

on your main domain. For example:

https://example.com/.well-known/security.txt
Enter fullscreen mode Exit fullscreen mode

Inside that file, you list things like:

  • Who to contact (email or URL)
  • A link to your security policy
  • Optional: your PGP key, acknowledgements page, hiring info, etc.

So when someone finds a bug and wants to report it responsibly, they don’t have to guess. They just go to that URL and follow the instructions.


Why should you care as a “normal” developer?

You don’t need to be a security engineer to benefit from security.txt.

1. It reduces friction for responsible disclosure

Many security issues go unreported because people don’t know where to report them:

  • No security@ email address
  • No bug bounty program
  • No clear disclosure policy

A security.txt file says:

“If you find something, here’s exactly how to tell us.”

That alone can be the difference between a quiet, responsible report and an angry social media thread.

2. It shows you take security seriously

Even if you’re a small SaaS, indie project, or side project, adding security.txt sends a signal:

  • You’ve thought about security, at least to the point of defining a contact and a process.
  • You’re open to hearing from researchers and power users.

You don’t need a massive program. A simple line like:

Policy: https://example.com/security-policy
Contact: mailto:security@example.com
Enter fullscreen mode Exit fullscreen mode

is enough to look much more mature than “no info at all”.

3. It’s cheap “security hygiene”

Some security improvements are complex and time-consuming.

This one is not.

  • A small text file
  • Served over HTTPS
  • Updated once in a while when contacts change

It’s one of those “10 minutes now, potential life saver later” tasks.


What goes inside a security.txt file?

The standard defines several fields. You don’t need all of them, but here are the most common ones:

Required-ish (strongly recommended)

  • Contact – How to reach you about security issues
  Contact: mailto:security@example.com
  Contact: https://example.com/security-contact
Enter fullscreen mode Exit fullscreen mode
  • Expires – When this file should be considered out of date
  Expires: 2026-01-01T00:00:00Z
Enter fullscreen mode Exit fullscreen mode

Very useful

  • Policy – Your security/vulnerability disclosure policy
  Policy: https://example.com/security-policy
Enter fullscreen mode Exit fullscreen mode
  • Acknowledgments – Where you thank researchers (if you have a hall of fame)
  Acknowledgments: https://example.com/security-acknowledgments
Enter fullscreen mode Exit fullscreen mode
  • Encryption – Public key for sending encrypted reports
  Encryption: https://example.com/pgp-key.txt
Enter fullscreen mode Exit fullscreen mode
  • Hiring – If you’re hiring for security roles
  Hiring: https://example.com/careers
Enter fullscreen mode Exit fullscreen mode
  • Canonical – The canonical URL of this security.txt
  Canonical: https://example.com/.well-known/security.txt
Enter fullscreen mode Exit fullscreen mode

You can also add comments with #:

# Security contact for Example Corp
Contact: mailto:security@example.com
Policy: https://example.com/security-policy
Expires: 2027-01-01T00:00:00Z
Enter fullscreen mode Exit fullscreen mode

That’s it. It’s just a structured text file.


The manual way vs. the generator way

You can create a security.txt file by hand:

  1. Read the RFC (or various blog posts)
  2. Decide which fields to use
  3. Copy/paste some examples
  4. Try not to mess up the syntax
  5. Remember to set a valid future Expires date
  6. Save the file, move it to the right path, deploy, test…

It’s not rocket science, but it’s also the sort of thing you’ll probably do once and forget how you did it next year when you need to update it.

That’s why I prefer using a generator.


Using a browser-based security.txt generator

There are several generators out there. I built one into CodersTool because I kept needing simple “one-off” web utilities while working on various SaaS projects.

The flow is basically:

  1. Fill out a small form in your browser
  2. Get a valid security.txt snippet
  3. Download or copy the text
  4. Drop it into your site at /.well-known/security.txt

No login, no project setup, no CLIs.

Example workflow (CodersTool-style)

You can follow this even if you use a different generator – the steps are the same.

  1. Open the generator
    Go to the security.txt generator on CodersTool.

  2. Fill in the key fields

  • Contact – Most people use a dedicated mailbox like security@yourdomain.com
  • Policy – If you don’t have a detailed policy, even a short page explaining “please email us, don’t publicly disclose immediately” is better than nothing.
  • Expires – Pick a date 6–12 months in the future, so you’re forced to review it periodically.
  • Optional: Acknowledgments, Encryption, Hiring, Canonical.
  1. Generate the file The tool will spit out a security.txt that looks something like:
   # security.txt for Example SaaS
   Contact: mailto:security@example.com
   Policy: https://example.com/security-policy
   Acknowledgments: https://example.com/security-acknowledgments
   Expires: 2027-01-01T00:00:00Z
   Canonical: https://example.com/.well-known/security.txt
Enter fullscreen mode Exit fullscreen mode
  1. Copy + save locally Save it as security.txt on your local machine.

Next step: deploy it.


Deploying security.txt on different kinds of sites

The goal is always the same:

Serve the file from https://yourdomain.com/.well-known/security.txt

How you get it there depends on your stack.

1. Static site / GitHub Pages / plain hosting

If your site is just static HTML/CSS/JS:

  1. Create a folder called .well-known at the root of your site:
   /your-site-root/
     index.html
     ...
     /.well-known/
       security.txt
Enter fullscreen mode Exit fullscreen mode
  1. Put your generated security.txt inside it.
  2. Deploy / upload as you normally would.

Test it:

https://yourdomain.com/.well-known/security.txt
Enter fullscreen mode Exit fullscreen mode

You should see your text file in the browser.

If you’re using a static site generator (Hugo, Jekyll, etc.), you can usually add .well-known/security.txt to your public/dist output via a static files folder.

2. Laravel / PHP apps

For a typical Laravel app:

Option A – Serve it as a static file

  1. Create public/.well-known/ if it doesn’t exist.
  2. Add your security.txt inside:
   /public/
     index.php
     ...
     /.well-known/
       security.txt
Enter fullscreen mode Exit fullscreen mode

Laravel will happily let the web server serve this file directly.

Option B – Route-based (if you really want it dynamic)

If you prefer to generate it dynamically (e.g., from config or DB), you can add a route:

// routes/web.php
Route::get('/.well-known/security.txt', function () {
    $content = <<<TXT
# security.txt for Example SaaS
Contact: mailto:security@example.com
Policy: https://example.com/security-policy
Expires: 2027-01-01T00:00:00Z
TXT;

    return response($content, 200)
        ->header('Content-Type', 'text/plain');
});
Enter fullscreen mode Exit fullscreen mode

But honestly, a static file is usually enough.

3. ASP.NET / IIS apps

For .NET apps hosted on IIS:

  1. In your site’s root folder, create a .well-known directory.
  2. Drop security.txt into it.
  3. Ensure IIS is configured to serve .txt from that path (it usually is by default).

File structure:

/wwwroot/
  web.config
  ...
  /.well-known/
    security.txt
Enter fullscreen mode Exit fullscreen mode

If you’re running ASP.NET Core with Kestrel + reverse proxy:

  • Put .well-known/security.txt into wwwroot, or
  • Map a route in your app to return the text file.

4. Behind a CDN or reverse proxy

If you sit behind something like Cloudflare, Fastly, etc.:

  • Make sure the upstream origin serves /.well-known/security.txt.
  • Check that your CDN isn’t blocking or rewriting that path.
  • If your CDN has its own security.txt feature, decide whether to:

    • Use theirs directly, or
    • Use your origin security.txt and let the CDN just pass it through.

In many cases, you can still generate the content using a tool and then paste it into whatever config your CDN expects.


How to verify your security.txt file

Once you’ve deployed, check:

  1. Direct browser test Open:
   https://yourdomain.com/.well-known/security.txt
Enter fullscreen mode Exit fullscreen mode

in your browser and confirm:

  • It’s accessible over HTTPS
  • It’s not being redirected somewhere weird
  • The content matches what you generated
  1. Check headers Use your browser dev tools or curl:
   curl -I https://yourdomain.com/.well-known/security.txt
Enter fullscreen mode Exit fullscreen mode

Look for:

  • HTTP/2 200 (or similar success code)
  • content-type: text/plain (ideal, though not strictly mandatory for humans)
  1. Use an online validator There are validators that will:
  • Fetch your security.txt
  • Check required fields
  • Flag issues like invalid Expires dates or unreachable URLs

(Just search “security.txt validator” and plug in your domain.)


Common mistakes to avoid

A few gotchas that pop up a lot:

  • Wrong path
    https://example.com/security.txt is not the standard path.
    Use https://example.com/.well-known/security.txt.

  • No HTTPS
    The file should be available over HTTPS. Serving it only over HTTP is discouraged.

  • Expired Expires date
    If the Expires value is in the past or very soon, tools may treat your file as stale.

  • Unmonitored email address
    Don’t point Contact to an inbox nobody checks. Even if you can’t reply to every report, someone should at least see them.

  • Invalid Contact
    Ensure the email address you list (security@ or admin@) actually goes to a real inbox that is monitored.

  • Forgetting to update when things change
    If your security contact moves, or your policy URL changes, update the file. That’s one reason having a generator handy is nice — you can recreate a clean file quickly.


Where to go from here

You don't need a SOC 2 audit or a dedicated CISO to take security seriously. You just need to be reachable.

If you own or manage a website, adding security.txt is one of those small, high-leverage tasks:

  • It takes minutes.
  • It helps people help you.
  • It signals that you give a damn about security.

You can:

  1. Open a security.txt generator (like the one on CodersTool).
  2. Fill in your contact, policy, and expiry.
  3. Save it as /.well-known/security.txt on your site.
  4. Verify it in the browser and with a quick validator.

Then you can forget about it… at least until your next Expires date reminder.

If you haven't created one yet, head over to the CodersTool Generator, create your snippet, and push it to production today.

Top comments (0)