Open-source project
ovh/the-bastion avatar
ovh/the-bastion

The Bastion: an SSH jump host that records and accounts for every session

Authentication, authorization, traceability and auditability for SSH accesses.

2,195 stars135 forksPerlNOASSERTION

At a glance

What is it?
The Bastion is a Perl application from OVHcloud that sits between an operations team and its infrastructure, adding per-account authentication, group authorisation, session recording and syslog output without a database or any other backing service.
Who is it for?
The Bastion is worth the operational cost when your team reaches production through shared credentials and nobody can say who changed what, because the value it adds is attribution: individual accounts, group roles, recorded sessions and syslog output that a SIEM can consume.
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 8 days ago.
What is it written in?
Mainly Perl, according to GitHub's language statistics.

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

Editorial analysis

The problem is attribution, not connectivity

The README opens by defining what a bastion is in general terms: a cluster of machines used as the unique entry point for operational teams such as sysadmins, developers and database admins to securely connect to devices, servers, virtual machines, cloud instances and network equipment, usually using `ssh`. Then it states the specific problem The Bastion addresses, providing mechanisms for authentication, authorization, traceability and auditability for a whole infrastructure.

That framing matters, because a bastion that only relays connections adds little. The interesting claim is the one about the layer of abstraction in between: the infrastructure no longer needs to know your operational team members individually. Each team member has an individual account on The Bastion and may be a member of one or several bastion groups that grant access to one or more infrastructures. The devices only need to trust the group identities, not the people.

That inversion is what solves the operational problem. Instead of provisioning and removing SSH keys on twenty hosts when someone joins or leaves, you change their membership in a bastion group. The blast radius of a departure is one configuration change in one place.

The README also points at a series of four blog posts that dig into the core functionality, running from Genesis through Delegation Dizziness and Security at the Core to A new era, plus a DESIGN.md at the top of the repository tree. Those are the documents to read if you want the reasoning rather than the feature list.

Nothing to install underneath it, and why that is the design

The README has a section on reliability that is really a statement about dependencies, and it is worth quoting the reasoning rather than the adjectives.

Only a few well-known libraries are used, and the argument is that less third party code means a tinier attack surface. The Bastion is engineered to be self-sufficient, with no dependencies such as databases, other daemons, other machines or third-party cloud services, neither for the authentication or the authorization phase, and the README notes that statistically this means less downtime.

That is a genuine architectural choice with real consequences. A bastion that needs a database is a bastion with a two-component failure domain, a migration story and a backup policy. A self-sufficient one is a directory of Perl scripts and configuration, and its state is inspectable with ordinary file tools. The cost is that you get exactly the access model The Bastion implements and nothing else, and the authentication logic is your own installation's rather than something delegated to an identity provider.

High availability is described as multiple bastion instances forming a cluster where any instance is usable at any time, on an active/active scheme. That is a coherent follow-through from the no-external-dependency stance: replicating a filesystem-based state is a different problem from replicating a database, and the README does not say how it is handled, which is exactly the kind of question to take to the documentation.

The repository structure backs the self-sufficiency claim. There is no database migration directory, no ORM and no service definition; instead there are `bin/`, `lib/`, `etc/`, `install/`, `contrib/`, `doc/`, `docker/` and `tests/` directories. The `DESIGN.md` file at the top is where the architecture rationale would live.

What you get in exchange for putting it in the path

The feature list on the README is long and deliberately non-exhaustive, and several items are genuinely unusual for a jump host.

Recording comes in two forms: interactive session recording in standard ttyrec files, and non-interactive recording of stdout and stderr through ttyrec as well. That second one matters, because most scripted SSH actions are non-interactive and most bastions record nothing about them. Logging goes out through syslog specifically so it can be consumed easily by a SIEM, which tells you the intended integration is not log files on a disk.

The protocol is broken between the ingress and the egress connections. That is the structural security argument: a compromise of the bastion does not hand an attacker a live session on the target, because there is no protocol continuity to hijack. The README backs this with a talk at the OSSIR 2021 that describes voluntarily adding a security vulnerability in the code to prove the design holds, which is an unusual and reasonably convincing thing to offer.

Authentication supports MFA with password and TOTP in addition to public key authentication, and the ingress side supports Yubico PIV key attestation checking and enforcement. Mosh is supported on the ingress side for connections that need to survive a network change.

The least obvious items are the legacy ones. SSH password autologin on the egress side is supported for devices that do not support public key authentication, telnet password autologin is supported for devices that do not support SSH at all, and in both cases the README is explicit that proper public key authentication is still forced on the ingress side. HTTPS proxying is supported with man-in-the-middle authentication and authorisation handling, for ingress and egress password decoupling, mainly useful for network device APIs. netconf SSH subsystem passthrough is there too, and realms let two bastions belonging to possibly different companies trust each other while each still enforces its own local policy.

File transfer and the parts that are ordinary

Not everything on the list is exotic. `scp`, `sftp` and `rsync` passthrough is supported, to upload and download files to and from remote servers. That is the capability most people need on day one and it is the one a naive jump-host implementation breaks, so it is good to have it stated.

The access model has two levels, personal and group, with group roles delegable. The README's framing is that this ensures team autonomy without security trade-offs, and it is linked to the documentation on access management. That is the mechanism behind the earlier claim about changing one person's group membership instead of rewriting keys across an estate.

