Imagine you're running a service that implements an OAuth 2.0 flow to allow your end users to log into 3rd party apps, and authorize those apps to consume your service's data through some API.
Upon successfully authenticating a 3rd party app through your OAuth flow, your service sends the 3rd party app a bearer token that authenticates (and authorizes) the 3rd party app (on behalf of the end user) to use your service's API.
Such a bearer token needs to be stored on your servers, in order to perform authentication for incoming API calls. Since the bearer token authenticates (and authorizes) clients, you need to store it safely, like you would store a password.
However, while passwords are salted + hashed before saving them to disk, they are also looked up by their corresponding principal (username/email-address), rather than by the secure representation of the password.
In case of a bearer token, there is no principal to use for looking up matching credentials/tokens. Assuming you'd want to store bearer tokens like passwords (salted + hashed), you'd have to look up every possible salt, apply each one, then hash the salted token, and then check if it exists anywhere in your system. That doesn't scale.
So my question is: How can you safely store bearer tokens on your server? That is, without having to generate every possible secure representation of it whenever you need to verify a token.
By "safely store bearer tokens", I mean that an attacker who obtains the file of all "safely stored" bearer tokens won't be able to use them.