Is there a way to bypass key/token-authentication in ManagedOnlineEndpoint (SDK-v2)? - azure-machine-learning-service

According to SDK-v2's ManagedOnlineEndpoint documentation, auth_mode must be provided thru key or aml_token. This means, once the endpoint is deployed, we need to include the api key or token when we send POST requests to the API. I'm wondering if there's a way to bypass providing these authentication methods, e.g., thru Azure ManagedIdentity?
My motivation for bypassing the key/token authentication is that, I have an ML model (deployed via ManagedOnlineEndpoint) that needs to call multiple other secondary ManagedOnlineEndpoints and then use their outputs as input-features in the (main) model. It would be nice to not have to manage API-keys for those secondary model endpoints.
I have a solution that works, but I'm curious if there's an alternative or more elegant way of doing it.
The current solution is, I'm storing APIkeys of the secondary models in Azure KeyVault and then retrieve them when needed, i.e., defined in the scoring script of the (main) model.

Use managed identity for seamless access to your resources. Here is the Document to access Azure resources from an online endpoint with a managed identity.
The identity for an endpoint is immutable. During endpoint creation, you can associate it with a system-assigned identity (default) or a user-assigned identity. You can't change the identity after the endpoint has been created.

Related

Azure API Management - Authenticate and Authorization sync with underlying services

I am new to Azure API Management and will be happy to receive suggestion and advise on my implementation.
I am developing a B2B Api Channel for 3rd parties to call my services via the API Management (APIM) Gateway. On the APIM developers portal I can onboard new clients and generate API key. My struggle is how best to figure out at the underlying services who is calling?
I have considered add the API Key generated in the APIM to a database which the underlying service will call to authenticate, however, the implementation will be manual and will not be in sync when the 3rd party client goes to APIM and regenerate a new API key.
What I want is a solution that auto syncs authorization and authentication between APIM and the underlying services.
Since API keys can be replaced, you better rely on IDs to identify clients.
You can pass a client ID to a backend in a header: https://stackoverflow.com/a/42277313/2579733
Now how do you correlate APIM's client IDs with your backend's client IDs?
If there are only a few clients, you can probably update that association in your backend's database manually. If you can use the clients's email to connect the APIM client and your backend client, that's even easier (you're done).
If you will need to register many clients and the manual approach is not feasible... One way to do it is with Delegated Authentication:
Delegation allows you to use your existing website for handling developer sign in/sign up and subscription to products, as opposed to using the built-in functionality in the developer portal. It enables your website to own the user data and perform the validation of these steps in a custom way.
I never used it but it seems you can transfer the responsibility of creating new clients to a backend service (developed by you).
This way you have access to client emails, you generate IDs and can store the ID relationship in the backend as necessary.

Azure B2C Microservice Authentication and GraphQL Layer

We have few micro-services that are used by a UI. Azure B2C is our auth provider. Each micro-service(API) requires an access token and needs to talk to a database for authorization. This database has role based access permission.
This is how it looks today:
With this we have two problems:
As Azure B2C do not allow adding scopes from multiple resources into one access token, we have to get multiple access tokens.
We are now at a stage where the UI need to call two or more APIs to display the data on one page.
We wanted to use GraphQL as an API Gateway. Something like this:
All the micro-services are placed inside a private vnet and only GraphQL API is allowed to talk to them. GraphQL Layer handles all authentication and authorization.
Now the questions are:
Do you see any problems with this approach?
Is it okay to use a client and secret for communication between GraphQL layer and other API's? or Is there an provision in Azure B2C that can do this validation with out GraphQL layer requesting individual access tokens?
what are the additional advantages of adding Azure API Management to this (other than logging, analytics, rate limiting etc)? Do I need to worry about SSL termination?
Option 2 looks like a good architecture.
A common pattern is for the UI to call a dedicated 'entry point' API, which then orchestrates calls to microservices in a private network - as in your second diagram.
Eg an Online Sales UI calls only an Online Sales API
This also helps to keep UI specific requirements out of microservices and keep responsibilities clean.
In OAuth terms as you say there will be a single resource - the entry point API - and you should only need a single access token.
The entry point API's token (or its claims) can then be forwarded directly to Microservices and used to identify the user there if needed.
I'd avoid getting additional tokens for microservices and just enforce authorization based on roles from your user database.
In some cases it may also make sense to also enforce rules such as 'Online Sales API not allowed to call Payroll microservice'.
Personally I would develop entry point APIs using the same technology as microservices.

