Why it's better to use RhodeCode Auth tokens than SSH


Using Auth Token Keys instead of SSH

SSH keys are a handy when it comes to usage in Version Control Systems, in particular they allow:

  • passwordless operations on operations like push/pull
  • easy integrations with scripts without storing credentials inside them
  • Stored credentials are limited to only vcs operations

There are some disadvantages however:

  • probably you need to create a new PK just for VCS operations, as users shouldn’t use they main PK
  • Windows is always a problem
  • Users needs to create the key, and configure they client to use it
  • Some of the added features of server don’t work with SSH, in particular things like ip restrictions, git LFS also is problematic
  • Many companies block SSH ports in particular on they infrastrcure

RhodeCode Enterprise Auth Token authentication tries to address both. Keep advantages of using SSH keys, as well as solves disadvantages

RhodeCode Auth Token authentication system is similar to google’s app specific passwords.

RhodeCode can generate special auth tokens per-user, that have special roles. Those include:

  • api (used only with RhodeCode Enterprise API)
  • web (allowed to use with our white-list access, meaning a raw-diff can be exposed using auth_token GET flag on protected content, and integrated with external code-review tool for example)
  • vcs (Limited to GIT/HG/SVN protocol operations only, users cannot log-in via web interface)
  • rss (Allows access to RSS feedbs ONLY, safe to put in your office, or RSS browser in plaintext)

All of those tokens, are generated by system as 40 char random hash, which is hard to remember, similar to how SSH keys are generated.

All of those can be configured with expiration, 5min, 30days or never. And all of those can be revoked from the web interface.

This allows really great control over, tokens can be shared with external parties, and with set expiration you

never need to worry about remembering to revoke access to someone.

VCS tokens are the ones that could be used in exchange of SSH access. The most use cases here are:

  • allowing users to have passwordless operations for VCS
  • Integrate with 3rd part, like CI without storing any system passwords

The usage of the auth tokens, addresses all of the disadvantages of SSH, since it’s based on http

you keep your additional security protection like ip restrictions and it’s not blocked by blocking SSH on the server.

Tokens don’t require any additional configuration

on client side, they are simply used as an alternative passwords.

passwordless access

Using .netrc for GIT, or .hgrc files allows easy access to the system without beeing asked
about the password each time.

For GIT (~/.netrc):

machine code.company.com
login john
password *token*

Git will not match the machine name in your .netrc if it has a username in it, so make sure you edit
your .git/config file in the root of your clone of the repository and remove the user and ‘@’ part from any clone URL’s
(URL fields) that look like https://user@machine.domain.com/… to make them look like http://machine.domain.com/

Also it’s recommended to add wrapper of git credentials helper to allow it to read .netrc file.

git config credential.helper "netrc -d -v"  

For Mercurial (~/.hgrc):

rc.prefix = code.company.com
rc.username = john
rc.password = \<token\>

There are even safer solutions like keychain extensions which allows to store credentials inside system keychain on OSX or Windows


Scripts integration

Auth tokens can be integrated into 3rd part scripts, one good example is our internal
rhodecode-export script, we added a CLI parameter to the script which passes internally
the token to the call, so you use it like that:

example-script --auth-token=<token>

In case you really don’y want any traces of passoword on CLI this coule be easily extended with

rhodecode-export --auth-token-from-file=/path/to/file_with_token.txt

Which internally translates to such example operation:

run_operation("hg push admin:{token}@https://{server}/{repo}".format(auth_token, server_name, repository_name))

Where auth_token is extracted either from the CLI option, or read from file_with_token.

Another approach is to use the env parameters that are very common in UNIX world, like

RC_AUTH_TOKEN=<secret> example-script

In this case for Python auth_token is then read from the environ variable

auth_token = sys.environ('RC_AUTH_TOKEN')

Even if the token is exposed somehow users would never be allowed to log in with them to the web interface.

Additionally with RhodeCode Enterprise IP restrictions will dissalow such token if it’s used with IP outside of whitelis of IPs