How to Get The `juju ssh` Key From Juju API

When I run juju ssh to connect to one of my machines it uses an ssh key that is in $HOME/.local/share/juju/ssh/juju_id_rsa, but where does that key come from? Is there a way to obtain that key from the Juju API?

So apparently the Juju CLI creates a juju ssh in your $HOME/.local dir when you first run the juju command. The question is how does it add this key to the controller/user/model so that Juju puts it on the machines in the models that the user has access to?

I an see the juju add-ssh-key commands and juju ssh-keys commands to add and list the keys, but somehow that key used by default by the Juju CLI is invisible? That doesn’t seem right to me. I’ve checked the API docs, but I still can’t find any place to set that key or otherwise add a new key that is also “invisible”.

The ssh key is added to the controller via cloud-init when the machine is created. When machines for units are created, the cloud-init contains ssh-authorized-keys data so the controller can login to the unit machines.

But what if I am on a different developer computer later? The first time I run juju it generates a new SSH key in my ~/.local/juju/ dir.

Then say I log into my controller and I try to run Juju SSH. I should be able to ssh into the machines in my model because I am the same user and I am authorized to do so, but how did the Juju CLI on my different developer computer add its key that it generated in the ~/.local dir to the machine’s trusted key list? Where does it store those keys, if when I run juju ssh-keys that key does not show up in the list?

So the full workflow:

  1. on computer 1: Run juju for the first time
    • ssh key generated and stuck on ~/.local/ on computer 1
  2. on computer 1: connect to controller
  3. on computer 1: connect create a model and add machines
  4. on computer 1: I can ssh into machine with juju ssh and it will use the key generated in ~/.local


  1. on computer 2: Run juju for the first time
    • ssh key generated and stuck on ~/.local/ on computer 2
  2. on computer 2: connect to controller
  3. on computer 2: try to ssh into model created from computer 1
    • Is this possible?
    • What key will be used?

This can be handled with juju users. By default there is an admin user who does the bootstrap. That admin can create user account with various permissions etc, even another admin.

From a 2nd machine, you juju register and juju login. That’s how juju knows that a user on a 2nd machine has permissions on the controller.

Details on users can be found here:

My question is, how does the CLI set the user’s ssh key to the one that it generated, though?

My use case is that I need to do exactly what the CLI does for its SSH key, except I need to do it for Juju Lens. I need Juju Lens to be able to generate an SSH key and then tell Juju to associate that key with a logged in user so that the user will be able to use that key to ssh into machines that they have access to.

When a user logs-in with the CLI, the CLI is able to somehow register the random ssh key that it generated with the Juju user account so that the Juju controller will make sure that every model that the user has access to will trust the key that it placed in the users ~/.local dir.

The Juju CLI appears to be able to tell the Juju controller to associate a certain ssh key to a certain user, but I can’t figure out how to do that through the API according to this API documentation.

There are more details on ssh keys with models here and what juju does at a high level: Juju - The simplest way to deploy and maintain applications in the cloud. Juju ssh is restricted to admin users. Though if you add a key ssh ubuntu@x.x.x.x should work.

Have you looked at this API?

@hatch, Is there any additional info you have on this?

1 Like

Ah, thanks for that link. This is what I was looking for:

Providing access to non-initial controller admin Juju users

In order for a non-initial controller admin user to connect with juju ssh that user must:

  • be created ( add-user )
  • have registered the controller ( register )
  • be logged in ( login )
  • have ‘admin’ access to the model
  • have their public SSH key reside within the model
  • be in possession of the corresponding private SSH key

…Otherwise access needs to be granted ( grant ) by a controller admin and keys need to be added ( add-ssh-key or import-ssh-key ) by a controller admin or the model admin.

So you must use juju add-ssh-key if you want to make sure that any user with admin access, that may not have initially been an admin, can ssh into the server. OK, thanks for the help! I think that covers what I needed to know.

I had looked at that API, but I was confused because you don’t need to add keys to ssh into a model that you have created. This is apparently because of the initial admin key setup of which I did not understand yet.

It’s only recently that we exposed admin access via the generated schema so that the libraries (js[1] and python) could access it.

  1. Not quite true, js already had this in the old schema format, but not in the new one.