Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EPIC: AUTH_API_KEY How to Run the App with a Single Environment Variable #42

Closed
4 tasks done
nelsonic opened this issue Mar 30, 2020 · 12 comments
Closed
4 tasks done
Assignees
Labels
discuss Share your constructive thoughts on how to make progress with this issue epic A feature idea that is large enough to require a sprint (5 days) or more and has smaller sub-issues. T1d Time Estimate 1 Day

Comments

@nelsonic
Copy link
Member

nelsonic commented Mar 30, 2020

As noted in the discussion in #34 ("How do we want to handle multiple applications using auth?"),
our objective is to let anyone connect to the App/API server or run the App on their localhost using a single environment variable: DWYL_API_KEY

  • Allow any person to create their own DWYL_API_KEY they can use for the App.
  • The DWYL_API_KEY should be the encrypted person.id so we can easily check if a Key is valid simply by confirming that it decrypts into an integer. 💡
iex(1)> key = Fields.AES.encrypt(1)
<<48, 48, 48, 49, 56, 39, 172, 166, 103, 23, 208, 232, 132, 247, 86, 129, 106,
  103, 135, 215, 140, 220, 234, 8, 178, 124, 86, 165, 28, 83, 55, 230, 137, 178,
  114, 127, 27>>
iex(2)> Fields.AES.decrypt(key)
"1"
@nelsonic nelsonic added epic A feature idea that is large enough to require a sprint (5 days) or more and has smaller sub-issues. discuss Share your constructive thoughts on how to make progress with this issue labels Mar 30, 2020
@nelsonic nelsonic self-assigned this Mar 30, 2020
@nelsonic nelsonic added the T1d Time Estimate 1 Day label Mar 31, 2020
@nelsonic
Copy link
Member Author

nelsonic commented Apr 1, 2020

The API Settings page should be clean focussed:

image

This is obviously just a rough sketch, but hopefully you get the idea.
(It should have some sort of navigation bar/menu to help people situate themselves, not shown here)

@nelsonic
Copy link
Member Author

The beauty of AES256 is that the person can create virtually infinite API keys for the same person.id:

iex(17)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMSqUAH1ReM2sSq1ILL4zlvZAAZsyMmP7Sj0FY1f90xCVUQ=="
iex(18)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMYLnkMAUa5NOpmrG/3fXIFLxWrAjw0FZN9McDv2rb5aikg=="
iex(19)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMfNpzWyscdnVbzbppQ7uahuzfK1rBdGoh7+daVppGakghw=="
iex(20)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMdduVysgIrxtKwerleB8rSw2M1r9RVQjFVXOr4+hwMKmJw=="
iex(21)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMfs/6SJmAifSRY8jg8G2GnDWrNLA0XyrCTEn4bEWjyjy+w=="
iex(22)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMdy9jIuuR9zrET7FmmGOYriqv+HI00cWH8iYBWnxMnk+gA=="
iex(23)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMb2x3dvOqs01MUwICRsS0fJCEga83gvc/UxdiCM3tXnCBw=="
iex(24)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMWZbJS4SFbaHrVFmGr0Bv/AfSo81iHNiVfQ6yQI4ylhNjQ=="
iex(25)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMf12pDPrjCxg2e1TsL9kjlQVSC5NCg0COksA4OfIH0oJhA=="
iex(26)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMSmxoCXciO6IzpoAy8B8XDzmph7/fbmzKYvdSpMtColuHA=="
iex(27)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMdiyS7VLEXQks78O4Oop5Fy9D5B0Qv+KaHgfRHefT5RtAg=="
iex(28)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMV2hnqNQhHakAQyiqH4AUnjEHfmjczo4XF+Z88ZQy3DbtQ=="
iex(29)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMR+i2AgANXskbNrrsStxpz754q+wyPx1q81UWLawYTu5kw=="
iex(30)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMfc8Vm5iY1ExdxwIYtLZUWo/G1sRLso+2r7ApSBFZNIuEQ=="
iex(31)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMdTIvtfEFg2q+K/DG9PrHZW+5k2birZo3oxlltcOmHhsmA=="
iex(32)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMX4WHSKaE0cBT5+r1ukNlekIoSEXgKZlGJytEM822rZsGA=="
iex(33)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMavN/nEPdzqabVKL7KPWgwKgMCpWKsJWNRpPV6n7YYK8sA=="
iex(34)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMXIxzgDULUDvlSVJjIAdRWSbiUG9E1rutDUcNeGFdl+5hQ=="
iex(35)> key = Fields.AES.encrypt(1) |> Base.encode64
"MDAwMfMp5raxCzgRgDjzZ0+yEP8ef0AImr6S65+v/p5TCiz29w=="

