diff options
Diffstat (limited to 'doc/arch.mdwn')
-rw-r--r-- | doc/arch.mdwn | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/doc/arch.mdwn b/doc/arch.mdwn new file mode 100644 index 0000000..6b9eaea --- /dev/null +++ b/doc/arch.mdwn @@ -0,0 +1,183 @@ +--- +title: "Architecture of Salami, an authorization server" +author: QvarnLabs Ab +date: work-in-progress +... + +# Introduction + +**What.** Salami is an authorization server. At this stage, it is an +[OAuth2][] authorization server, but later on it will grow into a +provider for [OpenID Connect][]. Salami controls access to a web API: +the API client authenticates itself to Salami, gets an access token +from Salami, and gives the access token to the API server. This +de-couples the acts of authentication and authorization and resource +access, which simplifies the individual software components. + +[OAuth2]: https://en.wikipedia.org/wiki/OAuth +[OpenID Connect]: https://en.wikipedia.org/wiki/OpenID_Connect + +**Why.** Salami is not the first server of its kind. We wrote Salami +because we wanted something we liked: + +* is fully free, open source software +* has a simple, clear architecture and implementation +* has a chance of being accepted into the Debian distribution +* is simple and fast to install, and configure +* is simple, transparent to operate +* scles to many requests per second, many identities +* is flexible and easily extensible, as far as authentication methods + go +* is robust and reliable +* is stable + +**Web, not enterprise.** We operate in a "web environment, which is +different from a typical enterprise or large organisation environment. +We do not care about "single sign-on" across unrelated services, for +example. + +**Why not an alternative.** We've used [Gluu][], but for our uses it +is cumbersome, and not simple. + +[Gluu]: https://www.gluu.org/ + +**Usage driven development.** We develop Salami mainly based on the +needs of actual users, not to complete feature comparsion matrices. + +## Glossary + +* access token + +# Current state + +**Currently, Salami does not exist.** We have just started developing +it. The first development phase of Salami aims to produce an OAuth2 +authorization server that supports the client credential grant only. +This means only the API client authenticates itself to Salami, but not +the actual end-user. This is so that we can use Salami with the +[Qvarn][] server and have the Qvarn API tests pass. + +[Qvarn]: http://qvarn.org/ + +Further, the first development phase aims for a simplistic OAuth2 +server. For example, the list of API clients will be hardcoded in the +configuration file. This is acceptable to get development started, but +soon after that we will add features such as dynamically registering +clients. + +## Vision for the future + +In the longer term, we aim for Salami to be an OpenID provider using +the OpenID Connect protocol. This includes being able to have the +end-user authenticate and authorize use of resources. We will make it +simple and flexible to provide authentication methods (such as +username/password, client-side certificates, and U2F tokens). + +Eventually, we aim to have Salami certified as a compliant OpenID +Connect implementation. + +We also intend to make Salami be flexible, easy, and secure. + +# Known problems and things to solve later + +The main problem of Salami at this stage is that it doesn't exist. All +other problems can be derived from that. + +We don't have a good way of rotating the token signing keys. + +# Requirements + +For the first development phase of Salami, our acceptance criteria +are: + +* setting up a Salami instance is simple: the software should be + provided as a Debian package installable on Debian 9 (stretch), and + a corresponding Ansible playbook that configures the instance + +* configuring a Qvarn instance to use the Salami instance is simple: + the Ansible playbook for Qvarn should be updated to work with Salami + instead of Gluu + +* the Qvarn API tests pass + +Once we have that working, we will add more requirements. + +## Non-requirements + +At this stage, we do not care about speed, portability, or other such +qualities. We care about security enough that we want to avoid any +glaringly obvious security issues, but, for example, we don't care +about storing API client secrets in an encrypted fashion. + +# Architecture overview + +Salami provides an HTTP API interface for authentication. The only +relevant endpoint is `/token` and to use it, the client must +authenticate itself using its "client id" and "client secret" using +HTTP Basic Authentication. A successful response will have the access +token in its JSON body. + +A request: + + POST /token HTTP/1.1 + Host: salami.example.com + Authorization: Basic c2FsYW1pOnBhc3N3b3Jk + Content-Type: application/x-www-form-urlencoded + + grant_type=client_credentials?scope=version + +A successful response: + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "access_token": "CAFEF00D", + "token_type": "bearer", + "expires_in": 3600, + } + +The client should extract the access token (`CAFEF00D`) and add it to +any requests it makes to the resource server: + + Authorization: Bearer CAFEF00D + +The client does not need to understand the token, it merely copies it +into requests it makes. + +## Components + +Salami consists of several components + +@startuml +title Salami components +component [API client] as client +node "Salami" { + component [Haproxy] as haproxy + component [Salami\nbackend] as backend + component [Salami\nconfiguration] as config +} + +client -> haproxy : 2. https +haproxy -> backend : 3. http +backend <- config : 1. read at startup +haproxy <- backend : 4. access token +client <- haproxy : 5. access token +@enduml + +**haproxy** is a load balancer. For Salami we use it to provide TLS +for communication with the client. + +The **backend** implements the actual Salami HTTP endpoints and +creates and returns access tokens to the client. + +The **configuration** lists the API clients (the id, the secret, and +any scopes the client is allowed to have), as well as the RSA keys +used to sign the access token. The API provider (Qvarn) will be +configured to know the public RSA key so that it can verify that an +access token has been created by Salami. + +The client and haproxy use TLS. haproxy and the backend use plain +HTTP, but they will be deployed in an environment where the plain text +communication cannot be overheard, such as via the `localhost` +interface (haproxy and backend would run on the same host). |