Bastillion: a self-hosted web SSH console and key manager for small fleets
Bastillion gives you a clean, browser-based way to manage SSH access across all your systems—like a bastion host with a friendly dashboard.
At a glance
- What is it?
- Bastillion puts browser terminals, centralized SSH key rotation and session recording behind one Java application. It is a good fit for teams up to eight systems, and a licensing decision beyond that.
- Who is it for?
- Bastillion suits a small operations team that wants browser terminals, one application key to rotate, and recorded sessions without buying a commercial PAM product. It is the wrong tool if you need per-user key pairs, a documented rollback path, or a fleet past the free tier without a budget line.
- 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 received new commits within the last day.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Bastillion actually replaces
The project describes two jobs. The first is a web-based SSH terminal: once a host is registered, authorized users open one or more live sessions to it from the browser. The second is SSH key management: Bastillion holds its own keypair and pushes or rotates public keys across registered hosts, so individual users never hold long-lived keys to those systems. The audience is an operations or platform team that has outgrown handing out personal SSH keys but does not want to run a commercial privileged access management suite. The trade is explicit. You get one application key to rotate, profile-based access control, and session recording on by default. You give up per-user keys, and you accept that the application sits between every operator and every host.
The keypair lifecycle and why revocation is a single action
On first startup Bastillion generates an Ed25519 keypair for itself. The README says this is the one key that ever gets pushed to your hosts, and it is shown in the console output and under Settings. Registration works in two steps: an admin adds a host under Manage, Systems with user, host, port, and the path to that host's authorized_keys file; Bastillion authenticates once with a password or passphrase you supply, then pushes its own public key into that file. Status flips to Success when the key is in place. From then on the connection uses the key, and the README states no stored passwords are kept. The design consequence is the interesting part. Because every host trusts the same application key rather than one key per user, disabling it once under Manage SSH Keys revokes access everywhere immediately. That is a real operational advantage over per-user key sprawl, but it also means a single compromise of the application key is a fleet-wide event. The README does not describe key rotation scheduling or a rekey interval, so treat rotation as something you trigger yourself.
Profiles, broadcast terminals and the shared-keystroke model
Access control is not per host. Systems are grouped into named Profiles, and users are linked to profiles under Manage, Users. The README states this is the only thing that controls who can reach what, and that revoking a profile assignment removes access immediately without key rotation. That is a clean model: authorization lives in the database, authentication lives in the keypair. The terminal side is where the project differs from a conventional jump box. Assigned users open Secure Shell, Terminals, pick one or more systems, and get xterm-based terminals side by side in the browser. Commands typed are broadcast to every terminal marked active. The README compares it to tmux synchronized panes, but for a fleet of remote hosts. This is genuinely useful for a health check across three web servers. It is also the sharpest edge in the product: a destructive command typed once runs everywhere at once. The README does not document a confirmation step or a dry-run mode before broadcast, so the caution has to live in your runbooks.
Installing it and opening a first session
The README points to a self-contained jar that runs with java -jar and provides HTTPS out of the box, and it lists Java 21 as the prerequisite. The repository also ships a Maven build (pom.xml) and a Node asset step (npm run build-assets) for building from source. The exact download URL is on the project site, loophole.company, so fetch the jar there rather than from an invented path. Once the jar is running, the first real task is registering a host, which the README describes as an admin action under Manage, Systems taking user, host, port, and the remote authorized_keys path, plus a one-time password or passphrase. After the key is pushed, the entry shows Success and the host is reachable from the browser terminal. Two configuration keys appear in the README and matter from day one: deleteAuditLogAfter controls how long sessions are kept (90 days by default) and ENABLE_INTERNAL_AUDIT=false switches recording off. If you are evaluating the audit trail, leave recording on and confirm where the logs land before you point it at production hosts.
Session recording, replay and the retention default
Recording is on by default. Everything typed and every byte returned in the terminals is captured, and managers open Audit Sessions to filter by user or system and replay a session. Sessions that spanned multiple hosts replay side by side, and output streams into the page as it loads, which the README says keeps even very large sessions usable. For teams facing a privileged-access audit-trail requirement, this is the feature that justifies the install. The limitation is retention. The default window is 90 days, set by deleteAuditLogAfter, and the README does not document an archival or export path for sessions that fall outside it. If your framework expects evidence to survive longer than a quarter, you are relying on a configuration change and on storage you control, not on a built-in archive. Read the configuration section before you promise an auditor anything.
Licensing, the eight-system ceiling and upgrade cost
This is the constraint that decides most adoptions. The README states Bastillion is free at up to 8 systems, with paid tiers at loophole.company/pricing.html. The badge and package.json identify the licence as the Prosperity Public License, and the repository carries LICENSE.md and 3rdPartyLicenses.md at the top level. The GitHub metadata reports the licence as NOASSERTION, which is a signal to read LICENSE.md yourself rather than trust a badge. For a lab, a small startup, or a team with a handful of servers, the free tier covers the whole use case. Past eight systems you are making a purchasing decision, and the README gives no migration or downgrade path if you decide against it. On maintenance: the last push was on 2026-09-10 and the most recent release listed is v5.2.1 on 2026-09-02, so the project is being worked on. Upgrades also carry a real cost: the release notes mention a v4 to v5 migration tool for bringing over users, systems, keys and audit logs, which tells you a major version bump is not a drop-in jar swap.
Where Bastillion is the wrong choice
Three cases stand out. First, if your security model requires per-user SSH keys with individual attribution at the SSH layer, Bastillion inverts that: one application key is trusted by every host, and attribution comes from the session recording and the application's own user accounts instead. Second, if you need a documented rollback. The README does not document rollback, key removal from hosts, or what happens to pushed keys when you uninstall, so plan for that gap before you push a key into a production authorized_keys file. Third, if you already run a mature PAM platform with credential vaulting, session proxying and policy engines, Bastillion's profile-and-keypair model is a smaller feature set, and the eight-system free ceiling makes it a cost comparison rather than a capability one. A straightforward alternative is plain OpenSSH with a hardened jump host: you manage authorized_keys by hand or with configuration management, and you get no browser terminal, no broadcast, and no replay, but also no new application in the access path and no licence ceiling. The difference is where the complexity lives, in your own automation or in this application.
Editorial conclusion
Bastillion suits a small operations team that wants browser terminals, one application key to rotate, and recorded sessions without buying a commercial PAM product. It is the wrong tool if you need per-user key pairs, a documented rollback path, or a fleet past the free tier without a budget line. Before adopting, verify three things: the exact terms in LICENSE.md, whether the 90-day deleteAuditLogAfter window matches your retention policy, and that a test instance can push its key into your target authorized_keys file.
Frequently asked questions
What does Bastillion mean?
The repository does not give an etymology for the name. The README describes the product as a web-based SSH console and SSH key management tool that behaves like a bastion host with a dashboard, which is the closest the documentation comes to explaining the naming.
What does bastion mean?
The README does not define the term directly. It positions Bastillion as sitting between your users and the systems they need to reach, acting as a trusted third party rather than a simple password vault, which is the role a bastion host plays.
What is the origin of the word "bastion"?
The repository does not discuss the word's origin. The README only uses the term to describe the product's role, comparing Bastillion to a bastion host with a dashboard.
What is a Bastillion alternative for managing SSH access?
The documentation does not name a competing product. The closest documented alternative is the manual approach: a hardened OpenSSH jump host with authorized_keys managed by hand or by configuration management, which gives up the browser terminal, command broadcast and session replay in exchange for no additional application in the access path.
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/bastillion-io-bastillion)