changing keys -- self service key management
Copyright: Jeff Mitchell (jmitchell@kde.org). Licensed under CC-BY-NC-SA unported 3.0, https://creativecommons.org/licenses/by-nc-sa/3.0/
[Note on v3 version: this has been manually spot-tested; there is no test suite. Changes from v2 version are minimal so it should all work fine but please report errors!]
Follow this guide to add keys to or remove keys from your account. Note that you cannot use this method to add your first key to the account; you must still email your initial key to your admin.
The key management is done using a command called sskm
. This command must be enabled for remote use by the admin (see here for more on this).
Important!
There are a few things that you should know before using the key management system. Please do not ignore this section!
Key fingerprints
Keys are identified in some of these subcommands by their fingerprints. To see the fingerprint for a public key on your computer, use the following syntax:
ssh-keygen -l -f <path_to_public_key.pub>
You'll get output like:
jeff@baklava ~ $ ssh-keygen -l -f .ssh/jeffskey.pub
2048 2d:78:d4:2c:b1:6d:9a:dc:d9:0d:94:3c:d8:c2:65:44 .ssh/jeffskey.pub (RSA)
Active keys
Any keys that you can use to interact with the system are active keys. (Inactive keys are keys that are, for instance, scheduled to be added or removed.) Keys are identified with their keyid
; see the section below on listing keys.
If you have no current active keys, you will be locked out of the system (in which case email your admin for help). Therefore, be sure that you are never removing your only active key!
Selecting which key to use
Although you can identify yourself to the Gitolite system with any of your active keys on the server, at times it is necessary to specifically pick which key you are identifying with. To pick the key to use, pass the -i
flag into ssh
:
jeff@baklava ~ $ ssh -i .ssh/jeffskey git@git info
hello jeff, the gitolite version here is v2.0.1-11-g1cd3414
the gitolite config gives you the following access:
@C R W [a-zA-Z0-9][a-zA-Z0-9_\-\.]+[a-zA-Z0-9]
....
N.B.: If you have any keys loaded into ssh-agent
(i.e., ssh-add -l
shows
at least one key), then this may not work properly. ssh
has a bug which
makes it ignore -i
values when that key has not been loaded into the agent.
One solution is to add the key you want to use (e.g., ssh-add
.ssh/jeffskey
). The other is to remove all the keys from the agent or
disable the agent, using one of these commands:
- Terminate
ssh-agent
or usessh-add -D
flag to remove identities from it - If using
keychain
, runkeychain --clear
to remove identities - Unset the
SSH_AUTH_SOCK
andSSH_AGENT_PID
variables in the current shell
Public vs. private keys
In this guide, all keys are using their full suffix. In other words, if you see a .pub
at the end of a key, it's the public key; if you don't, it's the private key. For instance, when using the -i
flag with ssh
, you are specifying private keys to use. When you are submitting a key for addition to the system, you are using the public key.
Listing your existing keys
To see a list of your existing keys, use the list
argument to sskm
:
jeff@baklava ~ $ ssh git@git sskm list
hello jeff, you are currently using a normal ("active") key
you have the following keys:
== active keys ==
1: 72:ef:a3:e0:f5:06:f8:aa:6f:a2:88:9d:50:86:25:4e : jeff@key1.pub
2: 61:38:a7:9f:ba:cb:99:81:4f:49:2c:8b:c8:63:8e:33 : jeff@key2.pub
3: 2d:78:d4:2c:b1:6d:9a:dc:d9:0d:94:3c:d8:c2:65:44 : jeff@key3.pub
Notice the @
sign in each key's name? That sign and the text after that up until the .pub
is the keyid
. This is what you will use when identifying keys to the system. Above, for instance, one of my keys has the keyid
of @key3
.
A keyid may be empty; in fact to start with you may only have a single
jeff.pub
key, depending on how your admin added your initial key. You can
use any keyid you wish when adding keys (like @home
, @laptop
, ...); the
only rules are that it must start with the @
character and after that
contain only digits, letters, or underscores.
Adding or Replacing a key
Step 1: Adding the Key
Adding and replacing a key is the same process. What matters is the keyid
. When adding a new key, use a new keyid
; when replacing a key, pass in the keyid
of the key you want to replace, as found by using the list
subcommand. Pretty simple!
To add a key, pipe in the text of your new key using cat
to the add
subcommand. In the example below, I explicitly select which existing, active pubkey to identify with for the command (using the -i
parameter to ssh) for clarity:
jeff@baklava ~ $ cat .ssh/newkey.pub | ssh -i .ssh/jeffskey git@git sskm add @key4
hello jeff, you are currently using a normal ("active") key
please supply the new key on STDIN. (I recommend you
don't try to do this interactively, but use a pipe)
If you now run the list
command you'll see that it's scheduled for addition:
jeff@baklava ~ $ ssh -i .ssh/jeffskey git@git sskm list
hello jeff, you are currently using a normal ("active") key
you have the following keys:
== active keys ==
1: 72:ef:a3:e0:f5:06:f8:aa:6f:a2:88:9d:50:86:25:4e : jeff@key1.pub
2: 61:38:a7:9f:ba:cb:99:81:4f:49:2c:8b:c8:63:8e:33 : jeff@key2.pub
3: 2d:78:d4:2c:b1:6d:9a:dc:d9:0d:94:3c:d8:c2:65:44 : jeff@key3.pub
== keys marked for addition/replacement ==
1: ff:92:a2:20:6d:42:6b:cf:20:e8:a2:4a:3b:b0:32:3a : jeff@key4.pub
Step 2: Confirming the addition
Gitolite uses Git internally to store the keys. Just like with Git, where you commit locally before push
-ing up to the server, you need to confirm the key addition (see the next section if you made a mistake). We use the confirm-add
subcommand to do this, but: to verify that you truly have ownership of the corresponding private key, you must use the key you are adding itself to do the confirmation! (Inconvenient like most security, but very necessary from a security perspective.) This is where using the -i
flag of ssh
comes in handy:
jeff@baklava ~ $ ssh -i .ssh/newkey git@git sskm confirm-add @key4
hello jeff, you are currently using a key in the 'marked for add' state
Listing keys again shows that all four keys are now active:
jeff@baklava ~ $ ssh -i .ssh/newkey git@git sskm list
hello jeff, you are currently using a normal ("active") key
you have the following keys:
== active keys ==
1: 72:ef:a3:e0:f5:06:f8:aa:6f:a2:88:9d:50:86:25:4e : jeff@key1.pub
2: 61:38:a7:9f:ba:cb:99:81:4f:49:2c:8b:c8:63:8e:33 : jeff@key2.pub
3: 2d:78:d4:2c:b1:6d:9a:dc:d9:0d:94:3c:d8:c2:65:44 : jeff@key3.pub
4: ff:92:a2:20:6d:42:6b:cf:20:e8:a2:4a:3b:b0:32:3a : jeff@key4.pub
Optional: Undoing a mistaken add (before confirmation)
Another advantage of Gitolite using Git internally is that that if we mistakenly add the wrong key, we can undo it before it's confirmed by passing in the keyid
we want to remove into the undo-add
subcommand:
jeff@baklava ~ $ ssh -i .ssh/jeffskey git@git sskm undo-add @key4
hello jeff, you are currently using a normal ("active") key
Listing the keys shows that that new key has been removed:
jeff@baklava ~ $ ssh -i .ssh/jeffskey git@git sskm list
hello jeff, you are currently using a normal ("active") key
you have the following keys:
== active keys ==
1: 72:ef:a3:e0:f5:06:f8:aa:6f:a2:88:9d:50:86:25:4e : jeff@key1.pub
2: 61:38:a7:9f:ba:cb:99:81:4f:49:2c:8b:c8:63:8e:33 : jeff@key2.pub
3: 2d:78:d4:2c:b1:6d:9a:dc:d9:0d:94:3c:d8:c2:65:44 : jeff@key3.pub
Removing a key
Step 1: Mark the key for deletion
Deleting a key works very similarly to adding a key, with del
substituted for add
.
Let's say that I have my four keys from the example above:
jeff@baklava ~ $ ssh -i .ssh/newkey git@git sskm list
hello jeff, you are currently using a normal ("active") key
you have the following keys:
== active keys ==
1: 72:ef:a3:e0:f5:06:f8:aa:6f:a2:88:9d:50:86:25:4e : jeff@key1.pub
2: 61:38:a7:9f:ba:cb:99:81:4f:49:2c:8b:c8:63:8e:33 : jeff@key2.pub
3: 2d:78:d4:2c:b1:6d:9a:dc:d9:0d:94:3c:d8:c2:65:44 : jeff@key3.pub
4: ff:92:a2:20:6d:42:6b:cf:20:e8:a2:4a:3b:b0:32:3a : jeff@key4.pub
I would like to remove the key that on my box is called newkey
and in the Gitolite system is known as @key4
.
I simply pass in the identifier to the del
subcommand of sskm
:
jeff@baklava ~ $ ssh -i .ssh/newkey git@git sskm del @key4
hello jeff, you are currently using a normal ("active") key
Listing the keys now shows that it is marked for deletion:
jeff@baklava ~ $ ssh -i .ssh/newkey git@git sskm list
hello jeff, you are currently using a key in the 'marked for del' state
you have the following keys:
== active keys ==
1: 72:ef:a3:e0:f5:06:f8:aa:6f:a2:88:9d:50:86:25:4e : jeff@key1.pub
2: 61:38:a7:9f:ba:cb:99:81:4f:49:2c:8b:c8:63:8e:33 : jeff@key2.pub
3: 2d:78:d4:2c:b1:6d:9a:dc:d9:0d:94:3c:d8:c2:65:44 : jeff@key3.pub
== keys marked for deletion ==
1: ff:92:a2:20:6d:42:6b:cf:20:e8:a2:4a:3b:b0:32:3a : jeff@key4.pub
Step 2: Confirming the deletion
Just like with Git, where you commit locally before push
-ing up to the server, you need to confirm the key addition (see the next section if you made a mistake). We use the confirm-del
subcommand to do this, but: unlike the confirm-add
subcommand, you must use a different key than the key you are deleting to do the confirmation! This prevents you from accidentally locking yourself out of the system by removing all active keys:
jeff@baklava ~ $ ssh -i .ssh/jeffskey git@git sskm confirm-del @key4
hello jeff, you are currently using a normal ("active") key
Listing keys again shows that the fourth key has been removed:
jeff@baklava ~ $ ssh -i .ssh/jeffskey git@git sskm list
hello jeff, you are currently using a normal ("active") key
you have the following keys:
== active keys ==
1: 72:ef:a3:e0:f5:06:f8:aa:6f:a2:88:9d:50:86:25:4e : jeff@key1.pub
2: 61:38:a7:9f:ba:cb:99:81:4f:49:2c:8b:c8:63:8e:33 : jeff@key2.pub
3: 2d:78:d4:2c:b1:6d:9a:dc:d9:0d:94:3c:d8:c2:65:44 : jeff@key3.pub
Optional: Undoing a mistaken delete (before confirmation)
Another advantage of Gitolite using Git internally is that that if we mistakenly delete the wrong key, we can undo it before it's confirmed by passing in the keyid
we want to keep into the undo-del
subcommand. Note that this operation must be performed using the private key that corresponds to the key you are trying to keep! (Security reasons, similar to the reason that you must confirm an addition this way; it prevents anyone from undoing a deletion, and therefore keeping in the system, a key that they cannot prove (by having the corresponding private key) should stay in the system):
jeff@baklava ~ $ ssh -i .ssh/newkey git@git sskm undo-del @key4
hello jeff, you are currently using a key in the 'marked for del' state
You're undeleting a key that is currently marked for deletion.
Hit ENTER to undelete this key
Hit Ctrl-C to cancel the undelete
Please see documentation for caveats on the undelete process as well as how to
actually delete it.
(Go ahead and hit ENTER there; the caveats are really only on the administrative side of things.)
Listing the keys shows that that new key is now marked active again:
jeff@baklava ~ $ ssh -i .ssh/newkey git@git sskm list
hello jeff, you are currently using a normal ("active") key
you have the following keys:
== active keys ==
1: 72:ef:a3:e0:f5:06:f8:aa:6f:a2:88:9d:50:86:25:4e : jeff@key1.pub
2: 61:38:a7:9f:ba:cb:99:81:4f:49:2c:8b:c8:63:8e:33 : jeff@key2.pub
3: 2d:78:d4:2c:b1:6d:9a:dc:d9:0d:94:3c:d8:c2:65:44 : jeff@key3.pub
4: ff:92:a2:20:6d:42:6b:cf:20:e8:a2:4a:3b:b0:32:3a : jeff@key4.pub
important notes for the admin
These are the things that can break if you allow your users to use this command:
-
"sskm" clones, changes, and pushes back the gitolite-admin repo. This means, even if you're the only administrator, you should never 'git push -f', in case you end up overwriting something sskm did.
-
There is no way to distinguish
foo/alice.pub
frombar/alice.pub
using this command. You can distinguishfoo/alice.pub
frombar/alice@home.pub
, but that's not because of the foo and bar, it's because the two files have different keyids.In other words, sskm only works with the older style, not with the "subdirectory" style of multi-key management.
-
Keys placed in specific folders (for whatever reasons), will probably not stay in those folders if this command is used. Even a key delete, followed by undoing the delete, will cause the key to effectively move to the root of the key store (i.e., the
keydir
directory in the gitolite-admin repo).