security.txt Validator

Fetch a site's security.txt and check the security contact it publishes against RFC 9116.

Secure server processingWeb & SEOWorkingNo account needed

What this tool does

security.txt Validator takes the address of a site and asks the OmniKitly processing service to request /.well-known/security.txt from that origin. Only the scheme, host and port of what you type are used — any path or query is discarded — and when that request comes back 404 the older top-level /security.txt is tried once as a fallback. The service returns the file's "Field: value" lines grouped under their field names, together with the final URL after redirects and the HTTP status, and hands that JSON back as a download beside the report.

The grouped fields are then checked against RFC 9116, and the check goes well past the two required fields. Contact and Expires must both be present. Contact has to be an https:, mailto: or tel: URI, so a bare email address is reported as an error with the mailto: form spelled out for you. Acknowledgments, Canonical, Encryption, Hiring, Policy and CSAF must be https URIs, with dns: and openpgp4fpr: accepted only for Encryption. Expires must be an ISO 8601 timestamp, becomes an error once it has passed, and draws a warning beyond 366 days. Preferred-Languages must be a list of well-formed tags. Expires and Preferred-Languages may each appear only once, a second copy is an error, and any field name outside the registered nine is flagged as one a reader will ignore. Missing Policy, Canonical and Preferred-Languages fields come back as notes rather than faults.

What the report cannot tell you is shaped by the fetch. The service parses the file into fields before the validator ever sees it, so comment lines, blank lines, lines that are not "Field: value" at all and fields left with an empty value are dropped in transit and never raise the errors the validator holds for them. The line numbers in the table are positions in that regrouped list, not lines in the published file, and the original order of interleaved fields is gone. The PGP armour is stripped as well, so a correctly signed file still collects the note saying it is not signed; the signature itself is never verified, and the Content-Type the server replied with is not recorded anywhere. When the exact bytes matter, read the downloaded security-txt.json.

The fetch is not something a browser tab can do — a cross-origin request for someone else's /.well-known/ path would be blocked — so the address is sent to the processing service over an encrypted connection and the request is made from there under OmniKitly's own user agent. The security-txt.json and the job record are removed together once the retention window expires, six hours by default. Addresses resolving to loopback, private, carrier-grade NAT or link-local ranges are refused, as are localhost and .local, .internal, .lan and .home hostnames and any URL carrying a username and password, so an intranet host cannot be probed through it.

How to use it

  1. Enter the site address. A full URL with the scheme in front, such as https://example.com. A bare hostname is rejected as an invalid URL before anything is fetched, and a path is ignored — the request always goes to the origin's well-known location.
  2. Let the service fetch the file. Up to five redirects are followed and each hop is re-checked against the same address rules. Reading stops at 64 KB, and a hop that has not answered in about fifteen seconds is abandoned.
  3. Start with the verdict line. A file that was found comes back as "Valid under RFC 9116" or as a count of errors and warnings, each finding naming the field it came from. If the file is absent, the status was not 200, or nothing parsed as a field, the raw JSON is shown in place of a validation report.
  4. Check the fields against what you published. Contact, Expires, Policy, Encryption, Canonical, Acknowledgments and anything else the file declares are listed in a table with their values, so a stale contact or a policy URL that has since moved is visible at a glance.

Processing & privacy

Secure server processing. This operation requires temporary server processing.

Common use cases

Confirming a file you have just published

The check reads what the origin serves right now, so a rewrite rule, a CDN path or a redirect that sends /.well-known/ somewhere unexpected shows up as a non-200 status and a raw JSON dump instead of a clean report.

Catching an Expires date that has lapsed

Expires is required and is the one part of the file that goes stale on its own. A date in the past is an error that counts the days since it passed; one set more than 366 days out is a warning that the contact details will drift.

Finding out where to report a bug in someone else's site

Point it at their domain and the Contact and Policy values come back — the security contact the organisation publishes for disclosure, rather than a support address that will not route a vulnerability report.

Auditing the domains you are responsible for

Every run leaves behind the JSON it was built from, naming the final URL and status, so an apex host, its www counterpart and an old brand still pointed at your infrastructure can each be checked and kept on file.

Questions

Can I paste the contents of a security.txt file?
Not today. The box is labelled as though you could, and the sample button fills it with a file, but whatever is in it is sent as the address to fetch — so pasted contents come back as "That is not a valid URL". Give it a domain that serves the file instead.
Is anything of mine sent anywhere?
The address is. The fetch runs on the OmniKitly processing service, so the URL travels there over an encrypted connection, the request is made from that machine, and the report and job record are deleted together when the retention window passes. The file being read is public either way — anyone on the internet can request it.
Does it verify the PGP signature?
No, and it cannot even tell you that a file is signed. The armour lines are stripped on the way back, so a properly signed file still collects the note saying it is unsigned. Verifying a signature needs the publisher's key and is a separate exercise.
Where is the file supposed to live?
At https://yourdomain/.well-known/security.txt, served over https as text/plain with a UTF-8 charset. The top-level /security.txt is only tried here when the well-known path returns a 404, because RFC 9116 keeps that older location for compatibility rather than as the place to publish. Whether your server sent the right Content-Type is not something this report records.
Does a clean result mean the file is perfect?
It means the nine registered fields, their URI schemes, the Expires timestamp and the language tags all held up. It says nothing about the signature or the Content-Type, and nothing about what was dropped before the checks ran — comments, blank lines, empty values and malformed lines never reach them.
Can I check a staging site or an internal host?
No. The hostname must resolve to a public address. Loopback, private, carrier-grade NAT and link-local ranges are refused, along with localhost and .local, .internal, .lan and .home names, and a URL with credentials embedded in it is rejected outright.
What if the site is slow, or the path serves something enormous?
Each hop is given up on after roughly fifteen seconds, and reading stops at 64 KB. A real security.txt is a handful of lines, so reaching that ceiling usually means the path is serving a page rather than the file.

Related tools