whoami.filippo.io: an SSH server that reports your GitHub identity back to you
A ssh server that knows who you are. $ ssh whoami.filippo.io
At a glance
- What is it?
- A small Go program that turns SSH public key negotiation into a lookup, using a scraped GitHub key database and the GitHub API to name you.
- Who is it for?
- The trick at the centre of this is narrow and legible: SSH offers a client several public keys before giving up, and a server that accepts keyboard-interactive without a challenge can therefore collect that list without ever being granted access. whoami.filippo.io does exactly that, joins the result against a SQLite copy of GitHub public keys, asks the API for a display name, and closes the shell.
- Can I use it commercially?
- Yes. ISC is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 178 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 October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One ssh command against a server that refuses every key
The pitch fits in a single line. The README calls this a ssh server that knows who you are, and the try-it block is the whole demonstration:
ssh whoami.filippo.ioWhat comes back is a username, a real name pulled from the GitHub API, and a closed terminal. No shell, no files, no command execution. The README pre-empts the obvious objection by publishing both host key fingerprints, an ED25519 and an RSA value, so a client can verify it is talking to the intended host rather than something intercepting the connection.
The repository is correspondingly small. The tree is `.gitignore`, `Dockerfile`, `LICENSE`, `README.md`, `cmd/`, `fly.toml`, `go.mod`, `go.sum` and `server.go`. There is one Go source file, a `cmd/` directory for the entrypoint, and a `fly.toml` that points at Fly.io hosting. The README points readers at `server.go` for the interesting parts, which is a reasonable thing to say about a program this size.
Enumerating client keys during public key negotiation
The mechanism is a property of the SSH protocol rather than a bug in any implementation. When a client authenticates with a public key, it sends the server each key it holds, one at a time, until the server accepts one or the list runs out. A server that never accepts any of them still learns every key offered.
whoami.filippo.io advertises `(publickey,keyboard-interactive)` and leans on both halves. It refuses every public key but records them. Then it accepts keyboard-interactive without sending a challenge, so the client moves past authentication without any password prompt and without any human interaction. A shell and PTY are granted, and at that point the program knows the client's full key set and can go do a lookup.
That last detail is what makes the demo work unattended. Most key-enumeration ideas stall because the server would need to authenticate before it knows who it is talking to. This one resolves identity after the fact, from data the client volunteered during a phase where declining to send keys was the only available objection.
Turning a key into a username with a scraped database
Key material is not a name, so the next step is a join. GitHub lets anyone download a user's public keys, and the README credits Ben Cox with turning that availability into a dataset covering all GitHub public keys. The server matches the collected keys against that dataset, recovers a username, and then asks the GitHub API for the account's real name.
The dependencies in `go.mod` show how that is wired in Go 1.25.0: `golang.org/x/crypto` for the SSH server itself, `github.com/google/go-github/v72` and `golang.org/x/oauth2` for the API call, `zombiezen.com/go/sqlite` for the local key database, and `github.com/prometheus/client_golang` for metrics. The SQLite driver is a pure Go implementation, which is why the indirect dependency list is long: it pulls in `modernc.org/sqlite`, `modernc.org/libc` and `remyoudompheng/bigfft` rather than cgo.
The `Dockerfile` confirms the shape. A builder stage compiles with `go install -trimpath`, and the runtime stage copies the binary alongside a `whoami.sqlite3` file, pointing `DB_PATH` at it under `/usr/local/share/`. The key data ships as a file with the container rather than being fetched at startup.
The ssh config that stops presenting your keys
A server that enumerates keys is only interesting against clients that volunteer them, so the README spends its last section on opting out. The fix goes at the end of `~/.ssh/config`, after other Host directives, and applies to every host:
Host *
PubkeyAuthentication no
IdentitiesOnly yesThat disables public key authentication outright. The cost is that you then have to name the keys you do want per host, which the next block shows:
Host example.com
PubkeyAuthentication yes
IdentityFile ~/.ssh/id_rsa
# IdentitiesOnly yes # Enable ssh-agent (PKCS11 etc.) keysThe interesting suggestion is further down. Separate keys per destination stop the correlation:
Host github.com
PubkeyAuthentication yes
IdentityFile ~/.ssh/github_id_rsaThis is the practical lesson the project teaches without stating it as one. A public key is a stable identifier, and presenting the same one to unrelated services lets anyone holding both logs link those services to the same person. Generating a distinct key per host is more work and it removes that link.
A demonstration server rather than a component to build on
It is worth being direct about what this program is. It is a public demonstration of an authentication edge case, hosted on Fly.io, with metrics instrumentation and a bundled SQLite database of GitHub keys. Nothing about it is designed to sit in an application path, and it would be a strange thing to depend on.
The dependency versions suggest steady, unhurried maintenance. `go-github/v72`, `prometheus/client_golang v1.23.2`, `x/crypto v0.50.0`, `x/oauth2 v0.36.0` and `zombiezen.com/go/sqlite v1.4.2` are all recent, and the module targets Go 1.25.0. The last push was on 2026-04-16 and the repository is not archived, with 2366 stars, 112 forks and 10 open issues. That combination suggests a project that gets touched when its dependencies or hosting need attention rather than one with a release cadence.
There are no tagged releases, which is consistent with the shape: this is something you connect to, not something you install. The README is the entire documentation, and the one piece of friction in it is a link that points at `server.go` in a differently named repository, which is either a leftover from the project's previous name or a redirect that never got updated.
Editorial conclusion
The trick at the centre of this is narrow and legible: SSH offers a client several public keys before giving up, and a server that accepts keyboard-interactive without a challenge can therefore collect that list without ever being granted access. whoami.filippo.io does exactly that, joins the result against a SQLite copy of GitHub public keys, asks the API for a display name, and closes the shell. It is a demonstration of an authentication edge case rather than infrastructure you should put in a path, and the README is honest that it accepts no keys at all. Everything lives in a single `server.go`, and the surrounding questions it raises, key reuse across hosts and what a scraped key database can tell an observer, are the interesting part.
Frequently asked questions
What does whoami.filippo.io do when I connect to it?
It collects the public keys your SSH client offers, matches them against a local SQLite copy of GitHub public keys to find your username, asks the GitHub API for your real name, prints both and closes the terminal. It accepts no keys and grants no shell access, so nothing you own is at risk beyond the key list itself.
How can I stop a server from seeing my SSH public keys?
Set PubkeyAuthentication no and IdentitiesOnly yes for Host * at the end of your ~/.ssh/config, then name an IdentityFile per host where you still want key authentication. A separate key for each destination also stops unrelated services from correlating you through a shared key.
Is it safe to ssh into whoami.filippo.io?
The server runs a shell and PTY but the program immediately prints what it found and closes the terminal, without accepting any key or executing anything you send. The README publishes ED25519 and RSA host key fingerprints so the connection can be verified rather than trusted.
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/filosottile-whoami-filippo-io)