IDM/Design

== Design overview ==
The Wikimedia IDM (Bitu) is implemented as a Django project, consisting of a number of custom "app" in Django terminology. The current target version of Django is 3.2, as this version ships with Debian Bullseye.
Currently implemented apps are:
* accounts
* keymanagement
* ldapbackend
* requisitions (partly implemented)
* signups
=== accounts ===
This app serves as a specialization of the Django user model, following best practices for Django project. See: https://docs.djangoproject.com/en/3.2/topics/auth/customizing/#extending-user. 
The app also serves as the entry point for users as they sign in, holding the "landing page".
=== keymanagement ===
One role that has been envisioned for the IDM, is to manage SSH keys and long term help rotate out deprecated or obsolete key types. The "keymanagement" app provides an interface for the user to upload and manage SSH keys. Keys are validate for as they are uploaded and keys deemed insure by the SRE or security team can be rejected.
=== ldapbackend ===
Another goal for the IDM has been to unify management of access across multiple systems, the ldapbackend serves as a trial implementation for plug-able backends. Backends are never allowed to be directly accessed by other apps, which should instead rely on dynamic loading of functionality from each backend, as configured in the IDM settings file.
The ldapbackend provides the IDM with the functionality required to provision new LDAP users and an interface for users to manage their own data in LDAP. Given that LDAP attributes may directly affect a users ability to login or use various systems, as well as security concerns, only those attributes with have been specifically added to an allow list may be edited.
=== requisitions ===
The primary reasoning for creating the IDM has been to allow for greater self-service when new permissions are required by a user. The requisitions app holds the code for requesting new permissions, as well that the code for validation and approval for the incoming request.
=== signups ===
Currently new Wikimedia Developer Accounts are created from WikiTech, making WikiTech as special wiki. The signup app is designed handle future user signups, allowing us to remove the extensions from WikiTech. 
The users is required to provide a username, email and password on signup. This information is stored in the IDM database, and an activation link is sent to the provided email address. If an account has not been activated within a certain number of days, the signup data is discarded. Similarly data is discarded once a signup has been completed and data has been transferred to the relevant backend systems.
For each system where the user is to be created and subsystem must be provided, the ldapbackend is the first of these subsystems. Each subsystem must provide a password hashing method, which is used to has the passwords provided during signup. Only the password hash is ever stored in the IDM, and only until signup as been completed or deemed abandoned.
== Technical Design ==
This part of the documentation aims to describe some of the technically design decisions and their implementation in the Bitu IDM. 
=== Use of packages ===
The use of third party packages should be kept to a minimum, to reduce the possible attack surface of the IDM, while still keeping in mind that custom written code will likely have more bugs than widely used open source packages. 
=== Authentication ===
Django provides an extendable authentication system which is used to for Bitu IDM. The goal is that allow any Django authentication system to work with the IDM, even if the WikiMedia deployment will only need the Django Social Auth module, for OIDC integration with Apereo CAS. 
=== Background tasks ===
Longer running tasks, such as synchronization with backends and emailing are handled using a queue. This is implemented using django_rq (https://python-rq.org/patterns/django/). This provides a queuing interface, build on Redis. Initially there are only two queue: default and notification. The notification queue is intended for anything that needs to send emails, while everything else falls into default.
=== Configuration ===
All BITU IDM configuration must be kept within the Django settings file, variables must be prefixed with "BITU_".
=== De-coupling ===
Part of the goal for the design of the IDM is to allow for reuse of the code by other organizations. These unknown organizations may not have the same infrastructure and systems as the WMF. As a result all "sub-systems", i.e. Puppet, LDAP and CAS, but be integrated in a way that allows these to be excluded or disabled. Integration into the IDM and Django provided functionality should happen in one of two ways: 
* Django signaling
* Dynamic imports, configured from the settings file, i.e. Module loading
Authorization backends are expected to provide the following functions:
* TBD
=== Expiring links ===
During the process of signup and for resetting passwords the users are email a link to a confirmation page. This is done to provide some level of guarantee that the person issuing the request is also the owner of the provided email address. To avoid hi-jacking or reuse of these links are protected using a cryptographic token. The implementation builds the solution provided by Django for password resets for the default database backed user model. See: https://github.com/django/django/blob/main/django/contrib/auth/tokens.py 
For both signup and password resets a custom version of the _make_hash_value function is provided.
=== Storage ===
The built in Django object model is used for database interactions. A MariaDB database is provided by the data persistence team. Stored data must only be relevant for auditing purposes or stored temporarily until the backend systems are updated. Any data which allow or deny actual permissions must be stored in their respective systems and be completely independent of the IDM. This design decision means that the IDM must be able to either directly read data from backends, or have the ability to synchronize the data at regular intervals. A positive effect is that users will be able to view existing permissions in the IDM as systems are being integrated.