geldata / geldata/rfcs

Authentication schemes for HTTP/Websockets

Open
#5 9 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
38
Forks
5
PR merge metrics
No merged PRs in 30d

Description

This adds to RFC 1001 at #4

# Overview

Features supported by HTTP:
1. `Authorization` header
2. `Cookie`
3. Basic and digest auth by browser (unusable)

Features suported by browser-based WebSockets:
1. `Cookie`
2. Authentication protocol packets
3. Basic and digest auth by browser (unusable)

Authentication schemes:
1. [OAuth2](https://oauth.net/2/) -- the most popular one
2. [OAuth1](https://oauth.net/1/) -- deprecated by OAuth2
3. [SAML](https://en.wikipedia.org/wiki/Security_Assertion_Markup_Language) -- we probably want in commercial version
4. [LDAP](https://ru.wikipedia.org/wiki/LDAP) -- doesn't map to the web by itself. Often used to validate username/password (not something we want to do) or to assign permissions by group (currently we're going to implement ACL in edgedb itself)
5. [Kerberos](https://web.mit.edu/kerberos/) -- usually relies on system libraries providing authentication and not widely used outside of large enterprises and academia

Related protocols:
1. [SCIM](http://www.simplecloud.info/) -- identity management. Basically a way to create and manage accounts with unified (REST) API. Could potentially replace our `CREATE ROLE`/`ALTER ROLE` statements, but out of scope of this research.
2. [WS-Federation](https://en.wikipedia.org/wiki/WS-Federation) -- does look like ecosystem of its own, with lots of standards including authorization

Commercial providers:
1. [Auth0](https://auth0.com/) -- basically provide JWT+OpenID-Connect (OIDC) identity after authentication
2. [Authentiq](https://www.authentiq.com/) -- is also a similar OIDC provider
3. [Atlassian Crowd](https://confluence.atlassian.com/crowd/overview-of-sso-179445277.html) -- looks like uses cookie for the actual authorization
4. [Okta SSO](https://www.okta.com/products/single-sign-on/) -- supports OIDC, SAML, and whatever they call "Secure Web Authentication"

Related tools:
`. JAAS, Pac4J, Apache Shiro -- java scpecific, not researched closely (but look like just Java interfaces for all other protocols)

# Requirements

1. Same or similar authentication for both HTTP and WebSockets
2. Scheme should work both in browser and using custom clients
3. Don't accept login/password or anything directly derived from it, so client doesn't need to keep password in memory for reconnects. And also to avoid handling 2FA. Use external application to verify passwords and multi-factor authentication and only authorize connection in edgedb.

# Proposal

Generally authentication should work by providing a [Bearer token](https://tools.ietf.org/html/rfc6750) which is either:
1. An opaque token, in this case such token should be inserted into the edgedb database by the application beforehand
2. A Self-Encoded access token, that implements OpenID Connect (OIDC) specification

The downside of (2) is that it's harder to revoke already created token, while the downside of (1) is that edgedb needs to keep track of all the tokens that are active now. Upside of (1) is that it's possible to integrate with more systems (in particular ones doesn't support OIDC, or that support OIDC in the way that is incompatible to edgedb).

The token can be transmitted in the one of three ways (all can be used interchangeably):
1. `Authorization: Bearer ` -- works for HTTP as well as non-browser websockets
2. `Cookie: =` -- works everywhere, but can be problematic to set a cookie for a domain that is devoted solely to edgedb (we may add a mechanism for that later)
3. As a `param` in [`ClientHandshake`](https://edgedb.com/docs/internals/protocol/messages#clienthandshake), this works on WebSockets only and is needed for browser-based websockets where using `Cookie` is not apropriate.
> We could use `AuthenticationSASL` with appropriate mechanism to provide token, but we don't need extra security here (i.e. passing token in the `ClientHandshake` is at least as good as passing it in the `Authorization` header, which is an accepted security practice). Keeping less round-trips for authentication is useful.

[RFC6750](https://www.rfc-editor.org/rfc/rfc6750.html) allows passing access_token as form-encoded body parameter and as URI query parameter. We don't allow that now, but we may consider adding them in future if compelling use cases arise.

Configuration:
1. Configure `cookie_name` in the "port" configuration
2. Any things needed to configure to make ACLs work (to be determined when ACLs implemented)

It's unclear whether we want to allow configuring JWT parameters in particular encryption schema. Also I expect secret keys to be generated and replicated within the edgedb itself, but we can have a mechanism to provide users' keys.

# Structure of the Self-Encoded Token

TO DO: research OpenID Connect

# Future Extensions

In the future, we should consider at least following ways of authentication:
1. SAML
2. TLS Client ceritificates
3. Kerberos

All of them might only be supported in commercial version.

**Update:** Note on RFC6750 of access_token usage

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.