This series is a #100DaysOfCode challenge about the making of Passwordless.ID, a free identity provider with enlightening simplicity.
Playing with CORS🚦
At the earliest stage, I cleanly separated UI and API. The result were two distinct projects, deployed in two separate sub-domains:
- https://app.passwordless.id for the UI (not yet available)
- https://api.passwordless.id for the API
So, guess what would happen by default? Right, the UI cannot communicate with the API because of cross-origin requests. Scripts running in one "origin" are by default not allowed to communicate with another domain. Add sessions/cookies into the mix, and you have a whole bunch of HTTP headers to configure correctly.
Some people sometimes misunderstand things and think the client script should adapt the cross-origin requests. But it's the other way round, it's the server which decides from which origin it accepts requests or not. Well, that's partially true, if sessions are involved, the client must add a flag too.
As long as you clearly understand how it works and how to set the headers properly, it is not a problem though. What is a bit more tricky is once consider the DEV and PROD environment. The first runs locally, on localhost with two different ports for UI and API, while the other runs on api|app.passwordless.id.
Should the API always accept localhost
connections too or not? Does it constitute a security risk?
These are important considerations to think about soon. What does it imply? Well, users could manually copy the session cookie from the browser and use it locally. So, you could write a localhost server to trigger some script interacting with the API. Nothing more, nothing less. Is it dangerous? Well, not really, it would be the same as copying a script and pasting it in the browser console of the UI. No biggie. What would definitely be disastrous would be the wildcard CORS with full access rights. This would allow any arbitrary website to interact with the API and a widely open door for attacks.
You could use CORS for everyone, and actually that's what the passwordless API will do, it is just important to assign the proper rights depending on the origin. The app.passwordless.api will have full rights, while other origins will only have a very restricted access to some endpoints and HTTP verbs.
What about localhost? Well, it shouldn't be necessary to restrict it since localhost should not be an attack vector. Nevertheless, since "identity" is a sensitive topic and security is paramount, we will apply extra care and only accept localhost
connections in DEV using an environment variable flag. Better be safe than sorry and be extra cautious. The cost is just an environment variable and a little bit more code. After all, accessing api.passwordless.id from localhost would be bad practice anyway, although very convenient, especially during this prototyping phase.
The new Logo
The previous dev journal entry was about branding and the need for a logo. So I messed a bit with Inkscape and did some work to combine some icons to finally end up with a logo! The logo is quite on the complex side, with lots of shapes and colors, and probably lacks a bit simplicity, but well, it will do for now. 😉
Thanks for reading, see you next time!