I'm currently setting up a Kubeflow environment in Azure using AKS. Everything is set up and working (users are able to log into the kubeflow platform using Azure AZ credentials and start notebook pods in their own namespace). I'm assuming these AD credentials are embedded somewhere in the container creation process, and I'm wondering if it's possible to tap into these credentials for other services that are AD integrated?
Use case:
A user is working in a Jupyter notebook started from the Kubeflow platform. The user wishes to access data in an Azure storage blob. Instead of having to login to Azure from their notebook session, the container already has their credentials stored.
It sounds reasonable but I'm unsure if it can actually be done in a secure way.
Assuming you're following the instructions in Authentication using OIDC in Azure: no, this isn't possible using the default configuration.
The way OIDC works is by giving back a token with a given audience (who it should be used with) and grants (what it says you should be able to do). The token that's being issued to Kubeflow is valid for the Kubeflow service principal audience only; in other words, you can't then take that same token and use it with Azure APIs. This is by design, and is one of the key factors in OIDC security. Allowing Kubeflow to have the permissions to issue more tokens (typically via the user_impersonation grant) opens a fairly major security issue - now anyone who manages to compromise that application secret can get powerful tokens, instead of limited scope tokens as normally designed.
If the resources they need to access aren't specific to the users in question, aad-pod-identity could be used to grant an access token to the pods the users are running instead of requiring them to log in again.
Related
I have a rather (hopefully) theoretical question regarding the secure usage of Service Pricipals in Azure (Enterprise Applications)
Introduction
we currently deploy our DevOps Code via Azure Service Principals.
AppRegistration/Enterprise App is created
Secret is generated
Permission (i.e. Contributor) to the Ressource Group is granted in Azure
Service Connection is made in Devops
everything works fine.
Assumption
By default the Service Principal (Enterprise Application) is not restricted to a specific user/group (Assignment Required => "no").
My assumption is now, that every user in the AAD-Tenant is able to login to the Enterprise Application as well.
I i.e. do this by using the "Graph Powershell API"-EnterpriseApp.
I can either use a Secret or use my User Credentials to access the Service Principal and its permissions
Security issue?
coming back to our DevOps configuration:
The Service Principal has Contributor Permission on the dedicated Resource Group
Assignment Required is set to no (default configuration)
if I (as a malicious user) have the Application ID, i could simply logon to the Service Principal and receive the Token.
Question:
With this token and my login to the App, do i also have the Contributor Permissions of the App and could now manipulate the whole Resource Group?
Since i'm not an Azure Developer - but only an Azure AD Admin - my knowledge regarding this is limited,
so i'm not able to test it.
Can someone maybe either provide code or prove that my assumptions are wrong or correct?!
Thanks
Yes, the SPN can manage the resources within the resource group if it has Contributor - it is no different than a normal (human) identity.
Consider if the SPN actually needs Contributor or if you can limit it with another role or even make a custom role.
Furthermore, monitor the sign-ins using the Azure AD sign-in logs:
https://learn.microsoft.com/en-us/azure/active-directory/reports-monitoring/concept-all-sign-ins
You can also use CanNotDelete resource lock, which means that the service principal cannot delete resource as it is only Contributor:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/lock-resources?tabs=json
You might want to look into the Conditional Access to strengthen your environment:
https://learn.microsoft.com/en-us/azure/active-directory/develop/workload-identities-overview
https://learn.microsoft.com/en-us/azure/active-directory/conditional-access/workload-identity
https://learn.microsoft.com/en-us/azure/active-directory/privileged-identity-management/pim-create-azure-ad-roles-and-resource-roles-review
Take a look here:
https://infosecwriteups.com/a-lab-for-practicing-azure-service-principal-abuse-bd000e6c48eb
https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/disable-user-sign-in-portal
https://learn.microsoft.com/en-us/powershell/module/az.accounts/connect-azaccount?view=azps-9.3.0#example-3-connect-to-azure-using-a-service-principal-account
My assumption is now, that every user in the AAD-Tenant is able to login to the Enterprise Application as well.
No. They would need the client secret or the rights to generate a new one. Which requires that they are owners of the App Registration. In the App Registration on the Owners tab it says:
The users listed here can view and edit this application registration. Additionally, any user (may not be listed here) with administrative privileges to manage any application (e.g., Global Administrator, Cloud App Administrator etc.) can view and edit the application registrations.
Anyone has suggestions on how to implement automated key rotation for service account credentials used in the cloud function, AppEngine, GKE.
GCP has added this as one of the recommended security policies for cloud-native services. We can find APIs/client libraries to generate a new private key for the existing service account. But we don't really get how to update the newly generated key on the application deployed in AppEngine, cloud function during runtime.
When you are on Google Cloud components, you don't have to use service account key files. It's a bad practice (even if presented as "standard" in too many tutorials, even Google Cloud tutorials!).
A service account key file is a nightmare to manage. It's a file. You can copy it, you can send it by email, you can even commit it in source repository (maybe public repo!!). In addition, you need to keep it secure and to rotate it regularly...
The best way to simplify this, is to not use them and to rely on Google Cloud component identity. Of course, for all external component, like a CI/CD, an on prem app (or on other cloud provider), the service account key file is the best way to be authenticated on Google Cloud
For Cloud Functions, you can use Cloud Functions Identity
For GKE, you can use Workload Identity
For App Engine, you can rely on the App Engine default service account
For you local development, perform a gcloud auth application-default login to create a default credential with your own user account
In each case, you can recover the default credential in your code. (here an example of a simple credential, without client library, only Google OAuth2 lib)
Note: For some operation, App Engine default service account isn't usable (generate an identity token based on metadata servers or changing the scope of the access_token). For this, I recommend you to impersonate service accounts instead of using service account key file
We will be building a couple of non-interactive scripts and console applications which will be invoking the Azure DevOps REST API to do various tasks. These apps and scripts will be executed via a job scheduler. What authentication scheme would be the correct one to use for this scenario? It seems like a PAT would work, however, I really don't want the jobs to be tied to a specific user identity and Azure DevOps does not support service principles. Is the correct approach to establish a "fake" Azure Active Directory user and use that user as the owner of the PATs? Is there something else that I am missing here?
Looking at the Authentication Guide, it seems like all of the mechanisms referenced result in some form of interactivity.
Also, we have Conditional Access Policies being enforced in our Azure DevOps organization. One of those policies is the requirement for MFA. If we use a PAT, how will that work? According to this link, it sounds like access may be blocked.
Personal access tokens (PATs) are used for personal authentication. They are alternate passwords that you can use to authenticate into Azure DevOps.
Really don't want the jobs to be tied to a specific user identity and Azure DevOps does not support service principles.
Yes, as you have pointed out. It doesn’t support to create a PAT token with a service account in Azure DevOps Service.
That would be ok to use the public fake MFA account to login Azure DevOps Service. And then use that account to generate PAT token. When request API, others simply use that generated PAT token to authenticate.
With CAP enabled the doc is clear. For Web flows, CAP is honored 100%. That means in most of the situations, Rest API will not be affected.
The limitation is third-party client flow. Some actually due to configuration of third-party. There's nothing we can do in Azure DevOps. You have to follow the policy mentioned in that link. If users do not meet IP range, it will be blocked.
I just wrote my first app with Azure. Just a small function app calling the IoT service and suddenly it hit me - I didn't have to create any IAM role or anything. The app just worked. I tried to look up the IAM service on Azure, but found nothing. This would never fly with AWS or Google Cloud. Does Azure have any IAM-like management anywhere? If my app has a bug that allows remote server-side code execution, does it mean that the attacker will basically gain access over my entire Azure account?
Azure does have role based access control and managed service identity (identity you assign to azure services, not all of the services have that yet). If you are using connection strings (usual pattern) nothing would happen if your app gets compromised. Attacker would be able to talk to your IoT Hub (or whatever you were using).
If you are using managed service identity then the attacker could, in theory, act on behalf of that identity. So if you grant all permission to that identity - then yes. Attacker would be able to do anything.
If your application talk to Azure REST Api directly to create\modify resources and gets compromised - attacker would, in theory, have the same rights as the application.
Having said that, I dont think Azure is any way less secure then AWS or GCP. Unless you grant the app all the permissions in the world - it has none to actually manage Azure.
I have a web application deployed on Azure with the Azure Active Directory security enabled (the express setting). So, when I try to access the application, I need to be a part of the AD to have access.
I would like to add more features to the application, like displaying the current user logged in, implement a logout, managing permissions etc... I believe I can achieve all of things with Azure Graph API.
However, to do this, I will need to test some stuff locally. Is there any way to simulate Azure AD locally? It is "switched on" on Azure and everything works great there, but ain't got nothing to simulate this on my local machine.
There is no "local" or "offline" version of Azure AD available.
Your options at this time are:
Test using an actual Azure AD tenant. You can create your own test tenant to allow you to make changes as necessary, postponing the need to work with the admin of your corporate Azure AD until you're ready to go to production.
Create your own Mock STS that implements the OpenID Connect protocol and use that during development/testing. The risk here is that you'll have to make sure that this Mock STS behaves just like Azure AD does or close enough for your purposes.
As a side note, you can create a feedback entry asking for a feature on this in the Azure AD Feedback Forum