Skip to main content

Simple SSH key management for shell servers

Project description

Keyholer - Simple SSH key management for shell servers

Keyholer is a web application that will allow your users to add an SSH key to their authorized_keys file so they can gain access to a system they don’t otherwise have an SSH key for. It attempts to do so in as secure a fashion as possible.

User Flow/Process:

  1. User visits keyholer-web
  2. User enters their username, presses submit
    1. keyholer-web submits command to keyholerd, “login <username>”
    2. keyholerd checks for ~<username>/.phonenumber, if bad/missing return False
    3. keyholerd generates and sends random code via SMS, return True
    4. keyholer-web checks return value, returns error if False
  3. keyholer-web displays a verification page, user enters code from SMS
    1. keyholer-web submits command, “verify <username> <code>”
    2. keyholerd checks username and code, returns false if wrong
    3. keyholerd reads the user’s authorized_keys, finds list of ID’s
    4. keyholerd returns: True\n<list of ID’s>
  4. keyholer-web displays the list of existing keys and an <input> for a new key
  5. User pastes a new key into the textarea, clicks Submit
    1. keyholer-web submits command, “add_key <username> <code> <ssh_key>”
    2. keyholerd makes sure the code is valid, if not return False
    3. keyholerd makes sure the ssh_key is valid, if not return False
    4. keyholerd adds the key to the user’s authorized_keys file
    5. keyholerd sends an sms to admin_user for alert/audit purposes


There are two pieces that need to be running; keyholerd and the web frontend. You can use systemd, runit, screen, or any other daemon management strategy you’d like. Despite the name keyholerd does not currently support running in the background as a daemon.

To run the web component you can use your favorite WSGI stack. My personal setup uses nginx to proxy the requests back to a gunicorn app server.


As this software interacts with a number of security sensitive subsystems, you should take great care when installing it.

The keyholerd program must run as root so that it can write to users’ authorized_keys files. You should run the web component as a dedicated non-priviledged user.

The user’s .phonenumber files must be owned by that user and chmod’d 600 or keyholerd will not consider that a valid user.

The user’s authorized_keys file must already exist or keyholerd will not consider that a valid user.

All submitted keys are verified using “ssh-keygen -l” before being added to an authorized_keys file.


Keyholer requires a configuration file. You can find a sample config in etc/keyholer.conf.example. You should install your configuration as /etc/keyholer.conf and it must be valid JSON.

  • admin_user
    • The username of the server’s owner. This user will get SMS’s anytime a user’s password is reset
  • web_user
    • The username the web app will run as
  • group
    • The group for the web_user
  • socket
    • The path for the socket the frontend uses to communicate with the backend. This directory must be owned by web_user:group and be mode 700. If if does not exist it will be created by keyholerd.
  • sms_number
    • The phone number that codes will be sent from
  • token_ttl
    • How many seconds a token is good for. Defaults to 300 (5 minutes)
  • twilio_sid
    • The account sid for your twilio account
  • twilio_token
    • The AuthToken for your twilio account


Sign up for an account, register a phone number, and get your auth_token and sid at their website:

This is required to send the code via SMS.


If you are on a system which uses systemd as the init system, you will find files that can be used to start keyholer at boot time in etc/systemd. Simply copy those files to /usr/lib/systemd/system and enable the service:

# systemctl enable keyholer.service
# systemctl enable keyholer-web.service
# /bin/systemctl start keyholer.service
# /bin/systemctl start keyholer-web.service

Initial development

Other contributers

  • (Your name could be here!)


2014 Sep 8: 0.7.2

Zach White <>

  • Fix formatting for CHANGELOG.rst

2014 Sep 8: 0.7.1

Zach White <>

  • Add a script to manage test/release
  • Add argparse support to keyholerd so a user can override the config
  • Create –write-config option to write the configuration to /etc/keyholer.conf

2014 Sep 5: 0.7.0

Zach White <>

  • Initial release

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for keyholer, version 0.7.2
Filename, size File type Python version Upload date Hashes
Filename, size keyholer-0.7.2-py2.py3-none-any.whl (15.0 kB) File type Wheel Python version 2.7 Upload date Hashes View hashes
Filename, size keyholer-0.7.2.tar.gz (11.5 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page