This premise is weird at best.
"the database is the ultimate source of truth" is not a "dangerous, implicit assumption", is the best rule you can get (and the rest of the post say so: all useful data comes from it!)
Instead the rest of the article is interesting on how to choose what to use for the hash, but not follow with this first paragraph :shrug:
For most monolithic applications I think the whole issue is be a bit moot; if the rest of the application state is in the primary database, then an attacker with database access could presumably accomplish anything without the need to spoof another user at the authentication layer.
Lastly, this scheme doesn't provide any mechanism for rotating the pepper.
The attacker doesn’t need to read the database or invert any hashes. An attacker can simply register a legitimate account and generate his own valid API key."
No they can't, The given scenario has not pushed the auth into the database at all. if your accounts are also database accounts why does the user have permission to create new accounts.
I have done this as an experiment, I was dreading building a comprehensive auth system and noticed that the barely used postgres internal auth system is very well fleshed out so just made every user be a database user. The application has little concept of auth at all, it just passes the user login into the database connection and all the auth (logins, what data the user can get, what data the user can write) is all done as database policy. It worked surprisingly well, I don't know if I would use it on a real system(whatever that means, pg logins probably do not scale) The idea still sort of makes my skin crawl, Nobody does it this way, I assume for a reason. But in theory it is fine.
I probably got the idea from the schemaverse game, where the whole game is internal to postgres, and the users are given direct select access.
Far too many systems don’t have a zero downtime key rotation.
You're worried about SQL injection attacks? Why are you allowing untrusted clients to do anything other than call stored procedures? They can attack the DB? Why can't they attack the backend?
And sure: cryptographically binding a password to a username in storing a durable credential doesn't hurt, I guess, and it's cheap enough. (But why are you using bearer tokens in the first place?)
My objection is only the tacit assumption in the article that a "database" is some kind of distinct object that somehow accrues special superpowers and vulnerabilities relative to any other kind of service.
A database engine is just one choice of service implementation technology, like Go or Python. A database is just a service. Any service can be insecure.
I'd rather invest time in writing a proper DB abstraction layer for new systems or audit all parts where the DB is accessed in an existing system than implement the suggested measure.