API.md 8.58 KB
Newer Older
ale's avatar
ale committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
API
===

This document defines a generic API to expose user accounts and
associated resources to UIs and management tools, so that they can
delegate privileged operations to a dedicated service.

The focus is on making adding resources and functionality as simple as
possible, to support diverse service ecosystems.

We'd like to make it possible to create a generic, extensible UI for
account management, which would deal with the UX workflows, leaving
the implementation-specific details to the (custom) accountserver
service. Such application would initially support standard operations
on resources: adding functionality should require only adding a bit of
UI-related code to the application (and the implementation-specific
support on the server side).

## Data model

The accountserver data model provides a high-level representation of
user accounts and associated resources, decoupled from the underlying
database implementation (which likely consists of inter-related SQL
tables or LDAP objects). Such high-level representation is targeted at
humans, either users themselves or administrators.

The top-level object is an *account*, representing a user's identity.
Accounts contain a number of *resources* (of different types), which
it owns - meaning that it has administrative control over them.

Resources can be of different types (mailboxes, websites, mailing
lists, etc), each associated with a different service. In some cases,
resources can themselves contain other resources, to represent a close
association of some form (the semantics will be service-specific, an
example could be a website and its associated MySQL database, which
should be co-located).

Resources have a *name*, which must be globally unique for resources
of the same type. Resources within an account are uniquely identified
by an *ID*, which combines type and name and is a globally unique
identifier:

    <id> = <type>/<name>

The resource type `account` identifies the account itself.

Each resource type supports a number of *actions* that can modify the
state of resources. The specific actions and their semantics will need
to be documented (see [Schema](#schema) below), and need to be agreed
upon by the UIs/tools and the accountserver, but this scheme is easily
extensible.

## Interface

The accountserver provides an HTTP endpoint operating as a RPC server.

Request bodies should be JSON-encoded, same as responses.

#### get(*account_name*)

Returns (public) information on an account and all the resources
contained in it.

#### action(*account_name*, *resource_id*, *action*, {*args*})

Perform a generic action on the specified resource.

### Authentication

All requests should be authenticated. We assume that there is a way to
identify certain users as *administrators* (for instance via group
membership). Action handlers in the accountserver implementation have
the option of choosing between two different ACL checks (and only
these two):

* *user*:
  * allow a user access if the resource belongs to the user's own
    account
  * allow administrators access to this action for any account
* *admin-only*:
  * only administrators have access to this action

In more detail, there are two options that could be implemented,
depending on the specifics of the authentication system used:

* *Trust the UI and tools*: authenticate the connection with the
  accountserver, and trust the front-ends with their own internal
  access control checks (so that, for instance, user x can not modify
  data belonging to user y).
* *End-to-end verification*: pass an authentication token for the user
  from the front-ends to the accountserver, and verify it on every
  request. This puts the trust on the authentication system itself,
  regardless of potential issues in the front-end implementation.


## Schema

The *schema* describes the known resource types and the actions that
can be performed on them, along with their parameters.

What follows is a sample schema, every resource type is described along with
the attributes that it supports and the actions that can be performed
on it.

### account

Represents a user account, or an *identity*. It is the primary
identificator for users in the system.

Attributes:

* `status`: one of *active*, *inactive*, or other states that might be
  necessary to implement more complex state machines related to
  account activation
* `otp_enabled`: true if OTP 2FA is enabled
* `u2f_enabled`: true if U2F 2FA is enabled
* `u2f_registrations`: list of U2F registration IDs (not the keys
  themselves though)

Actions:

* `set_password`: change primary account password to a new one
* `enable_otp` / `disable_otp`: enable or disable OTP 2FA
* ...

### email

### mailing list

### web hosting (website / db / FTP account or equivalent)

...
ale's avatar
ale committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286


# API Reference

## User endpoints

The following API endpoints invoke operations on an individual
user. Access is allowed for admins, and for the user itself.

Most requests dealing with encryption keys are so-called *privileged*
requests, and will require the user's password in the *cur_password*
parameter in order to decrypt the existing encryption keys.

### `/api/user/get`

Retrieve information about a user and all its associated resources.

Request parameters:

* `username` - user to fetch
* `sso` - SSO ticket

### `/api/user/change_password`

Change the primary authentication password for a user. This operation
will update the user's storage encryption keys, or initialize them if
they do not exist.

Request parameters:

* `username` - name of the user
* `sso` - SSO ticket
* `cur_password` - current valid password for the user
* `password` - new password (unencrypted)

### `/api/user/set_password_recovery_hint`

Sets the secondary authentication password (a hint / response pair,
used to recover the primary credentials) for a user. This operation
will update the user's storage encryption keys, or initialize them if
they do not exist yet.

Request parameters:

* `username` - name of the user
* `sso` - SSO ticket
* `cur_password` - current valid password for the user
* `hint` - the secondary authentication hint
* `response` - the secondary authentication response (effectively a
  password, unencrypted)

### `/api/user/enable_otp`

Enable TOTP for a user. The server can generate a new TOTP secret if
necessary, or it can be generated by the caller (usually better as it
allows for a better validation UX).

Request parameters:

* `username` - name of the user
* `sso` - SSO ticket
* `totp_secret` - new TOTP secret (optional)

### `/api/user/disable_otp`

Disable TOTP for a user. Existing 2FA credentials will be wiped as
well.

Request parameters:

* `username` - name of the user
* `sso` - SSO ticket

### `/api/user/create_app_specific_password`

Create a new application-specific password. 2FA must already be
enabled for the user. A new random password will be generated by the
server and returned in the response. A new copy of the encryption key
will be encrypted with the new application-specific password.

ASPs are identified by a unique random ID that is also automatically
generated by the server.

Request parameters:

* `username` - name of the user
* `sso` - SSO ticket
* `cur_password` - current valid password for the user
* `service` - service that the password should be valid for
* `notes` - a user-controlled comment about the client

### `/api/user/delete_app_specific_password`

Delete an application-specific password (and the associated encryption
key).

Request parameters:

* `username` - name of the user
* `sso` - SSO ticket
* `asp_id` - ID of the app-specific password


## Resource endpoints

These API endpoints manipulate individual resources regardless of
which user they belong to. Access is normally granted to admins and to
the user that owns a resource, but some operations are restricted to
admins only.

### `/api/resource/enable`

Enable a resource (admin-only).

Request parameters:

* `resource_id` - resource ID
* `sso` - SSO ticket
* `comment` - notes on the operation

### `/api/resource/disable`

Disable a resource (admin-only).

Request parameters:

* `resource_id` - resource ID
* `sso` - SSO ticket
* `comment` - notes on the operation

### `/api/resource/move`

Move a resource between shards (admin-only).

Resources that are part of a group (for instance websites and DAV
accounts) are moved together, so this request might end up moving more
than one resource.

Request parameters:

* `resource_id` - resource ID
* `sso` - SSO ticket
* `shard` - new shard

### `/api/resource/create`

Create one or more resources associated with a user. Note that if
creating multiple resources, they must all belong to the same user.

Request parameters:

* `sso` - SSO ticket
* `resources` - list of resource objects to create