Self-hosted service
sensepost/gowitness avatar
sensepost/gowitness

gowitness: the compose file ships a working basic auth password, and the Docker image is a Chrome image

🔍 gowitness - a golang, web screenshot utility using Chrome Headless

4,560 stars455 forksGoGPL-3.0

At a glance

What is it?
gowitness is SensePost's GPLv3 Go screenshot utility that drives headless Chrome, latest release 3.2.2 in October 2026, whose deployment example publishes a report server behind Traefik with a bcrypt hash for the password gowitness checked into the repository. Its runtime image is built FROM chromedp/headless-shell, so Chrome is the base image rather than a dependency.
Who is it for?
gowitness fits a reconnaissance workflow where a list of hosts needs visual confirmation rather than a status code, since it takes screenshots and optionally keeps the request log, console logs, headers and cookies it gathered along the way, then serves the result through a web viewer with an API. Three things to weigh before you deploy the report server.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 17 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • sensepost/gowitness4,560 ★ · +43
Star history
Repository2026-09-232026-11-14
sensepost/gowitness4.5k4.6k

43 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The compose file documents a working password for the report server

This is the section to read before you copy anything. The deployment example runs the report server through Traefik with a router rule matching the host gowitness.local, on the web-secure entry point, with TLS from a cert resolver named default and a basic auth middleware applied. The basic auth middleware is configured inline with a realm of gowitness and a bcrypt hash, and the file carries a comment above it giving the credentials that hash corresponds to: gowitness:gowitness. The comment also tells you how to change it, that you can set it statically or use something like trauth to manage it, that you should use htpasswd to generate a hash for a different password, and that you need to escape a dollar sign with another dollar sign for Docker Compose. So the example is not a placeholder: it works, with a guessable password, and the note is there so a reader knows what to do about it. Traefik itself is pinned to 3.1, uses the docker provider with exposedByDefault disabled, listens on 443, and mounts the Docker socket read only.

The runtime image is Chrome, with three symlinks onto one binary

Read the final stage of the Dockerfile and the architecture is obvious. The runtime is not a Go image with Chrome installed, it is built FROM docker.io/chromedp/headless-shell:stable. Into that image the compiled gowitness binary is copied to the local bin path, tini and ca-certificates are installed with no recommended packages, and then one binary is symlinked to three names: google-chrome, chromium and chromium-browser. That is what makes the tool work with whatever Chrome path a configuration expects. The build is a three-stage affair: a Node 24 slim stage builds the web interface with npm ci and npm run build, a golang:1-bookworm stage generates the API documentation with swag and compiles the binary with the git hash, the Go build environment and the UTC build time stamped into the version package through linker flags, and then the third stage assembles the runtime. The image exposes 7171, declares a volume at the data directory, sets that directory as the working directory, and uses tini as its entrypoint so the process gets a real init.

Two browser automation libraries, and the credits list names one of them

The credits section names nine projects and links the go.mod file as the source of that list: chi, chromedp, go-rod, cobra, gorm, glamour, go-nmap, wappalyzergo and goimagehash. The module file is a longer list than that, and the difference is instructive. Both browser automation libraries are direct requirements, chromedp at a released version and go-rod at a released version, so the tool ships two ways of driving a browser rather than one, and the README's description of it as using Chrome Headless does not say which it prefers. The rest of the direct requirements explain the other features. The router is chi with its CORS companion. The command line is cobra, which is where the subcommand shape comes from, and the README's note that you can add -h anywhere to read about a flag is a cobra convention. The output formatting glamour and lipgloss are terminal renderers. The go-nmap dependency is pinned to a pseudo-version dated 2019, which is the old one, and it is what makes the scan list accept Nmap results. wappalyzergo is the technology fingerprinting step and goimagehash is perceptual image hashing, which is how a screenshot is compared to others rather than byte for byte.

Three database backends are compiled in, not only SQLite

The README names SQLite in the feature list, as one of the output formats alongside jsonlines and csv, and in the quick start as the destination for the database flag. The module file has three GORM drivers as direct requirements: a pure Go SQLite driver, plus MySQL and Postgres. So the report server is not tied to a local file even though the example uses one. That has a practical consequence. The compose example passes a file URI pointing at a SQLite file inside the data volume, which is the simple deployment, but the same binary can be pointed at a MySQL or Postgres instance, and a multi-operator setup would want that rather than a SQLite file mounted into a container. The JSON schema for the API is generated by swag from annotations rather than maintained by hand, and the Makefile has a separate target that regenerates both the schema and the formatting.

The Makefile builds windows/arm64 while the README hedges on Windows

