Our needs are a little different as well, because each service may need to reach out to a third-party service and we are holding a bearer token for the third-party service on behalf of the user. We provide that to the services behind an auth middleware through a header.
(We had considered changing this from an Auth Service to a general User Service, but I am strongly leaning toward having a separate User Service and leaving Auth tightly constrained.)
1) Authentication data (login id?, password) 2) Personal data that is not used in an online manner (depends on the site of course) (full name, email address, etc.) 3) Data that shows up on the site
If this data is segregated in to separate silos with no 'read everything' apis exposed to the web servers, you might stand a chance of not leaking all of your users data when the web servers are compromised. This of course will not help you if the authentication servers are also compromised.
I was imagining a social-network use case while reading the post, so when a similar objection came to mind, the answer seemed obvious: make "users" and "accounts" separate things. The business-logic keeps around its own "users" table. The business logic can, and must, index that.
Each user then HAS A account; there's a 1:1 correspondence. The accounts are in a separate service (a AAA microservice, effectively) that exposes this minimal API where you can only talk about individual accounts to it.
How does a backoffice user-management dashboard do its job? Like the name suggests, by reading off the users table—and then doing O(N) queries to the accounts service to effect changes. These sort of one-off administrative operations are allowed to be costly like that.
> It should be accessible only via its specialised API which is designed to constrain the ways that it is accessed.
Constrained in what ways? Especially in management / support roles you may need to do bulk actions against users (full listing, bulk changes, etc) so I'm not sure what constraints would be compared to a normal database.
> Its API should have password salting and hashing built in.
I disagree; I think password hashing should happen before the data hits the database.
> Its API should throttle access with some sort of algorithm designed to prevent downloads of large quantities of user data.
Does someone have an implementation idea for this? Depending on the type of user data we're talking the data could be very small. So the throttling may have to be quite significant but even then what's to prevent the attacker from bypassing it by using multiple connections? Multiple threads that each request a subset? I don't think you can get around those and still have a performant system.
> It should encrypt data internally.
How? Does it encrypt using a passcode specified by the system administrator (which means it exists somewhere on the system or nearby system making it decrypt-able anyway)? Or does this mean encryption using the user's password thus separating the data? If so how do you handle the cases when administrators need to modify the user's information for support or other reasons?