Free tool · Runs in your browser

authorized_keys Analyzer: See Who Can Actually Log In

Paste an authorized_keys file and get a graded A to F review: every key with its type, size and SHA256 fingerprint, what each one is restricted to, and which keys nobody can account for. Reads the options field that every other parser ignores. Nothing is uploaded.

Analyzed entirely in this browser tab. Nothing is uploaded. The keys in this file are public, so they are not secret the way a private key is, but the file still names everyone who can log into the account.

Try:

How to audit your authorized_keys file

  1. On the server, print the file: cat ~/.ssh/authorized_keys. Check the other accounts too, including root, since each has its own.
  2. Paste it above. The review runs as you type, in your browser, and nothing is uploaded.
  3. Open the Access list tab. Every fingerprint there matches ssh-keygen -lf ~/.ssh/authorized_keys, so you can copy one and ask your team whose it is.
  4. Delete every key you cannot attribute to a person or a system that still exists. That is the whole job, and it is the step people skip.
  5. Use the Reviewed file tab to add restrict and from= to what remains, edit the placeholder addresses, then back up the original and replace it.

Why this file is the one nobody reviews

An authorized_keys file is an access control list, but it does not look like one. It has no owner column, no expiry column and no audit trail. It is a list of base64 blobs, and it only ever grows.

Keys accumulate the way permissions always accumulate: a contractor in 2023, a CI runner that was decommissioned, a laptop that was replaced, a colleague who left. None of those events removed a key, because removing a key is a separate task that nobody was assigned. Meanwhile the file grants permanent, password-less, unlogged-by-default access.

MITRE tracks the offensive side of this as T1098.004, Account Manipulation: SSH Authorized Keys. Appending one line to this file is among the first things an automated attack does after compromising a Unix host, precisely because the file is rarely read and changes to it are rarely alerted on. A key with no comment is indistinguishable from one your colleague added last year.

The options field, which almost every tool ignores

A line in this file can carry options before the key type, and they decide what the key is actually allowed to do. Compare these two lines, which look almost identical:

ssh-ed25519 AAAA... backup is a full interactive shell, with port forwarding and agent forwarding, usable from any address on the internet, forever.

restrict,from="10.0.0.5",expiry-time="20271231",command="/usr/local/bin/backup" ssh-ed25519 AAAA... backup can run one command, from one address, until one date.

Same key, same access in principle, completely different blast radius if the private half leaks. Every other authorized_keys parser on the web stops at the key type, the size and the fingerprint. This one reads the options, because that is where the security is.

One trap worth knowing: command= on its own is not a sandbox. The holder can still request a pty and still open port forwards to reach anything the server can reach. It needs restrict alongside it.

What the fingerprint is for

The SHA256: value in the access list is the same one ssh-keygen -lf prints, byte for byte. That matters because it is the only practical way to resolve an unattributed key.

You cannot tell who a key belongs to by looking at it. You can post its fingerprint in a channel and ask people to run ssh-keygen -lf ~/.ssh/id_ed25519.pub and check. Whoever matches it owns it. Whoever does not answer, you delete.

The legacy MD5: form is shown too, because some consoles, AWS included, still display imported key fingerprints in that format.

What a key file cannot tell you

This tool reads one file, and it is honest about that. It cannot tell you whether the person behind a key still works for you, which is the actual question. It cannot check the permissions on ~/.ssh/authorized_keys, find the files belonging to other accounts, or know whether a private key has leaked.

Those need the running server. The SSH and Access fix guide covers the server-side checks, and the SSH and Access checklist lists all eleven as commands you can paste into a terminal. CtrlOps scans a whole fleet for who can log in where and offboards someone from every server at once, which is the part that does not fit in a text file.

Reviewing how the server authenticates rather than who it lets in? The sshd_config Analyzer is the other half. Need to issue a replacement key? The SSH Key Generator makes one in the browser.

The options that decide what a key can actually do