Here is a small inconsistency worth knowing if you are picking a release artefact. The README says that both Linux and macOS are supported, with Windows support mostly working. The Makefile lists the cross compilation targets and among them are darwin/amd64, darwin/arm64, linux/amd64, linux/arm64, linux/arm, windows/amd64 and windows/arm64, with CGO disabled for all of them. So the build matrix claims a Windows ARM64 binary that the documentation does not promise works. The default target is a chain: clean, test, frontend, api-doc, build and integrity, where build produces every platform and integrity runs a checksum over the build directory. The version in each artefact's file name is read out of a version file by grepping for the version assignment, so the number comes from source rather than from a tag, and the artefact name carries the version, the operating system and the architecture. Cross compilation with CGO disabled is consistent with shipping against a pure Go SQLite driver rather than a cgo one.

Install is go install, and a first scan writes a database and a screenshot

The quick start is two commands and one assumption. The assumption is that your GOBIN path is in your shell PATH, which is the usual caveat for a Go tool installed with go install:

text
go install github.com/sensepost/gowitness@latest

Otherwise you take a platform specific release binary or compile from source. Then the first scan writes the results to a SQLite database and the screenshot to a local directory:

text
gowitness scan single --url "https://sensepost.com" --write-db

The subcommand structure is two words, a verb then a target type, which is why the single target form reads the way it does. The README is candid that the flag surface is large, telling you there are many flags and scan types and to add -h anywhere, and it points at the wiki for anything beyond the quick start rather than documenting scan types in the repository. So the documentation strategy is a one command start plus a wiki, and the repository itself is where you look to see how the tool is built rather than how to drive it.

GPLv3 with a commercial licence offered separately

The licence section is two sentences and the second one is the interesting one. gowitness is licensed under the GNU General Public v3 License. Then: permissions beyond the scope of this license may be available from the vendor's contact page. That is an offer of further permissions stated in the README, and it is the arrangement to look at if you need to embed the tool in something you cannot release under GPLv3. The other credits are worth noting for provenance. The project is from SensePost, a security company, and the README carries a link to an individual maintainer's social account. It also links a docker workflow badge alongside it, so there is a container build path in continuous integration, and the repository tree contains both a Dockerfile and a compose file plus an images directory for the README's own screenshots. The advanced documentation, including installation detail beyond go install, lives in the wiki rather than in the repository.

Editorial conclusion

gowitness fits a reconnaissance workflow where a list of hosts needs visual confirmation rather than a status code, since it takes screenshots and optionally keeps the request log, console logs, headers and cookies it gathered along the way, then serves the result through a web viewer with an API. Three things to weigh before you deploy the report server. The compose example is a working configuration with default credentials in it, the realm is gowitness and the documented account is gowitness with the password gowitness, so change both before exposing it. It also sits behind a reverse proxy with TLS terminated at the proxy, so the exposure you are managing is the proxy's. And on licensing, the project is GPLv3 with an offer of permissions beyond that scope from SensePost on request, which is the arrangement to check if you intended to keep the tool out of a commercial product. The last push is dated 2026-10-29.

Frequently asked questions

How do I install Gowitness?

With `go install github.com/sensepost/gowitness@latest`, assuming your GOBIN path is in your shell PATH. Otherwise take a platform specific release binary or compile from source. There is also a container path: the Dockerfile builds a Go binary and puts it into a chromedp/headless-shell base image, and the compose example runs the report server behind Traefik.

how to use gowitness

A first scan writes results to a SQLite database and the screenshot to a local directory: `gowitness scan single --url "https://sensepost.com" --write-db`. The README notes there are many flags and scan types, suggests adding -h anywhere to read about them, and points at the wiki for advanced documentation. Scan targets can be URLs, CIDRs, Nmap results or Nessus results.

what does gowitness do

It takes website screenshots using headless Chrome from the command line, and optionally saves what it gathered along the way, including a request log, console logs, headers and cookies. Results can be written to a SQLite database, jsonlines or CSV, and if you saved to SQLite there is a web based results viewer with an API.

which platforms does gowitness support?

Linux and macOS are described as supported, with Windows support mostly working. The Makefile cross compiles for darwin/amd64, darwin/arm64, linux/amd64, linux/arm64, linux/arm, windows/amd64 and windows/arm64 with CGO disabled, and the go.mod file requires Go 1.26.0.

Official sources

  1. Issues
  2. License: GPL-3.0
  3. README
  4. Releases
  5. sensepost/gowitness on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sensepost-gowitness.svg)](https://hysenlabs.com/projects/sensepost-gowitness)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/sensepost-gowitness.svg)](https://hysenlabs.com/projects/sensepost-gowitness)

Was this useful?