REDbot: a linter for what your HTTP responses actually promise
REDbot is lint for HTTP resources.
At a glance
- What is it?
- REDbot fetches an HTTP resource and reports on the semantic and caching layers of the response, from cache-control handling to protocol feature support. It ships as a Python command line tool, a standalone web daemon and an OCI container, and it is aimed at people who need a repeatable answer to whether a response is correct, not just whether it was delivered.
- Who is it for?
- REDbot suits developers and system administrators who need one repeatable check for response semantics and caching headers, and who can run it locally or on a shared internal host to keep request logs inside their own perimeter. It does not suit a team that wants a broad web vulnerability scanner or a load tester, because the checks sit at the HTTP semantic and caching layers only.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What REDbot actually inspects
The project states its purpose in one blunt line: it is lint for HTTP resources. The README then narrows the scope to HTTP resources that are checked for feature support and common protocol problems at the HTTP semantic and caching layers. That phrase does a lot of work. Semantic checks ask whether a response means what the protocol says it means, for example whether a status code carries the headers it is allowed to carry, and caching checks ask whether a response describes its own freshness correctly.
The tooling is aimed at people who already know HTTP and want a second opinion on a response, which is a different audience from people who want a general site check. The topic tags on the project, `http`, `lint`, `linter` and `protocol-analyser`, put it in the same family as header inspection tools rather than in the family of vulnerability scanners.
Two ways to use it are documented. There is a public instance at `https://redbot.org/`, or you can install REDbot locally and run it yourself. The local route matters for anything confidential, because the resource you check is fetched by whichever instance you use, and the README does not describe any data handling policy for the public one.
The lint engine sits in httplint and http-sf
The Python package metadata shows how little of the checking logic lives in the REDbot package itself. The runtime dependencies are `httplint`, `http-sf`, `cryptography`, `Jinja2`, `markdown`, `MarkupSafe`, `netaddr` and `thor`. `httplint` and `http-sf` are the two names that matter for understanding the architecture: they are separate packages by the same author, and the version constraint on `httplint` is a date-based floor of `2026.10.3`, which suggests the lint rule set ships on its own cadence rather than inside REDbot's release notes.
That split has consequences for a team considering the project. Updating REDbot does not necessarily update the rules, and the rules are what you are actually judging your server by. The `thor` dependency provides the command line parsing, `Jinja2` and `markdown` render the report and the web interface, `netaddr` handles address values, and `cryptography` is what makes the Ed25519 signing in Web Bot Auth possible.
The package also defines three console entry points in `pyproject.toml`: `redbot` for the command line, `redbot_daemon` for the web interface as a standalone daemon, and `redbot_gc` for garbage collection. The presence of that third program tells you the daemon can persist test results, and therefore needs a janitor.
One report in three formats
Output selection is a first-class part of the interface rather than a flag buried in a subcommand. By default `redbot` prints a text report for the URL. The `-o` option picks another format: `text_verbose` adds an explanation of each note, and `har` produces an HTTP Archive file. The `-a` flag, spelled `--assets`, makes the `text` and `text_verbose` formats list the resources linked from an HTML response, which is how a reader sees the sub-resources the page pulls in.
The web interface accepts the same format names through a `format` query argument, so `format=text`, `format=text_verbose` and `format=har` are the web equivalents of the command line options. That symmetry is deliberate and useful: a team can point a person at a browser URL and get the same report the CI job produced.
The three formats are not interchangeable. The default text report is the terse one, `text_verbose` is the one that explains itself, and the HAR file is the one you open in a generic archive viewer to inspect the exchange. Choosing the wrong one for the job tends to produce a complaint that REDbot says little, when the requested format was the terse one.
Installing with pipx and running the first check
REDbot needs a current version of Python, and the project metadata requires Python 3.11 or newer. The recommended installation method is `pipx`, which installs each program into its own environment and puts the commands in the pipx binary folder. To get the latest release:
> pipx install redbotTo follow the development branch instead, the README gives a different install target:
> pipx install git+https://github.com/mnot/redbot.gitEither route provides two commands: `redbot`, the command line interface, and `redbot_daemon`, the web interface as a standalone daemon. A first useful run is a single URL argument, for example `redbot https://example.com/`, which prints the text report described above. For a scripted check the format flag matters, because the machine readable artefact here is the HAR file rather than the text report.
If you want the daemon instead of the command line, the README points to `extra/README.md` for sample systemd units and a step-by-step setup, and the project also documents a container route. The daemon is the piece intended for shared use, and it is the piece that needs a configuration file.
The container runs unprivileged and starts with saving disabled
OCI compliant images are published, and running one is short:
> docker run --rm -p 8000:8000 ghcr.io/mnot/redbotThe same command works with Podman, and the daemon inside listens on port 8000. The Dockerfile shows how that is arranged. A build stage installs the package into a virtual environment, and the final image copies only that environment, so the compiler and headers never reach the runtime layer. The image also enables the `en_US` locales, which the daemon needs because it normalises a language setting to a specific locale string.
The security posture is deliberate. The daemon fetches and parses arbitrary remote content, so it runs as an unprivileged `redbot` user with UID 999 and no login shell, and the Dockerfile creates `/var/lib/redbot` owned by that user. Saving tests is off by default. To turn it on you set `save_dir = /var/lib/redbot` in a config file, pass that file as the container command, and mount a named volume at `/var/lib/redbot`. The README is explicit that a bind mounted host directory must be writable by UID 999, which is the most common way a container run of REDbot fails on a shared host.
Web Bot Auth signs only when the origin asks
REDbot can authenticate its outgoing requests using Web Bot Auth, signing them with an Ed25519 key under HTTP Message Signatures, RFC 9421. The point of the mechanism is that an origin can tell a genuine REDbot instance from an impostor. The key is generated as PEM:
> openssl genpkey -algorithm ed25519 -out web-bot-auth-key.pemThe daemon reads two keys from `config.txt`:
web_bot_auth_key = /path/to/web-bot-auth-key.pem
web_bot_auth_directory = https://your-redbot.exampleThe directory is the HTTPS origin where the public key directory is published, and the daemon serves it at `/.well-known/http-message-signatures-directory` as a JWKS. The behaviour that matters most in practice is the default: requests are sent unsigned, and a signature is attached only when the origin challenges for one with a `401`, `403` or `429` response carrying an `Accept-Signature` header, after which REDbot transparently retries the request signed. Signing is therefore opt-in per origin, and the bot does not advertise itself to servers that never asked.
There is one trap. The daemon serves the directory at the origin given by `ui_uri`, and `ui_uri` defaults to `https://redbot.org/`. Enabling signing without setting `ui_uri` to your instance's real public origin would publish the wrong bot identity, which is why the README recommends setting `web_bot_auth_directory` explicitly when the key directory lives elsewhere.
What REDbot will not tell you, and how to live with the licence question
The limits follow from the scope. REDbot checks HTTP semantics and caching, so it is the wrong tool for finding application level bugs, and it will not judge your TLS configuration or the quality of your content. It reports, it does not repair: there is no patch or configuration generator, only notes and an explanation in the verbose format. And because it must fetch the resource, it inherits the network position of wherever it runs, so a check from inside your network and a check from the public instance can legitimately differ.
The project classifies itself as `Development Status :: 4 - Beta` in the package metadata, so treat the interface as still moving. On the other hand the maintenance picture is busy rather than abandoned: the last push was on 2026-10-17, the same day as the v2.7.1 release, and v2.7.0 landed on 2026-10-16 with v2.6.2 following on 2026-09-21. That cadence is worth tracking, because a linter that changes its rules between releases can move a build from green to red without any code changing on your side.
The licence needs a closer look. The package metadata declares `license = "MIT"` and lists `LICENSE.md` as a licence file, but the licence is a custom one that GitHub could not classify, and the LICENSE file holds the real terms. Read `LICENSE.md` before you ship REDbot inside a product, and pin a version rather than tracking the development branch if you need reproducible reports.
Editorial conclusion
REDbot suits developers and system administrators who need one repeatable check for response semantics and caching headers, and who can run it locally or on a shared internal host to keep request logs inside their own perimeter. It does not suit a team that wants a broad web vulnerability scanner or a load tester, because the checks sit at the HTTP semantic and caching layers only. Before adopting it, verify two things: the licence file, since `pyproject.toml` declares MIT while the repository carries a `LICENSE.md` that GitHub could not classify, and the output format you need, since the default text report and the HAR output carry different information. Then check that your deployment sets `ui_uri` correctly before enabling Web Bot Auth.
Frequently asked questions
How do I install REDbot and run my first check?
The recommended method is pipx, which installs the `redbot` command line tool and the `redbot_daemon` web interface. After `pipx install redbot`, running `redbot` against a URL prints a text report, and the `-o` flag switches to `text_verbose` or `har` output.
Can I run REDbot in Docker?
Yes. OCI compliant images are published and the daemon listens on port 8000, so `docker run --rm -p 8000:8000 ghcr.io/mnot/redbot` starts a working instance. The daemon runs as an unprivileged `redbot` user with UID 999, and saving test results is disabled until you set `save_dir = /var/lib/redbot` and mount a volume there.
What is Web Bot Auth in REDbot and when are requests signed?
Web Bot Auth lets REDbot sign its outgoing requests with an Ed25519 key using HTTP Message Signatures, RFC 9421, so an origin can verify the request came from your instance. Requests are sent unsigned by default, and a signature is added only when the origin responds with a `401`, `403` or `429` carrying an `Accept-Signature` header, after which REDbot retries the request signed.
What licence is REDbot released under?
The package metadata declares MIT and names `LICENSE.md` as the licence file, but the project listing records that GitHub could not classify the licence and points to the LICENSE file for the actual terms. Check `LICENSE.md` in the repository before redistributing it.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mnot-redbot)Was this useful?