Best practice to send secure data from azure webhook

Unfamiliar with handling secure data but now I've began working in azure, specifically with a dynamics instance and logic apps. The webhook needs to give the external api secure data such as ssn. What's the best way to go about sending secure data like this over network? Oauth2 is implemented but is there something else I can implement so we are not directly sending the ssn?
Always using SSL (HTTPS) is a secure way to send data over the wire. I believe a little more added security would be to use Certificate and Public Key Pinning if possible.
Also, another way to secure sensitive data would be to first store it in Azure Key Vault and share the reference to that secret in your webhook call to the Logic App.
The Logic App would then acquire the secret from Azure Key Vault using Managed Identity.

Multi Instance Apps and Azure Authentication Best Practices

We have a multi-instance Saas Application:
Each of our clients is given their own instance and their own subdomain for the site.
Our application (Web app & API) is protected by Azure, currently with the ADAL javascript libraries
We also have a second API for system-level integration that needs to be protected, currently using a second 'native' azure app, but this is likely incorrect and we want to consolidate
Our application reads and writes to the Azure AD both through the AzureAD Graph API and Microsoft Graph API (including password reset calls)
We're looking at Azure AD application configuration options and want to make sure we're building the most sensible and secure Azure AD Application. Here are some of the documentation we've been looking at:
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-client-creds
https://learn.microsoft.com/en-us/azure/architecture/multitenant-identity/
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-compare
We want the application to be multi-tenant to ease configuration, and allow availability in the Gallery; but when looking into doing so we're left with some security questions.
A. Which application version to use
1) v1. Allows access to both Graph API. And as suggested by Microsoft we should use this when we're not concerned with Microsoft Accounts.
2) v2. When looking at the MS Graph API documentation it recommends using v2. Reportedly doesn't work for AzureAD Graph API? Allows the same app to be of multiple types (Web App/API and native), which we may or may not need to protect both our web api and our system api (which we're still trying to model).
B. How to manage the reply URL when our clients have different sub-domains?
I've noted the following options:
1) On the app registry, we add the reply urls for all of our customers. This seems okay because we only need to do it once, but feels odd. Is there a limit to the number of reply urls?
2) Have one reply url, but manage an external tool to route the responses to the correct instance, leveraging the state url parameter. Microsoft seems to be suggesting that in this link: https://learn.microsoft.com/en-us/azure/architecture/multitenant-identity/authenticate I'm not sure if ADAL allows us to set the state for a return subdomain url though. Is this approach common?
3) Is it possible for each ServiceProvider instance in our client's directories to configure the reply url to their own subdomain? I feel like this would be the cleanest approach, but I don't see documentation for it. It would be nice if we could set the replyURL programmatically as well.
C. How to manage authorization to the Graph APIs (AzureAD and Microsoft Graph)
I've noted the following options:
1) Use the client credential flow, with a single application key (used for all clients). As clients subscribe they will admin consent with our app to give the application permission to their directory. Of course we'd do our best to keep that key secure. But if for some reason it was compromised this would put all of our clients at risk, not just the one instance that was compromised.
2) Same as 1, but use a certificate instead of a secret key. I understand this could be a little more secure, but I don't see how it wouldn't suffer from the same issue as 1.
3) Instead of using application permissions, use delegated permissions with an admin user. This would be good, in that it inherently prevents one instance of our app from talking to the wrong directory. However changes to the administrator may interrupt service; and I think it is best audit-wise that our application is responsible for the changes it makes. (Also, do delegated permissions allow for password resetting? I know for app permissions you need to run powershell script to upgrade the application's directory role)
4) Is there some way for the service principal to generate a unique key for it's directory on creation? can this be handed back to our app programmatically? Perhaps during admin consent?
Really good questions. I'll try to answer each to the best of my knowledge, but if someone has other ideas, feel free to comment/add your own answer.
A. Which application version to use
v2 should allow you to call Azure AD Graph API. The documentation you linked shows an example of specifying Azure AD Graph scopes:
GET https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=2d4d11a2-f814-46a7-890a-274a72a7309e&scope=https%3A%2F%2Fgraph.windows.net%2Fdirectory.read%20https%3A%2F2Fgraph.windows.net%2Fdirectory.write
The main decision point if you should use v2 is: Do you need to support Microsoft accounts which are not in an Azure AD? If yes, you need to use v2. Otherwise there is no problem using v1 (well, lack of dynamic permissions).
Since you are using Azure AD Graph to modify things, I'm going to guess pure Microsoft accounts will not work for you. I would recommend sticking with v1.
v2 also has some limits: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-limitations
B. How to manage the reply URL when our clients have different sub-domains?
I could not find documentation on a limit for URLs. It could be that you can add however many you want. But I am not sure :)
If your subdomains look like this: https://customer.product.com, you can configure the reply URL as:
https://*.product.com
It will then allow any subdomain to be specified in the redirect_uri.
Though note that at the time of writing this, wildcard reply URLs are not supported in v2.
C. How to manage authorization to the Graph APIs (AzureAD and Microsoft Graph)
Using multiple keys makes no sense as they are all equal anyway :) Any of them could be used to call another tenant.
You can store the secret/certificate in an Azure Key Vault, and then use Azure AD Managed Service Identity to get it on app startup.
I would prefer using delegated permissions, but if the users of the app won't have the rights to do the things your app needs to do then that does not work.
I would just make sure it is not possible for a customer's instance to call to the APIs with another tenant id. And also make sure token caches are separated in such a way that it is not possible to get another tenant's access token (an in-memory cache on the instance would be good).

