6.5 KB
Newer Older
ale's avatar
ale committed
1 2 3

4 5 6 7
The *accountserver* is the main interface used to manage the database
of user accounts. Other internal services use it to query and modify
user account information (settings, credentials, etc). It implements
all the validation and business logic related to accounts.
ale's avatar
ale committed

9 10
Motivations for this service stem from our experience with previous
account management strategies:
ale's avatar
ale committed

12 13 14 15 16 17 18 19 20 21 22
* the necessity for a high-level API on top of the database layer
  (*accounts* and *resources*, instead of nested LDAP objects or SQL
  tables), isolating applications from the database structure;
* the desire to have a single authoritative implementation of the data
  validation logic, and to have every change to the database go
  through it;
* a wish for a cleaner separation between the business logic of
  complex operations ("disable a resource", "move an account between
  hosts", etc) and their UI. In our ideal model, user interfaces (web
  panels, admin tools) are simply thin clients focused on presentation
  and interaction, and the logic is implemented in RPC servers.
ale's avatar
ale committed

24 25 26
The service is implemented as an RPC service, without any user
interface. This approach has been preferred over others (like a
library for clients to embed) for a few reasons:
ale's avatar
ale committed

28 29 30 31 32 33 34
* information on accounts and resources might be aggregated from
  multiple backends (an LDAP database, Redis, MySQL for Noblogs, etc)
  and we'd like to limit the proliferation of network flows;
* privilege separation: only the accountserver needs write credentials
  for the backends;
* a single centralized service offers a simpler target for
  logging and monitoring.
ale's avatar
ale committed
35 36

## Data model
ale's avatar
ale committed

39 40 41 42 43 44 45
The [data model]( offered by *accountserver* is quite
simple: the top-level object is the *user* (an *account*). Each user
owns a number of *resources*, which can be of different
types. Resources have a loose hierarchical structure, and might
themselves contain sub-resources, expressing an association of some
kind (as for instance between a website and the associated MySQL
ale's avatar
ale committed

47 48 49 50 51 52
This data model is meant to work with our legacy user database, but it
is slightly overkill for the simplest cases: for instance a simple
email service might consider users and their email accounts to be the
same thing, while this model would present them as a *user* object
containing an *email* resource with the same name. It is however at
least easily adaptable to most use cases.
ale's avatar
ale committed

The schema is explicitly defined in [types.go](types.go).
ale's avatar
ale committed
55 56

## API
ale's avatar
ale committed

The service API is documented in [](
ale's avatar
ale committed
60 61

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
## Extending the service

The business logic (account creation, validation, and all the
high-level operations defined on them) is currently implemented as Go
code within the accountserver itself, in the *actions_\*.go* and
*validators.go* files.

There are specific notes on how to add and modify functionality in

## Testing

Running the integration tests requires, beyond a working Go
development environment, a JRE: we start a test LDAP server locally
(which is written in Java) in order to test the LDAP backend.

On a Debian system this should be enough:
ale's avatar
ale committed
80 81 82 83 84

sudo apt install default-jre-headless

85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107

# Usage

The *accountserver* daemon simply listens on a port for HTTP(S)
requests. Specify the address to listen on with the *--addr*
command-line option.

## Configuration

The configuration is stored in a YAML file, by default
*/etc/accountserver/config.yml*. Known variables include:

* `shards`: map of shards by service, for sharded (partitioned) services
  * `available`: map of available shards by service name,
    e.g. `{"web": ["1", "2"]}`. Used in resource creation.
  * `allowed`: map of allowed shards by service name
* `sso`:
  * `public_key`: path to file with SSO public key
  * `domain`: SSO domain
  * `service`: SSO service for the accountserver
  * `groups`: list of allowed groups
  * `admin_group`: a specific group that will be granted *admin* privileges
    (the ability to read/write data about different users than oneself)
ale's avatar
ale committed
108 109 110 111 112 113 114 115 116 117 118 119
* `http_server`: specifies standard parameters for the HTTP server
  * `tls`: server-side TLS configuration
    * `cert`: path to the server certificate
    * `key`: path to the server's private key
    * `ca`: path to the CA used to validate clients
    * `acl`: TLS-based access controls, a list of entries with the
      following attributes:
      * `path` is a regular expression to match the request URL path
      * `cn` is a regular expression that must match the CommonName
        part of the subject of the client certificate
  * `max_inflight_requests`: maximum number of in-flight requests to
    allow before server-side throttling kicks in
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
* `user_meta_server`: connection parameters for
  the [user-meta-server]( backend
  used to store user audit logs
  * `url`: URL for the user-meta-server service
  * `sharded`: if true, requests to the service will be
    partitioned according to the user's *shard* attribute
  * `tls_config`: client TLS configuration
    * `cert`: path to the client certificate
    * `key`: path to the private key
    * `ca`: path to the CA used to validate the server
* `auto_enable_encryption`: if true, automatically enable user-level
  encryption when a user changes their primary authentication
* `forbidden_usernames` / `forbidden_usernames_file`: list (or file)
  containing forbidden usernames
* `forbidden_passwords` / `forbidden_passwords_file`: list (or file)
  containing forbidden passwords
* `available_domains`: list of available domains for email resources
* `website_root_dir`: root directory of user websites
* `min_password_len`: minimum length of passwords (default 8)
* `max_password_len`: maximum length of passwords (default 128)
* `min_username_len`: minimum username length (default 3)
* `max_username_len`: maximum username length (default 64)
* `min_backend_uid`: minimum auto-assigned UID (default 1000)
* `max_backend_uid`: maximum auto-assigned UID (default 0, disabled)
ale's avatar
ale committed
145 146 147 148 149 150 151 152 153 154 155 156 157
* `ldap`: configuration for the LDAP backend
  * `uri`: LDAP URI to connect to
  * `bind_dn`: LDAP bind DN
  * `bind_pw` / `bind_pw_file`: LDAP bind password, or file to read
    it from
  * `base_dn`: base DN for all LDAP queries
* `pwhash`: password hashing parameters
  * `algo`: password hashing algorithm, one of *argon2* or *scrypt*
  * `params`: parameters for the selected hashing algorithm, a map
    whose values will depend on the chosen algorithm: *argon2*
    requires the *time*, *mem* and *threads* parameters (defaults
    to 1/4/4); *scrypt* requires *n*, *r* and *p* (defaults