Skip to content

Commit

Permalink
Start improving documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nlachat-compassion committed Oct 24, 2024
1 parent 13bf1cc commit d829628
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
30 changes: 26 additions & 4 deletions auth_external/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
# Compassion CH External Auth
This module is intended to allow authentication and authorization to the odoo backend from various frontends (the first use-case is for the tranlsation platform, https://github.com/CompassionCH/translation-platform-web).
This custom module was required for the following reasons:
1. Odoo xmlrpc calls required to provide the (login, password) pair for each call, which required the storage in the user's browser. This would be a very important security risk, for example if an XSS vulnerability was discovered in the frontend.
2. Odoo xmlrpc calls do not support users who enabled 2FA.

For these reasons, this module was developped.

A typical user session plays out as follows:
1. The user makes a request to `/auth/login`, providing their credentials (`login`, `password`, optionally `totp`). If the credentials are verified (using the `auth_totp` module if the user activated 2FA), the server returns an object which includes (not exhaustive) :
- A JWT `access_token` which will be used to authorize the following xmlrpc requests. This token contains a Message Authentication Code produced using the `access_token_signing_key`, which allows to verify the authenticity of this token (without keeping state on the server for each token). This token remains valid a few hours (configurable through `auth_external.tokens_config`).
- A JWT `refresh_token` which will be used to refresh the `access_token` (and also the `refresh_token`). This is described below. This token remains valid a few days/weeks. This duration of validity determines the maximum period during which a user can not use the application and still remain "connected". If the user regularly uses the application, the tokens are refreshed and they could remain "connected" indefinetly without needing to re-submit their credentials.
2. The user uses their `access_token` to make xmlrpc requests to the odoo backend.
3. The user refreshes their tokens by making a request to `/auth/refresh`, providing their current `refresh_token`. If the `refresh_token` is considered valid (authentic, non-expired, non-revoked), a fresh (`access_token`, `refresh_token`) pair is returned, and the provided `refresh_token` is revoked.
4. When the user is done using the platform, they make a request to `/auth/logout`, providing their current `refresh_token`. This revokes all `refresh_token`s of the family (the original one obtained during login and the subsequent ones obtained through refreshes).

To get a more precise idea of how to use this module, have a look at `tests/test_auth_controller.py:test_full_2fa_user_lifecycle`.

# Security mechanisms
## Refresh Token Reuse Detection (RTRD)
This feature is heavily inspired by this article: https://web.archive.org/web/20240828080645/https://auth0.com/blog/securing-single-page-applications-with-refresh-token-rotation/#Automatic-Reuse-Detection
It prevents reuse of `refresh_token`s by keeping a list of the issued `refresh_token`s (see `models/refresh_tokens.py`).
The tokens are stored as a doubly linked list, the parent `refresh_token` being linked to a child `refresh_token` after the former was used to authorize the issuance of the latter.
Once a token is used to authorize a refresh, it is marked as revoked.
If a revoked token is submitted, it means that it was probably intercepted/exfiltrated by a malicious actor. In this case, we refresh all tokens of the token family, and the user has to submit their credentials again (through `/auth/login`) in order to use the platform again.

# TODO add access rules
2024-10-22 14:03:51,077 62965 WARNING t1486 odoo.modules.loading: The model auth_external.refresh_token has no access rules, consider adding one. E.g. access_auth_external_refresh_token,access_auth_external_refresh_token,model_auth_external_refresh_token,base.group_user,1,0,0,0


# TODO JWT library
Expand All @@ -12,8 +35,7 @@ https://github.com/jpadilla/pyjwt



# TODO security properties
Describe what you can expect from this module in terms of security properties


# Security considerations

Expand Down
4 changes: 2 additions & 2 deletions auth_external/data/tokens_config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<data noupdate="0">
<record id="tokens_config" model="auth_external.tokens_config">
<field name="issuer_id">compassion.ch</field>
<field name="access_token_duration_hours">2.0</field>
<field name="refresh_token_duration_days">27.0</field>
<field name="access_token_duration_hours">3.0</field>
<field name="refresh_token_duration_days">28.0</field>
</record>
</data>
</odoo>

0 comments on commit d829628

Please sign in to comment.