OAuth 2.0 has become the protocol of choice to secure web API's. It requires a user to authorize an application to access your web API.
You want your application to be the only one that can access certain API's. OAuth 2.0 allows doing just that.
In your authorization server, implement the Authorization Code Grant with client credentials required (not optional). Make it so that only your app (or a configured list op first party apps) can acquire the scope required to make those API calls. As long as you keep your client secret a secret indeed, your app will be the only one able to get an access token with the required scope. In the web API, ensure the scope is granted to the access token used to call the API.
Good authorization servers, such as The Identity Hub, will allow you to do just that.
Do not use the Resource Owner Password Credentials Grant. As the specification says:
The credentials should only be used when there is a high
degree of trust between the resource owner and the client (e.g., the
client is part of the device operating system or a highly privileged
application), and when other authorization grant types are not
available (such as an authorization code).
This is repeated later on:
The authorization server should take special care when
enabling this grant type and only allow it when other flows are not
viable.
If the password credentials grant is available, any application can acquire a token by asking the user for a user id and password. This is exactly what you do not want.
The specification is very clear about the problems inherent to using passwords:
In the traditional client-server authentication model, the client
requests an access-restricted resource (protected resource) on the
server by authenticating with the server using the resource owner's
credentials. In order to provide third-party applications access to
restricted resources, the resource owner shares its credentials with
the third party. This creates several problems and limitations
OAuth 2.0 was designed specifically to overcome some of the issues with using passwords:
OAuth addresses these issues by introducing an authorization layer
and separating the role of the client from that of the resource
owner. In OAuth, the client requests access to resources controlled
by the resource owner and hosted by the resource server, and is
issued a different set of credentials than those of the resource
owner.
Furthermore, if your API wants to know the user (in addition to knowing the client app), it is impossible to abuse the Resource Owner Password Credentials Grant to authenticate the client (i.e. app) instead of the resource owner (i.e. user), as suggested by Florent Morselli.