OAuth2 - Can a trusted Client access User resources with Client Credentials flow - security

Looking at this explanation of the client credentials grant type from the OAuth website:
The Client Credentials grant type is used by clients to obtain an access token outside of the context of a user.
This is typically used by clients to access resources about themselves rather than to access a user's resources.
In case the client is a trusted app (internally developed), is it ok for it to access users' resources?
Technically, the app isn't the "resource owner" of these resources, but because it's a "super" app, developed internally, it should be able to access them, for the sake of implementing the organization's business requirements.
For example - think of your user in Google. The Google maps app creates resources owned by you (e.g places you "saved" on the map). Then, some Google daemon app with "super" permissions, can access those resources you created, in order to process them and show you relevant ads.
Does that make sense?
Thanks!
Simon.

Yes, that’s a fairly typically scenario in my opinion.
There are a few additional best practices to consider for your trusted client like storing secrets in a key vault, rotating the secret on a schedule, limiting and logging administrator access, etc.

Related

How does an Azure Active Directory app registration establish trust?

The Microsoft docs state:
Registering your application establishes a trust relationship between your app and the Microsoft identity platform. The trust is unidirectional: your app trusts the Microsoft identity platform, and not the other way around.
What exactly is meant by "trust" here and how does the app registration establish said trust?
The way I understand it the registration basically makes the app known to the AD, but how does that make the AD, the app is redirecting to for interactive logins, more trust-worthy to the app? Couldn't a malicious AD just pretend to know any app that's using it for logins? Wouldn't it need some kind of shared secret to assure the app that the AD really is the AD? And isn't HTTPS establishing that trust already?
It makes more sense to me the other way around: the AD receives a login request along with a redirect URI set by the app. But if the redirect URI is not known to the AD then the request is not trust-worthy and will be rejected.
I'm probably misunderstanding something, so could someone please explain the idea behind this?
In authentication world trust is a complicated word. In my opinion, the easiest way to approach this thing is taking the Google Sign-In -button as an example. You can use it to log in with your Google account on almost every website out there. Does this mean Google trusts every website out there using it? No, of course not. Do those websites trust Google? Sure they do, they have no visibility if Google returns the correct information about the users to them.
The case is very similar here as in most cases you will be using the same protocol to implement it (OAuth2 OIDC).
You are correct, you need to configure secrets & returnUrls to make sure that the App Registration is not used for malicious purposes, however, this does not create trust between the identity provider and the application. It's just technical measures to protect the client.
However, you can of course trust the application if you want to. The most common way is to grant it access to scopes so the application can do actions on behalf of the user. Usually this is done by those consent screens you probably know ("grant access to your email and phone number"). In enterprise setting, they are often omitted and access is granted with admin constent.
TL;DR; There is no inherit trust just because there is an App Registration, however you can trust an app to access user data.

Method for site wide authentication?

I am currently looking for a method to provide site wide authentication, for services exposed to the cloud, on the site I am responsible for. Some services are a Python based, some in PHP and some in Perl. Individual services would need to be able to get access to the user profile and the associated roles.
On the main page users are logged in and a cookie is created using a JWT token. The main site is using NodeJS for the auth system and is built in-house.
At this point I am wondering whether we should use OAuth2 across the site or whether there is another approach that may be simpler, where we don’t need to deal with inter domain requirements?
The approach you're currently investigating is the re-use of a JWT as an authentication token across multiple services. Although it's technically possible - it is not the ideal secure approach.
The most secure approach is for separation of application contexts, whereby each application should be tied to a different application credential (in OAuth2 terms). This is ensures that the user receives a credential unique to that application, allows the credentials to be managed/revoked separately and audited in isolation.
To implement this smoothly for UI flows requires an identity provider that supports SSO, and also assumes that each UI application can handle negotiation to the IDP to access that SSO session.
For interactions that are system to system authenticated, eg. Python, you would need to use system to system authentication (OAuth2 client credentials) that again have its own credential. In the case where you need access to the end-user's profile, a management api key (or similar) would be required.

Should the server to server authentication include User on which behalf the request is made?

