Skip to content
This repository was archived by the owner on Jul 23, 2024. It is now read-only.

RFC: API Design #75

Open
tyrannosaurus-becks opened this issue Jun 26, 2020 · 3 comments
Open

RFC: API Design #75

tyrannosaurus-becks opened this issue Jun 26, 2020 · 3 comments
Labels
question Further information is requested

Comments

@tyrannosaurus-becks
Copy link
Contributor

tyrannosaurus-becks commented Jun 26, 2020

Request For Comment

This Github issue is a Request For Comment regarding adding an administrative API to Approzium.

Background

Currently, to plant credentials for the Go authenticator to use in creating connections, people must directly place credentials in their storage back-end. They are placed as a JSON map, for example, these are placed for those using HashiCorp Vault:

$ vault write approzium/1.2.3.4:5432 [email protected]
# creds.json is: 
{
    "password": "asdfghjkl",
    "iam_arns": [
        "arn:aws:iam::accountid:role/rolename1",
        "arn:aws:iam::accountid:role/rolename2"
    ]
}

This approach is brittle. A slight typo on the user's end regarding the Vault path or the credentials will result in the Authenticator failing to locate or authorize use of the credentials.

We would like to add an API that improves user experience.

Proposal

At Startup

We will take a secure by default approach, since this is a security application.

  • We would fail if a credential manager wasn't configured for persistent storage.
  • If we didn't detect any administrators, we would provide a message like, "Welcome! Your username is admin, and your password is sdfhawieuninf (random high-entropy string every time)! We encourage you to create a new user under your real name and to delete this one when done".
  • Using this username and password, the admin could set up more administrators.
  • Usernames and passwords would be provided in every API request through basic auth.
  • Each admin would only be able to view and update their own password; they would be able to add and delete other admins at will. This is a naive trust model, but is intended for first-iteration design. Designing and implementing a policy system is out of scope for the original design.

Admin Management Endpoints

We would expose the following endpoints:

  • POST (create, update, delete) /v1/administrators/:username
    • password
  • GET (list response) /v1/administrators
    • // all the people

Credential Management Endpoints

We would expose endpoints specific to each database type for which we were given credentials. For example, since we currently support postgres:

  • POST (create, update, delete) /v1/creds/:human-friendly-name
    • dbhost: 127.0.0.1
    • dbport: 1234
    • username: bob
    • password: foo
    • grant_access_to: { iam_arns: [foo] }
  • GET (list response) /v1/creds

Endpoint Visibility

We would ensure that all endpoints were well described from the outset using Swagger, so that it would be easy in the future for others to build integrations with us, or for a UI to be built.

Comments/Thoughts Welcome!

This is an early-stage RFC and I am happy to edit it as your feedback arrives! Please don't hesitate to comment. :-)

@tyrannosaurus-becks tyrannosaurus-becks added the question Further information is requested label Jun 26, 2020
@kirklandnuts
Copy link
Contributor

This is great! One question I have is why does the db type (e.g. postgres) need to be part of the cred mgmt endpoint? Is this in case we end up storing in different structures for various db types?

@tyrannosaurus-becks
Copy link
Contributor Author

@timothydnguyen yeah, that's what I was thinking. So maybe for MySQL it would be /v1/mysql/:dbhost/:dbport. However, that's a very good question. Do you think it would be better if it were just /v1/:dbhost/:dbport?

On the plus side, it would be shorter. Also, the :dbhost field might already be rather descriptive, like it could be, my-company-mysql.

On the minus side, if the :dbhost were simply 127.0.0.1 for a bunch of locally accessible databases, it could be hard to reason about which one a cred is for by only looking at the ports.

Another option might be to make the endpoint something more like /v1/:human-friendly-name, and its parameters would be dbhost, port, username, password to return, and authorized iam arns.

@tyrannosaurus-becks
Copy link
Contributor Author

@UpGado @timothydnguyen I updated it above per our conversation, let me know if you have further thoughts!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants