If we pose a question "Why not use a non-expiring access token, and not bother with a refresh token?", the answer would probably be "Because if an access token is stolen, the malicious actor has X time (the lifetime of the said non-expiring access token) to perform malicious acts on behalf of the user that token was generated for." So the way that problem is solved, as far as I understand, is by, on successful authentication, sending the user a token-pair of a short lived access token, and a longer lived refresh token. I don't see how this isn't just an attempt at circumventing the original problem. The problem apparently lies in the theoretical possibility of the access token being stolen. So that if it ever is, it's validity expires quickly, so the malicious actor can't be authenticated for a long time. In this hypothetical situation, if whoever can steal the access token, why can't they steal the refresh token instead? The usual answers I got were something along the lines of:
I guess my question is:
"If we assume that there are any inherent vulnerabilities with the concept of the access token, or with using it, or with how it's stored etc... What makes the refresh token less susceptible to these vulnerabilities?"
Whilst the security properties of both the access token and the refresh token "at rest" are the same indeed, the difference is that "in transit" a refresh token is easier to secure than an access token because of the way it is used, as explained below.
Firstly the access token is only ever sent to the Resource Server(s), the refresh token is only ever used towards a single Authorization Server. A Resource Server is considered less trusted in many scenario's (the Authorization Server is - by design - a trusted component for the Client) and as you mention, there may be a lot of them which may have different levels of security that apply to them.
Secondly, the refresh token flow towards the Authorization Server may use a "rolling refresh" of the refresh token which means that at the time of access token refresh, a new refresh token is issued as well, which invalidates the old refresh token. This is a pretty common implementation pattern for Authorization Servers.
Lastly, and perhaps a bit of a long shot, the access token is used in many more requests than the refresh token so the chances of any vulnerability that applies to the transport layer (timing attacks) are proportionally increased.