I am going to implement security (using Identity Server 4). I have mobile application (front end) and few microservices (back end).
General scenario is that User_John calls Service_A_API using User-JWT token (obtained with Device flow). In order for Service_A to complete request, it has to access some data from Service_B. Service_A is calling Service_B using Server2Server-JWT token (obtained with Client credentials flow).
Server2Server-JWT is "Full access" token, allowing Service_A to do operations on any user on Service_B (e.g. it can delete user's order, update user's money balance, etc.)
Concerns that I have:
Is it correct to assume that Server2Server-JWT can have some long lifetime (e.g. 10-20 minutes) and it can be used for many requests originated from many different users?
Assuming Service_A and B are hosted in AWS (Dockers), is the Server2Server-JWT secure in those service's memory? What if (and how) the Server2Server-JWT get stolen?
Should Service_A request new Server2Server-JWT token for every user to call Service_B (and e.g. store this UserId in Claims)? Or is it safe to assume that Server2Server-JWT is safe in memory, and can be reused for any user request within the lifetime span of the full access Server2Server-JWT token?
Is Hybrid flow an answer to create a Server-to-server token on behalf of a user? Or is it something else?
My source of info are:
http://docs.identityserver.io/en/latest/topics/grant_types.html
https://www.pluralsight.com/courses/asp-dotnet-core-oauth2-openid-connect-securing
I definitely can answer the last question and only try with the rest.
Hybrid is a kind of interactive flow where one app has both client and server parts. Interactive means that a user goes through the IdP's portal to get authenticated.
Mobile apps usually run Authorization Code authorization flow with PKCE extension which all together behave pretty similar to hybrid where the "client" is a mobile browser and the "server" is the app itself.
No place for an API. But... you can look into the Extension Grant docs. Allows to implement Service Credentials on behalf of a user, exactly what you want, but... probably you don't need that with AWS.
They offer Network firewalls built into Amazon VPC, and web application firewall capabilities in AWS WAF to create private networks, and control access to your instances and applications. Together with "Customer-controlled encryption in transit with TLS across all services" that might be more than enough. The decision is yours.

Is it possible to use/forward certificate information from key credentials to a bearer token (Azure AD)

I have a scenario where I have to let external systems have access to one of our internal API's.
The security team want the externals to use client certificates as the preferred authentication method, so that basically leaves us two options:
Use direct client certificate authentication. It will give us the most control, but that will leave all the certificate handling and validation in our hands, and I'd rather not do that if I have a choice. Besides - direct client certification auth does not play well with our existing authentication methods on that API. If you turn on client certificates on the App Service, you will require a certificate on every request (and most requests on that API use cookies)
Add key credentials to the Azure AD app. We'd rather not give access directly to the app the API is registered on, so we register a OUR-APP-EXTERNAL and set up a trust relationship between the two. So the client authenticates with a certificate to the "external app", gets a bearer token and use that on our API. I'd prefer to use this solution, and it seems to play nicely with everything else.
So far so good - but I'm worrying about scaling this. We have to separate the external clients somehow (each client will in effect be different systems in different companies). One strategy is to create one AD-app per external system (OUR-APP-EXTERNAL-SYSTEM-A), but it seems cumbersome and somewhat spammy. One quick and easy solution would be to add some metadata from the client's authentication certificate (where we could just set what system this cert is issued to during creation), and add that to the bearer token.
Is this possible? Or are there other ways to handle "multi tenant" external clients?
Thanks
Consider an option of using Azure API Management for your scenario. API Management provides the capability to secure access to APIs (i.e., client to API Management) using client certificates. Currently, you can check the thumbprint of a client certificate against a desired value. You can also check the thumbprint against existing certificates uploaded to API Management.
Follow this guide - How to secure APIs using client certificate authentication in API Management
Also you can create multiple Azure AD Application for different clients and provide provide required roles to each of these Azure AD application to Azure AD Application registered to secure Internal API.
Follow this guide for this approach - Protect an API by using OAuth 2.0 with Azure Active Directory and API Management

what's the different between the OAuth 2.0 client credentials flow and Certificate credentials

I want to write a daemon service to visit customer office 365 resource by application identity, from document i found there are two ways to support it one is https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-client-creds and the other is https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials. I want to know what's the different between them and which is the beat solution to implement a daemon service.
thanks
Based on my understanding, the only difference between them is that certificate credential provides a higher level of assurance. For example, you can control the expired time of the client_assertion you generated flexibly. Even it is leaked, the damage will be minimized based on the lifetime of client_assertion.(This is only suppose that HTTPS is not security). If the shared secret was leaked, we will not able to limit it before we detect it and disable the secret.
More detail about client credentials flow, you also can refer link below:
Service to service calls using client credentials (shared secret or certificate)

Resources