Thursday, August 26, 2021

Azure RBAC in use

Azure identity and access management is the dragon. He sits on pile of gold. You have to beat him to win, to get the gold. Or to get your Azure secured but still easy to use for developers and DevOps guys. Here are some ideas on how to beat the beast.

First and the most important information is that forget the AD and Azure AD when you think about Azure RBAC. AAD is storing some of the identities. It’s actually the Identity Provider for the Azure RBAC users and groups. It’s not storing the RBAC principles. RBAC is the authorization method for Azure. 

After we have cleared our understanding of what AAD is not, we can go deeper into Azure RBAC.

Let’s start with the example:

az role assignment create --role "User Access Administrator" \
--assignee testuser_1@myazuredomain.onmicrosoft.com \
--scope  /subscriptions/11111111-2222-3333-4444-555555555555
/resourceGroups/test-group

The parts in this RBAC role assignment are:

  • Assignee - who gets the role. This can be user, group or service principle. It’s recommended that instead of assigning the roles to users you assign them to the user groups.
  • Role - this is a list of the access rights which the user gets. Azure has built-in roles which can be used. They can be used with all AAD subscriptions. There is also the possibility to use custom roles but it requires Premier P1 or P2 AAD subscription.
  • Scope - the scope is the ‘path’ for the resources which are under this role for this assignee. 

Scope is the path to the resources. It allows the role for everything under the path. The previous role assignment allows testuser_1 to modify the access rights of all resources under resource group test-group. 

If the resource structure is following:

  • Subscription 11111111-2222-3333-4444-555555555555
    • Resource group: test-group
      • Virtual network: test-network
        • Subnet: test-subnet
    • Resource group: another-group
      • Virtual network: another-network

The role assignment covers resources test-group, test-network and test-subnet.  It doesn’t allow the user to do any user administration at the resource group another-group. 

If the user has the role "User Access Administrator" he does not have any administrator access to the AAD itself. He cannot change the password of the users. He can’t create the users to AAD. But AAD has the option (which is enabled by default) to allow guest invites. It can be disabled from the AAD User Settings. The user can create new service principles with the scope where he is the User Access Administrator.

Examples

Creating the service principal with the scope:

az ad sp create-for-rbac --name testServicePrincipal
--scope /subscriptions/11111111-2222-3333-4444-555555555555
/resourceGroups/test-group

Adding the role for the service principal:

az role assignment create --role "Network Contributor" \
--assignee aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee \
--scope /subscriptions/11111111-2222-3333-4444-555555555555
/resourceGroups/test-group/providers/Microsoft.Network
/virtualNetworks/test-network

Attempts to create the role assignment or service principal outside the  user’s scope will fail.


Friday, January 15, 2021

Kubernetes Service Account debugging notes

Kubernetes and RBAC are horrible monsters. Debugging them is time consuming activity. Here’s several hints on how I'm doing that. 

First you have to get out the secret which stores the token to the system account.  This happens with the command:

kubectl get sa <service account name> -n <name space> \
-o=jsonpath='{.secrets[*].name}'

I’m using the Helm Data Tool to create the proper Kubernetes configuration file. It needs the access token and server certificate. It also needs the URL to the Kubernetes API server. The ca.crt and token files must be in the same directory. This example creates them in the directory ./tmp.

Next step is to generate the access token and certificate. First the certificate is created:

kubectl get secret my-secret-12345 -n ingress \
-o=jsonpath="{.data['ca\.crt']}" | base64 -d > tmp/ca.crt

Then the access token is created:

kubectl get secret my-secret-12345 -n ingress \
-o=jsonpath='{.data.token}' | base64 -d >tmp/token

If we’re now at the directory ~/helm-data-tool, and the kubeconfig-creator.sh is at the bin directory, you will create the Kubernetes configuration file with the command:

bin/kubeconfig-creator.sh -b tmp -h https://my-api:443 >sa-kubeconfig

One global kubectl parameter is --kubeconfig. You can give sa-kubeconfig for it. After that you can test your API calls. E.g. to check if the System Account has global access to list the roles:

kubectl get role -A --kubeconfig=sa-kubeconfig 

Helm is not that well supporting the setting of configuration from the command line. But those commands which are supporting that have option --kubeconfig

helm upgrade -i --kubeconfig sa-kubeconfig …

These are my personal notes. I hope you like them too. If you have own hints how to debug Kubernetes configuration, please let me know.