OptionEffectWhen to use it
restrictDisables port, agent and X11 forwarding, pty allocation and ~/.ssh/rc, in one word.Every automated key. Add pty or port-forwarding after it to re-enable just the one you need.
from="..."Refuses the key unless the connection comes from a matching host or CIDR range.Any key with a fixed caller. It makes a stolen key useless outside your network.
command="..."Runs this command instead of whatever the client asked for.Backups and deploys. Pair it with restrict, or it is not a sandbox.
expiry-time="..."Refuses the key after a date. YYYYMMDD or YYYYMMDDHHMM.Contractors, temporary access, and honestly everything else.
cert-authorityTreats the key as a CA: anyone with a certificate it signed can log in.Only with a deliberate SSH CA setup. Never by accident.
environment="..."Sets environment variables for the session.Almost never. With PermitUserEnvironment on, it is an LD_PRELOAD privilege escalation.
no-agent-forwardingStops the session using your forwarded SSH agent.Anywhere you do not fully trust root on the destination host.
permitopen="host:port"Limits ssh -L forwarding to one destination.A tunnel-only key that should reach a database and nothing else.
authorized_keys FAQ

Frequently asked questions

Yes, on two counts. The analysis runs entirely in your browser using JavaScript on this page, so the file is never uploaded, logged or transmitted. And the keys in an authorized_keys file are public keys, which are not secret the way a private key is. That said, the file does name every person and system that can log into an account, so it is not something to hand to a third-party server either. This tool refuses private keys outright.
Use the fingerprint. The SHA256 value shown for each key is identical to what ssh-keygen -lf prints, so you can post it and ask people to run ssh-keygen -lf ~/.ssh/id_ed25519.pub on their own machine and check for a match. Whoever matches owns the key. Anyone who cannot match it does not, and that key should be removed. There is no other reliable way, which is why the comment field at the end of each line matters so much.
restrict disables port forwarding, agent forwarding, X11 forwarding, pty allocation and execution of ~/.ssh/rc, all in one word. It was added in OpenSSH 7.2 and it is the sane default for any automated key. If a key genuinely needs one of those back, you add the specific re-enabling flag after it, for example restrict,pty. Note that restrict,pty is meaningfully less restricted than restrict alone, which is easy to miss when reading a file quickly.
No, and this is the most common mistake in this file. A forced command stops the client choosing what to run, but on its own it does not stop them requesting a pty, and it does not stop them opening port forwards to reach anything the server can reach. A backup key with command= but no restrict is still a route into your internal network. Always pair the two: command="...",restrict.
A line marked cert-authority is not one person's key. It tells sshd to trust any certificate signed by that key, so everyone holding such a certificate can log in. That is a legitimate and good way to run SSH at scale, but only if you meant to set up an SSH certificate authority. If it appeared without a deliberate decision, it is a very large amount of access hiding in one line, and revoking it means managing a revocation list rather than deleting a key.
RSA at 3072 bits or above is fine. RSA at 2048 is acceptable but it is the floor, not a target. RSA below 2048 should be treated as compromised and replaced, not resized. DSA keys are worse than dated: they are capped at 1024 bits, OpenSSH disabled them by default in 9.8 and removed them in 9.9, so on a current server a DSA key already does not work. Ed25519 is the sensible default for anything new.
Because access that never expires is access nobody ever revokes. expiry-time="20271231" makes sshd refuse the key after that date, which turns forgetting from a security failure into an automatic revocation. It is the single cheapest control in this file, it needs no infrastructure, and almost nobody uses it. It was added in OpenSSH 8.2.
sshd tries each line and accepts the first that authenticates, so in practice the more permissive line usually wins. That makes a duplicated key with different restrictions genuinely dangerous: you believe a key is limited to one command from one address, and a second line grants it a full shell. This tool flags duplicates and specifically calls out the case where the options differ.
The file should be 600 and ~/.ssh should be 700, owned by the account. If either is group- or world-writable, sshd will refuse to use the keys at all when StrictModes is on, which is the default. This tool cannot see permissions because they are not in the file contents. Run chmod 600 ~/.ssh/authorized_keys && chmod 700 ~/.ssh on the server, and see the authorized keys fix page for the server-side check.
No. It reviews one file on one account. It cannot see the other accounts on the server, cannot check file permissions, and above all cannot tell you whether the human behind a key still works for you. That last question is the one this file exists to answer and the one it never records. The SSH and Access checklist covers the server-side checks, and CtrlOps scans a fleet for who can log in where.
One file is easy. Every account on every server is the problem.

Review one file here, see the whole fleet there.

CtrlOps scans every server you manage for who can log in and who has sudo, and offboards someone from all of them in one click. Your keys never leave your machine.

Start instantly· No credit card· No sneaky autorenewals