Oauth2 vs APIKey in a server to server communication
This is an interesting topic and there are a couple of things to consider. First we need to come at it from the API provider, not just the consumer.
Who?
The main consideration is Authentication vs. “Identity” and Permissions. Refresher:
- Identity = Who say you are
- Authentication = Who you really are
- Permissions = What you can do
Check out this post for more detail on API ID and Permissions.
While, in this instance permissions may be implicit (where by virtue of being authenticated you are able to use the API), consider this: As the provider of an API to a service with the level of sensitivity payments require, I want to know that the consumer is who they say the are.
Passing an API Key only confirms that you have the API Key: it does not prove that you are authorised to access the API.
Now, possessing an OAuth Access Token may initially be viewed the same, however the OAuth RFC states
The authorization server MUST authenticate the client whenever possible.
OAuth enables this by providing refresh token, as you said, along with a registered redirect URI. It also suggests a minimally scoped token for all initial and re-authentication requests.
This gives the API provider much more control, more visibility and thus more confidence that their API has not been compromised.
OAuth also plays nicely with permissions. If the payment gateway company decided to extend authentication to require permissions to GET and to POST, this would be less work and more secure than if you had to try to tie a key to permissions.
Exposure
A secondary but relevant consideration is what to do if the API Key is exposed.
I know I want be able to trust the key, however it might have been breached. So I also whitelist the clients IP... IP’s can change, depending on configuration, and they can also be spoofed... How can I know if the key is being used nefariously or not?
If the API key is then re-issued post breach it can be easier for someone to determine possible new keys once the initial key is known. This means that the providers key gen algorithm may also need to be adjusted.
If you were issued an Access Token that somehow got exposed, once it comes up for refresh, the unauthorised user should not be able to get reauthorised. I can log them log this erroneous request and work with the consumer to diagnose root cause.
Summary
The API key was only ever meant to serve as a form of ID. As such they are basically misused when implemented as a primary security measure.
If API Consumers need to be authenticated - as in you need to verify the caller of the API and provide access to certain resources based on that verification - OAuth is the better choice.
Hope this helps!
NB For arguments sake, I have assumed no one has root access to your internal services or network, and all over-the-wire comms are via HTTPS.
API key/client secret makes more sense for service to service communication, which seems to be your scenario from what I gather (your backend to their API service).
Having said that, OAuth 2 has a client credentials grant flow, which can do some sort of API key/client secret/certificate based authentication - check with your third party provider to see if they support it.
Usually OAuth 2 is associated with the authorization code grant flow, which is good when the user agent is a browser since that was what it was designed for, but not appropriate for service to service.