Although orgHasUser calls are intended to prevent two instances of the same username in the same organization, there is a race condition that can realistically occur.
Fargate Task 1 receives a request to create "alice@example.com"
Fargate Task 2 simultaneously receives an identical request to create "alice@example.com"
Both Fargate instances open a connection to the primary DocumentDB instance and execute session.startTransaction(). DocumentDB provisions two separate snapshots for the two independent connections.
Fargate Task 1 checks if the user exists in its snapshot. Fargate Task 2 checks if the user exists in its snapshot. Both get a response of false.
Both instances of application code from separate Fargate tasks proceed to create the user. Similarly, DocumentDB accepts the write operations from both Fargate tasks.
This can, for example, happen when any organization writes their own GUI client for creating users and an accidental double press of the Create button sends two API requests. The client may receive both API responses and store the two different API keys for the alice@example.com user. Normally, the problem is limited to the fact that one API key will always work and the other will never work.
However, it's also possible to have a data breach where both of those stored API keys are stolen. Then, reset_secret can only change one of the two API keys. The organization may conclude that the other API key is irrelevant because it never works.
But, if the server database is ever later dumped and restored, it's possible that the order of the two alice@example.com users will change, and only the other API key then works. Thus, the breached credential data becomes valid for use.
There may be multiple ways to address this. For example, a BaseUser could have org_UUID and then there could be a compound unique index such as BaseUserMongooseSchema.index({ username: 1, org_UUID: 1 }, { unique: true })).
Although orgHasUser calls are intended to prevent two instances of the same username in the same organization, there is a race condition that can realistically occur.
Fargate Task 1 receives a request to create "alice@example.com"
Fargate Task 2 simultaneously receives an identical request to create "alice@example.com"
Both Fargate instances open a connection to the primary DocumentDB instance and execute session.startTransaction(). DocumentDB provisions two separate snapshots for the two independent connections.
Fargate Task 1 checks if the user exists in its snapshot. Fargate Task 2 checks if the user exists in its snapshot. Both get a response of false.
Both instances of application code from separate Fargate tasks proceed to create the user. Similarly, DocumentDB accepts the write operations from both Fargate tasks.
This can, for example, happen when any organization writes their own GUI client for creating users and an accidental double press of the Create button sends two API requests. The client may receive both API responses and store the two different API keys for the alice@example.com user. Normally, the problem is limited to the fact that one API key will always work and the other will never work.
However, it's also possible to have a data breach where both of those stored API keys are stolen. Then, reset_secret can only change one of the two API keys. The organization may conclude that the other API key is irrelevant because it never works.
But, if the server database is ever later dumped and restored, it's possible that the order of the two alice@example.com users will change, and only the other API key then works. Thus, the breached credential data becomes valid for use.
There may be multiple ways to address this. For example, a BaseUser could have org_UUID and then there could be a compound unique index such as BaseUserMongooseSchema.index({ username: 1, org_UUID: 1 }, { unique: true })).