Preferred approach for inter-service communication in microservices/SOA

In my architecture, I have several internal services that need to communicate with each other. I also have a identity access management service that stores information about users, roles and (coarse-grained) permissions.
Components (not exhaustive):
Service A
Service B
IAM service
Rather than giving services A and B full access to each other via IP whitelisting, I would like them to run as users who are managed by the IAM service. So the services need a way of interrogating each other's roles and permissions. I've considered the following approach:
I create opaque API keys for the users that the services will be running under. I store them on each service. When service A calls service B, it passes its API key. Service B then calls the IAM service to validate the key and acquire information about service A's roles before processing the request. Service B caches its responses from the IAM service to reduce chattiness.
I've seen solutions that involve an API gateway, but this assumes that the traffic is coming outside the network. I do not want to redirect internal traffic to the outside just for the sake of converting opaque tokens to by-value JWTs.
Opaque by-value tokens are really intended for the following purposes:
Reducing token size to a minimum (for client efficiency)
Hiding the details of what claims a user has as they dont need to know
Forcing a lookup of the claims on each request (so you can revoke/change tokens instantly)
You are on an internal network so payload size isnt as big of an issue and you probably don't care about leaking claims to other services. If your claims arent changing often then opaque tokens probably arent needed. This means that your service simply needs to request an maintain a by-value token to access internal resources.
Thats not too bad.
If you do need to convert by ref to by value on every request, or you want to simplify the auth loop for consumers a proxy approach is best. This would intercept requests to your service and replace the by-ref token (or perhaps apikey) with a by-value token. The advantage here would be that you have more detailed control over usage of by-value tokens, and your clients dont need to care about your internal security infrastructure.
This approach adds more overhead in exchange for more control. Its also fine to call through this from your internal services.
I wrote a bit about the authentication proxy pattern on my blog.

Resources