VaultShell is a small Linux tool that puts authentication + simple RBAC in front of interactive container shells.
It works by installing a lightweight wrapper for docker exec that:
- Prompts for a VaultShell username + password
- Verifies access (admin or assigned container)
- Opens an interactive
bashsession inside the container - Logs the session output and (optionally) converts ANSI logs into plain text
- Auth: Passwords are stored as bcrypt hashes.
- RBAC:
adminusers can access any container.useraccounts can only access containers assigned to them.
- Session logging:
- Raw session logs are written to
/var/lib/vaultshell/logs/. - A watcher can convert those logs to text in
/var/lib/vaultshell/logstxt/.
- Raw session logs are written to
make installinstalls:/usr/local/bin/vaultshell(a PyInstaller one-file binary)/usr/local/bin/docker(a wrapper that interceptsdocker exec)/usr/local/bin/watch.shand/usr/local/bin/logconverter.sh(log conversion)/var/lib/vaultshell/(SQLite DB + logs directories)
- When you run
docker exec ..., the wrapper detectsexecand runs:vaultshell enter-container <container>
- VaultShell checks credentials and authorization, then runs:
/usr/bin/docker exec -it <container> bash- while capturing all output into a timestamped log file.
- Linux
- Docker Engine + daemon running
- Docker CLI at
/usr/bin/docker(the wrapper forwards non-execcommands there)
make- Python (recommended: 3.10+)
pip
These are also listed in dump.txt:
inotifywait(frominotify-tools)ansi2txt(a command available on your distro; see install steps below)
Important: the installer puts a wrapper at
/usr/local/bin/docker. On most systems,/usr/local/bincomes before/usr/bininPATH, so this will affect all users.
Install Docker (if you don’t already have it), plus optional log conversion dependencies:
- Fedora:
sudo dnf install -y inotify-tools
- Debian/Ubuntu:
sudo apt-get update && sudo apt-get install -y inotify-tools
For the ansi2txt tool, package names differ by distro.
After installing it, these should work:
command -v inotifywait
command -v ansi2txtgit clone <your-repo-url>
cd VaultShell
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtmake installmake install will:
- Build a one-file binary using PyInstaller
- Copy binaries/scripts into
/usr/local/bin/ - Create and permission
/var/lib/vaultshell/like this:/var/lib/vaultshell/vaultshell.db/var/lib/vaultshell/logs//var/lib/vaultshell/logstxt/
which docker
which vaultshellExpected:
dockerresolves to/usr/local/bin/dockervaultshellresolves to/usr/local/bin/vaultshell
VaultShell is intended to gate interactive container shells.
If a user is in the docker group, they can often bypass controls by calling Docker directly.
From dump.txt:
sudo gpasswd -d "$USER" dockerThen log out and log back in so group membership updates.
VaultShell stores its state in an SQLite database at:
/var/lib/vaultshell/vaultshell.db
Tables are created automatically on first run.
vaultshell add-user alice
vaultshell add-user bobContainer access is by container name:
vaultshell assign alice my-containerIf a container isn’t assigned, non-admin users will get Access Denied.
There is no CLI command yet for role management.
To promote a user to admin, update users.role in /var/lib/vaultshell/vaultshell.db.
If you don’t have a sqlite3 CLI available, you can do it with Python:
python - <<'PY'
import sqlite3
db = "/var/lib/vaultshell/vaultshell.db"
username = "alice"
conn = sqlite3.connect(db)
conn.execute("UPDATE users SET role='admin' WHERE username=?", (username,))
conn.commit()
conn.close()
print(f"Promoted {username} to admin")
PYWith the wrapper installed, use docker exec as usual:
docker exec -it my-container bashVaultShell will prompt for credentials and then open a shell (if authorized).
You can also call VaultShell directly:
vaultshell enter-container my-containerThe wrapper installed at /usr/local/bin/docker is intentionally minimal.
- It only intercepts
docker exec ...(notdocker container exec,docker compose exec, etc.). - It always launches
bashinside the container (it does not forward the command you typed after the container name). - Avoid
docker execflags that take a separate value (for example-u root/--user root), because the wrapper may mis-detect the container name.
If you need more control, prefer running vaultshell enter-container <container> directly.
When a session starts, VaultShell writes a file like:
/var/lib/vaultshell/logs/<username>_<container>_YYYYMMDD_HHMMSS.log
It also records metadata (start/end timestamps + log path) into session_logs.
On session start, VaultShell tries to start /usr/local/bin/watch.sh, which runs logconverter.sh in the background.
logconverter.sh:
- Watches
/var/lib/vaultshell/logs/usinginotifywait - Converts ANSI logs to
.txtusingansi2txt - Writes results to
/var/lib/vaultshell/logstxt/
If inotifywait or ansi2txt is missing, sessions still work, but .txt conversion won’t.
| File | Purpose |
|---|---|
vaultshell.py |
Click-based CLI entrypoint (add-user, assign, enter-container) |
auth.py |
Password hashing (bcrypt) + authentication |
rbac.py |
Authorization rules (admin vs container owner) |
db.py |
SQLite schema + CRUD helpers; stores state under /var/lib/vaultshell/ |
session.py |
Launches docker exec with a PTY and logs session output |
docker-wrapper.sh |
Wrapper installed as /usr/local/bin/docker to intercept docker exec |
watch.sh |
Starts the log conversion watcher in the background |
logconverter.sh |
Watches logs dir and converts ANSI logs to .txt |
Makefile |
Builds via PyInstaller and installs binaries + permissions |
systool.sh |
Convenience script: make build, make install, make clean |
requirements.txt |
Python dependencies used for building/testing |
dump.txt |
Notes about required system packages and group permissions |
.gitignore |
Ignores local artifacts like .venv/ and vaultshell.db |
vaultshell.db |
Repo-local SQLite DB (dev artifact; system installs use /var/lib/vaultshell/vaultshell.db) |
watch.log |
Repo-local watcher output (dev artifact; system installs write /var/lib/vaultshell/watch.log) |
sudo rm -f /usr/local/bin/vaultshell
sudo rm -f /usr/local/bin/watch.sh /usr/local/bin/logconverter.sh
# removes the docker wrapper (restores system docker resolution to /usr/bin/docker)
sudo rm -f /usr/local/bin/docker
# optional: delete state (users, assignments, logs)
sudo rm -rf /var/lib/vaultshellAuthentication Failed.- Username doesn’t exist or password is wrong.
Access Denied.- User isn’t
adminand the container isn’t assigned to them.
- User isn’t
Error: Run 'sudo vaultshell' once to initialize.- VaultShell couldn’t create
/var/lib/vaultshell/. Runmake install(recommended), or create the directory with the permissions shown in theMakefile.
- VaultShell couldn’t create
Container '<name>' not running./not found.- Start the container, and verify the name matches
docker ps.
- Start the container, and verify the name matches
- After removing yourself from the
dockergroup,docker psfails- Expected: the wrapper forwards most Docker commands to
/usr/bin/dockerwithout elevated group permissions. Usesudo docker ...(admin tasks) or keep operators in thedockergroup.
- Expected: the wrapper forwards most Docker commands to
- Docker CLI not at
/usr/bin/docker- Update the wrapper in
docker-wrapper.sh(it hard-codes/usr/bin/docker).
- Update the wrapper in
- Shell fails because container has no
bash- VaultShell currently launches
bashexplicitly. Installbashin the image, or changesession.pyto usesh.
- VaultShell currently launches
- Access to the Docker socket is effectively root-equivalent on most systems.
- VaultShell’s default install uses group permissions (
root:docker+ setgid) to allow controlled access. - Treat
adminusers as highly privileged.