Delegation extends further than human accounts, which is the part that makes the tool usable at scale. The README describes fine-grained RBAC that lets you delegate responsibilities to any account, group-scoped or bastion-wide, including accounts used by automation to manage the lifecycle of accounts linked to a human resources system, LDAP or AD, or to keep a group's ACL up to date from a CMDB. Automated processes are implemented through a JSON API over SSH.

An API over SSH rather than over HTTP is a deliberate choice worth understanding before you build against it. It means the automation channel inherits the same authentication and authorisation as a human session, including whatever MFA policy applies, and it means the API is reachable from exactly the places the bastion is reachable and nowhere else. It also means you script it with an SSH client.

Trying it in a container before you commit to it

The README's last section is a suggestion to test The Bastion with a disposable Docker sandbox, described as a good way to try it within seconds. It immediately qualifies that with a pointer to the FAQ entry on running it under Docker in production, for anyone serious about containerization in production. That pairing is a good sign about the project's documentation: a fast path to see the thing work, and an explicit warning that the fast path is not the production answer.

The sandbox image is published for a wide set of architectures: linux/386, linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64, linux/ppc64le and linux/s390x. That list is itself informative, since it says the build covers everything from a Pi to s390x mainframes, and the docker image is the place to start if you want to look before committing.

For the actual installation, the README does not describe steps. It points at the online documentation at ovh.github.io/the-bastion and at a text-based version of the same documentation in the repository's `doc/` folder. That split is deliberate and worth noticing: the text version in `doc/` means the instructions travel with a clone, so an air-gapped install has its documentation with it.

The tree also has a `docker/` directory and an `install/` directory, so both the containerised and the conventional installation paths exist in the repository even though the README declines to walk through either. There are `tests/` and a `sonar-project.properties`-free but present `AUTHORS` and `CONTRIBUTORS` file, which is a sign of a project with institutional rather than sole-maintainer backing. The last push was on 2026-07-28 and the most recent release is v3.24.01, published on 2026-07-08.

Versioning, licensing and how to compare it fairly

Two things to settle before you evaluate this seriously.

The first is the version line. Releases move in three-part numbers with a patch level that has reached double digits in the current series: v3.24.01 published on 2026-07-08, v3.24.00 on 2026-07-06, and a v3.23.99-rc3 release candidate on 2026-07-03. The `99` in a release candidate position is an explicit signal that the series is considered stable and that the rc is there to rehearse the final release. A project on a v3.24 line with patch numbers in the twenties is one that has been running for a long time and shows it.

The second is the licence, and here the repository is less clear than it could be. The GitHub metadata does not classify the licence at all, reporting no recognised licence type, while the default branch contains a `LICENSE` file. Read the file. Do not infer terms from a badge or from the fact that it is published by a company, because a missing classification on a security-adjacent tool is exactly the kind of detail that matters when you are putting it in the path to production.

The fair comparison is with a plain SSH jump host plus key management, and with commercial session-recording proxies. Against a plain jump host, The Bastion's advantages are individual attribution, group-scoped authorisation, ttyrec capture of both interactive and non-interactive sessions, syslog output for a SIEM, and the ability to reach telnet and password-only devices without weakening the ingress side. Its costs are a Perl application in your path, an installation with its own upgrade procedure, and the fact that nothing is delegated to an identity provider. Against a commercial proxy, the difference in approach is that the access model and the identity store are yours to run, with no external service in the authentication path, which is exactly what a regulated environment asks for and exactly what a small team may not want to operate.

Editorial conclusion

The Bastion is worth the operational cost when your team reaches production through shared credentials and nobody can say who changed what, because the value it adds is attribution: individual accounts, group roles, recorded sessions and syslog output that a SIEM can consume. It is not worth it if your infrastructure already authenticates each engineer individually and your network equipment accepts modern SSH, since in that case a plain jump host already gives you the connection and The Bastion gives you the paperwork. Start with the Docker sandbox, which the README describes as a way to try it within seconds, and read the FAQ entry on running it under Docker in production before you build a deployment around containers. Then install from `install/` following the documentation, and turn on syslog and ttyrec capture before you grant anyone access, because a bastion that records nothing retroactively is a bastion that answers no questions.

Frequently asked questions

What is a bastion host?

A bastion is a machine that acts as the single entry point for an operations team to reach servers, virtual machines, cloud instances or network equipment over `ssh`. The Bastion from OVHcloud is a bastion host that adds per-account authentication, group authorisation, session recording and auditability on top of that relay.

Does The Bastion need a database to store user accounts and permissions?

No. The README states that it is engineered to be self-sufficient, with no dependencies such as databases, other daemons, other machines or third-party cloud services, neither for the authentication or the authorization phase. Accounts and group membership are held by the application itself, and high availability across instances is described as an active/active cluster.

Can The Bastion record sessions for auditing?

Yes, and it covers the non-interactive case as well. The README lists interactive session recording in standard ttyrec files, non-interactive recording of stdout and stderr through ttyrec, and extensive logging through syslog for SIEM consumption. Enabling these before granting access is what makes the tool useful for attribution.

How do I try The Bastion before installing it on real infrastructure?

The README points at a disposable Docker sandbox described as a way to test it within seconds, with an image published for linux/386, linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64, linux/ppc64le and linux/s390x. It also directs you to the FAQ entry on running it under Docker in production before treating containers as the supported production path.

Official sources

  1. Issues
  2. ovh/the-bastion on GitHub
  3. Project website
  4. README
  5. Releases
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/ovh-the-bastion.svg)](https://hysenlabs.com/projects/ovh-the-bastion)