Nexmo / nexmo-cli

Nexmo CLI (Command Line Interface)
https://nexmo.com
MIT License
78 stars 52 forks source link

[Discuss] Create Nexmo Application config file upon app creation #109

Open leggetter opened 7 years ago

leggetter commented 7 years ago

The main motivation behind the potential need for a configuration file is that the application_id should always be saved somewhere upon application creation. There are other values that are returned from POST /applications that should also probably be stored by default and I believe we should consider making the Nexmo CLI do this by default.

{
  "id": "95ce0260-c23b-4783-b110-1987532b8f63",
  "name": "test-app",
  "voice": { "webhooks": [
    {
      "endpoint_type":"answer_url",
      "endpoint":"https://example.com/answer",
      "http_method":"POST"
    },
    {
      "endpoint_type":"event_url",
      "endpoint":"https://example.com/event",
      "http_method":"POST"
    }
  ] },
  "keys": 
  { 
    "public_key": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n",
    "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
  },
  "_links": { "self": { "href": "/v1/applications/95ce0260-c23b-4783-b110-1987532b8f63" } }
}

As an initial suggestion:

  1. Saving the id and keys values a nexmo_app.json config file
  2. Save the contents of private_key to a nexmo_private.key and make the value of private_key in the config the name of the saved file.
  3. Save the contents of public_key to a nexmo_public.key and make the value of public_key in the config.
  4. Don't save name, voice (which should really be an application type) as these values can change and the config will get out of sync.

Note: is there a better naming convention for public and private keys whilst still making it clear these are Nexmo app key files?

sammachin commented 7 years ago

There is already an option to write the private key to a file on app creation,

I'm not sure how much benefit there is to writing the app id as its easy enough to get it in the list from nexmo apps if you miss it the first time.

Is the public key used for anything by the developer? I hadn't even noticed it TBH!

adambutler commented 7 years ago

I think this should be one file or a directory as I wouldn't particularly like to add three files to the root of my project. Furthermore this would mean one exclusion would need adding to a .gitignore file.

There might even be potential for storing the certificates in the the keychain.

Secondly I personally would prefer prefixing any such file with . and making the file name more generic for example .nexmo or .nexmo.json

leggetter commented 7 years ago

There is already an option to write the private key to a file on app creation

Yes, there is. But if you forget to save it that time then it's lost. Part of my suggestion is that this is always saved and that you have to opt-out rather than opt-in.

I'm not sure how much benefit there is to writing the app id as its easy enough to get it in the list from nexmo apps if you miss it the first time.

I've had the problem where I've not stored the application ID a number of times. Finding it again has been a bit of a hassle and in a lot of cases I've ended up just creating a new application instead. Again, I'd say it's something that should always be saved.

Is the public key used for anything by the developer? I hadn't even noticed it TBH!

I don't believe it is used at present.

I think this should be one file or a directory as I wouldn't particularly like to add three files to the root of my project.

Good point.

Furthermore this would mean one exclusion would need adding to a .gitignore file.

Are . prefixed files/directories ignored by default? Or would we still need to add them to .gitignore? It is something we could automate.

There might even be potential for storing the certificates in the the keychain.

Do we then assume the user is on a specific runtime?

I personally would prefer prefixing the files with . and making the file name more general for example .nexmo or .nexmo.json

We should go with a well established convention. What does other similar tooling do? Can we provide some good examples to feed into the decision?

adambutler commented 7 years ago

Are . prefixed files/directories ignored by default? Or would we still need to add them to .gitignore? It is something we could automate.

No they are not, it's still handy as convention this is used to identify it as a configuration file and groups such files together (since they are alphabetically together) in a list of files such as when using ls -l or a editor project navigator.

Do we then assume the user is on a specific runtime?

I mean the system keychain. Supported on Linux & MacOS, I'm unsure if Windows has an equivalent.

We should go with a well established convention. What does other similar tooling do? Can we provide some good examples to feed into the decision?

Here are some examples:

.bowerrc

Is JSON format for configuring a package. I'm not in favour of the rc suffix and find this to be misused here since it stands for run command. This is appropriate for files like .zshrc where commands are run but not so much for configuration.

package.json

This file name is used by npm modules. It's become so ubiquitous that everyone knows what it's for but does not identify its purpose by name. There has been conversation about changing this but it seems to have stuck because it's too late.

.flowconfig

This file is used flow for configuration. I like this example as it is relatively new and created by developers (a little known company called Facebook) who are very well respected and informed by the JS community.

Perhaps a suffix of config should be considered to make it more explicit.


My suggestion is for .nexmo.json I've included the .json extension as it isn't likely for a .nexmo file to be recognised as being JSON format by editor grammars. We therefor need to be explicit about the file format.

You can see the JSON grammars file types supported by atom for instance here

cbetta commented 7 years ago

Excellent discussion. FYI currently your API credentials are stored in ~/.nexmorc or ./.nexmorc depending on the project. This allows anyone to have global API credentials, while overriding them on a local level.

Anyway, I think we should focus less on the implementation, and more on the use cases here. What are we trying to achieve?

I agree that currently the CLI is very verbose, and constantly requires me to provide app IDs, which are not very easy to use. It would be great to "switch" the CLI to a certain app. We can either do this globally:

nexmo switch app_name

Or we can do what Heroku does and try and determine some context on a per project basis. I would not want my keys to be stored in my project, but I probably do want to store in my project what Nexmo app is attached to this project.

Again, let's focus on use cases, then the implementation will arise from it.

sammachin commented 7 years ago

I don't think it should be a . prefix, most systems 'hide' these files from general view when you list for example ls -l won't show a .file only ls -la will. .files are better used for system configuration for example .gitignore but in this case the details form part of the project and may well not be related to the local system on which the CLI is run.

sammachin commented 7 years ago

I'm concerned about having this as the default and creating files containing security credentials automatically potentially anywhere on the system. There are plenty of scenarios where a developer may be creating an application and not ever needing the private key, e.g. an inbound only VAPI app. Therefore they could end up with files containing sensitive keys lying around their system.

sammachin commented 7 years ago

What should happen if there is an existing file named nexmo.json or whatever we are calling it? overwrite? fail? use alternate name eg nexmo_1.json

cbetta commented 7 years ago

I agree with most what's being said here.

Let's focus on the real usecase here though, and not solutions. Often solutions are simple once you properly understand the usecase.

So, what is the main user story we can come up with? This is my attempt:


Use case:

I feel this is a pretty simple use case but probably also the only one? Did I miss one?


To achieve this we need:

Did I miss anything?

sammachin commented 7 years ago

The app ID and private Key for a given app are not needed by the CLI itself to manage application level config that is still currently all done with APIKEY and SECRET although may well move to its own JWT/Private key in the future.

This is more about the CLI generating you a 'config file' for your application automagically rather than just outputting the values to the terminal for you to use as you want.

cbetta commented 7 years ago

@sammachin thanks for clarifying. So @leggetter what really is the use case? Can you help describe it a bit more structured?