So the person can use their dwyl app data from an unlimited number of places
(think of services like IFTTT or Zapier or Excel macros where they analyse their data!)

@nelsonic
Copy link
Member Author

What are the desired fields for an API key schema/table?

  • person_id - references person.id
  • key_id - the id of the encryption key we used to create the client_secret
  • client_secret - the secret used to sign the JWT
  • name - e.g. my amazing key
  • description - optional description for the key
  • status e.g: "active", "test" or "suspended"
  • url - the url of the app. e.g: http:localhost:4000 or https://myapp.net
mix phx.gen.html Apikey Apikeys key_id:integer client_secret:binary name:string description:text url:binary person_id:references:people status:references:status  --no-context

Can you think of any other fields we might want to have for an API key?

@nelsonic
Copy link
Member Author

I freaking hate the totally unnecessary complexity that Phoenix Contexts introduces.

mix phx.gen.html Ctx Apikey apikeys key_id:integer client_secret:binary name:string description:text url:binary person_id:references:people status:references:status

But this is what we have after running that generator:
image

@nelsonic
Copy link
Member Author

Example of DWYL_API_KEY
image
Don't worry, this is not valid for any real data access.

@nelsonic
Copy link
Member Author

Slightly better styling:
image

nelsonic added a commit that referenced this issue Apr 24, 2020
@nelsonic nelsonic mentioned this issue Apr 24, 2020
2 tasks
@nelsonic
Copy link
Member Author

API key working with Base58.encode:
image

@nelsonic
Copy link
Member Author

nelsonic commented Apr 25, 2020

I think I'm going to store the keys as String in the database ... 🤔
But then again we have an effective way of looking up keys for a given person, 🔍
so we can store them as (encrypted) binary. 🔐

@nelsonic
Copy link
Member Author

Final version of the DWYL_API_KEY with a / splitting the client_id and client_secret
image

This means people only need one environment variable to use our app. ✅

nelsonic added a commit that referenced this issue Apr 26, 2020
nelsonic added a commit that referenced this issue Apr 26, 2020
@nelsonic
Copy link
Member Author

https://dwylauth.herokuapp.com/
image

https://dwylauth.herokuapp.com/profile
image

https://dwylauth.herokuapp.com/profile/apikeys
image

https://dwylauth.herokuapp.com/profile/apikeys/new
image

image

2cfxNaWUwJBq1F4nPndoEHZJ5YCCNqXbJ6GaSXj6BPNTjMSc4EV/2cfxNadrhMZk3iaT1L5k6Wt67c9ScbGNPz8BwLH1qvpDNAARQ9J

nelsonic added a commit to dwyl/auth_plug that referenced this issue Apr 28, 2020
@nelsonic nelsonic changed the title EPIC: DWYL_API_KEY How to Run the App with a Single Environment Variable EPIC: AUTH_API_KEY How to Run the App with a Single Environment Variable Apr 29, 2020
@nelsonic
Copy link
Member Author

Next: UX #51

@nelsonic
Copy link
Member Author

UX Complete. PR is reviewable! #43 :shipit:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discuss Share your constructive thoughts on how to make progress with this issue epic A feature idea that is large enough to require a sprint (5 days) or more and has smaller sub-issues. T1d Time Estimate 1 Day
Projects
None yet
Development

No branches or pull requests

1 participant