ceo is a distributed HTTP application running on three hosts. As of this
writing, those are phosphoric-acid, mail and caffeine (coffee in the dev
environment).
* The `mail` host provides the `/api/mailman` endpoints. This is because
the REST API for Mailman3 is currently configured to run on localhost.
* The `caffeine` host provides the `/api/db` endpoints. This is because
the root account of MySQL and PostgreSQL on caffeine can only be accessed
locally.
* All other endpoints are provided by `phosphoric-acid`. phosphoric-acid is the
only host with the `ceod/admin` Kerberos key which means it is the only host
which can create new principals and reset passwords.
Some endpoints can be accessed from multiple hosts. This is explained more in
[Security](#security).
Interestingly, ceod instances can actually make API calls to each other. For
example, when the instance on phosphoric-acid creates a new user, it will
make a call to the instance on mail to subscribe the user to the csc-general
mailing list.
## Security
In the old ceo, most LDAP modifications were performed on the client side,
using the client's Kerberos credentials to authenticate to LDAP via GSSAPI.
Using the client's credentials is desirable since we currently have custom
authz rules in our slapd.conf on auth1 and auth2. If we were to use the
server's credentials instead, this would result in two different sets of
authz rules - one at the API layer and one at the OpenLDAP layer - and
syscom members would very likely forget to update both at the same time.
So, we want a way for the server to use the client's credentials when
interacting with LDAP. The most secure way to do this is via a Kerberos
extension called "constrained delegation", or [S4U](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/1fb9caca-449f-4183-8f7a-1a5fc7e7290a).
While the MIT KDC, which we are currently using, does provide support for S4U,
this [requires using LDAP as a database backend](https://k5wiki.kerberos.org/wiki/Projects/ConstrainedDelegation#CHECK_ALLOWED_TO_DELEGATE),
which we are *not* using. While it is theoretically possible to migrate our
KDC databases to LDAP, this would be a very risky operation, and probably
not worth it if ceo is the only app which will use it.
Therefore, we will use unconstrained delegation. The client essentially
forwards their TGT to ceod, which uses it to access other services over GSSAPI