Spyderisk / domain-network

Network domain model
Apache License 2.0
1 stars 0 forks source link

Discussion: OAuth-style Authorization Code Flow #115

Open mike1813 opened 7 months ago

mike1813 commented 7 months ago

If one service 'controls' another service, it means the first service is an OIDC/OAuth-style credential management service which controls access to the second service using an OIDC/OAuth-style credential exchange workflow.

If the second service usesForAuthZ the first, it means the credential exchange workflow uses the Authorization Code Flow pattern, rather than the simpler Implicit Flow pattern. The client of the second service obtains an authorization grant code (a special type of token) from the first service, presents it to the second service, and the second service exchanges it for an access token from the first service.

The interesting question is whether the second service should authenticate to the first in this situation. The first service can only respond with a token, or an error code. If the second service sends an invalid authorization grant code, an error code will be returned. If the code is valid, an error code may still be returned if the OAuth client (the second service) is not authorized to use this authorization grant type, or failed to authenticate.

However, authentication of an OAuth client (the second service) is mandatory only if it is a 'confidential client'. Some authorization code grants could be accessible to any client, even to an anonymous client. In that case, it should be sufficient to send a valid grant code.

If we have a simple scenario, a client of the second service (an OAuth User Agent) is redirected to the OAuth service, from which it gets a grant code (represented by a 'usesForAuth' relationship) and sends it to the second service, which exchanges it for an access token from the OAuth service. (represented buy a 'usesForAuthZ' relationship). If the OAuth service authenticates its clients, that would be expressed by asserting controls representing the authentication mechanism. It is therefore easy to handle the case where the OAuth service does authenticate (by enabling the controls), or where it does not (by not enabling the controls).

It gets more complicated if the OAuth service is controlled by another OAuth service, also using the authorization code flow. This seems an unlikely scenario if we're dealing with standardised OAuth services, but in the domain model the same relationships can represent any similar credential exchange pattern, even if the services involved do not comply with the OAuth specification. (Hence we do no assume a service with those relationships uses TLS, even though that is mandatory under the OAuth 2.0 specification).

One such pattern is where a key vault is controlled by an OAuth service. The key vault is a credential management service, which issues keys (a form of token) allowing access to data resources. An Authorization Code Flow pattern is appropriate where the keys are passed to a service (corresponiding to an OAuth client role) that will decrypt the data on behalf of its client (an OAuth user agent). If access to the key vault is controlled by an OIDC service, which is a common pattern, we end up with nested 'controls' and 'usesForAuthZ' relationships.

In that situation, the user agent must authenticate with the OIDC service to obtain a grant code (Auth Code Flow) or key (Implicit Flow) from the key vault. In the fAuth Code Flow, the service that will be using the key then presents the grant code to the key vault to get the required access key. The presence of a 'controls' relationship implies this service must also authenticate with the OIDC service, but in fact this may not be necessary if this service is a 'public' client of the key vault service. In that case, the key vault would determine the validity of a key request on its own, based only on the grant code presented to it.

This is all a little uncertain, given that (a) OAuth allows the possibility to authenticate or not, and (b) we're not necessarily talking about a fully compliant credential exchange service - just one that uses the same credential exchange workflow. On that basis, we can't reasonably change the current interpretation of the 'controls', 'usesForAuth' and 'usesForAuthZ' relationships. What would be interesting is to try out different combinations, e.g., can we use 'usesForAuthZ' without a reversed 'controls' to cover a wider range of possibilities?

So - at least for now this is a 'Discussion' issue just to raise the questions:

Noting that credential exchange patterns are 'distinct' if and only if they create different opportunities for attacks on the client-service relationships (i.e., different threats).