containerssh-authserver is a configurable authentication server application designed to work with ContainerSSH as a webhook backend, by implementing the ContainerSSH authentication API. It allows user-specific Docker container profiles to be defined in either a simple YAML configuration file or a PostgreSQL database, enabling per-user images, shell commands, bind-mounts, and network connections.
- Go 1.26.4 or newer (for building from source)
- Docker 20.10+ (or compatible), with Docker Compose (for the demo), Docker API version 1.41
- openssl, ssh-keygen
containerssh-authserver supports multiple backends for user profiles, allowing for both simple static configurations and dynamic database-driven setups:
- Static (YAML): Define users directly in the
config.yamlfile underapp.authServer.users. - PostgreSQL: Store and manage user profiles in a PostgreSQL database for better scalability and dynamic updates.
You can configure which backends to use in the app.authServer.backends list. If multiple backends are enabled, they are queried in order until a user is found.
When using the PostgreSQL backend, the application expects a user_profiles table in the authserver schema:
CREATE TABLE authserver.user_profiles
(
username VARCHAR(32) PRIMARY KEY,
binds TEXT[],
image VARCHAR(384),
networks VARCHAR(64)[],
public_keys TEXT[],
shell_command TEXT[],
secret VARCHAR(255)
);The username is limited to 32 characters (Linux limit), the image to 384 characters (Docker name + tag limit), and each network name to 64 characters.
To build the application from source, use the provided Makefile:
# Install tools, generate code, lint and build
make all
# Or just build the binary
make buildThe repository comes with an example Docker Compose stack that needs little configuration. Run the following commands to generate the required key material; generated key files are stored in the keys directory:
docker/generate-keys.shFind the public key for the johndoe demo account in keys/johndoe.pem.pub and add it to the publicKeys list of the johndoe user in the authserver configuration file in docker/services/authserver/config.yaml. Of couse, you can add more users at will.
The johndoe demo account uses the alpine:3.21 image, without any additional bind mounts or network connections.
The containerssh service comes with a minimal configuration file (see docker/services/containerssh/config.yaml that defines the listening port, the backend URLs for the authentication webhook, and the per-user container configuration.
The demo stack includes containerssh-authserver, a PostgreSQL database, and ContainerSSH. It is pre-configured to use both PostgreSQL and static YAML backends.
Use the following command to build and run the entire stack:
docker compose -f docker/docker-compose.yml up --buildThe stack also includes a postgres-seed service that automatically initializes the database schema and seeds it with demo users.
Once started, you can connect to containerssh as johndoe using the generated private key and get a shell to a container as configured, for instance:
ssh -i docker/keys/johndoe.pem -p 2222 johndoe@localhost If you have many keys loaded in ssh-agent, SSH may attempt to authenticate with all of them before using the key you specify with -i. ContainerSSH limits the number of authentication attempts, which can cause the connection to fail before the correct key is tried.
To prevent SSH from offering all agent keys, use the IdentitiesOnly=yes option:
ssh -o IdentitiesOnly=yes -i docker/keys/johndoe.pem -p 2222 johndoe@localhostThis tells SSH to use only the explicitly specified identity file and ignore any keys loaded in ssh-agent.
Example: Run the following command to generate a bcrypt password hash for the johndoe user:
docker run --rm httpd:2.4 htpasswd -Bbn johndoe topsecretSee docker/services/authserver/config.yaml file; find the user configuration and update the secret property.
Copyright 2025 - 2026 by Matthias Friedrich