AWSSDK.IdentityManagement ( AWS IAM )
Tags: cloud, csharp, aws, dotnet
Published: 2021-08-27 07:26:50

The `AWS SDK` for .NET supports `AWS Identity and Access Management (IAM)`, which is a web service that enables AWS customers to manage users and user permissions in AWS.

First of all, let's have a brief about IAM Service in AWS...
#➽What is IAM Service in AWS?
☞`AWS Identity and Access Management (IAM)` is a web service that helps you securely control access to AWS resources. You use `IAM` to control who is authenticated (signed in) and authorized (has permissions) to use resources.
☞You grant permissions to a user by creating a `IAM policy`. The policy contains a policy document that lists the actions that a user can perform and the resources those actions can affect.
☞ Read more about [IAM Service](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html)
☞ Read more about [Policies and Permissions](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)
_____________________________________________________
#➽Installing AWSSDK.IdentityManagement :
☞`AWSSDK.IdentityManagement` is installed mainly from [Nuget] (https://www.nuget.org/)
☞There is 3 ways to install `AWSSDK.IdentityManagement`, they are the same as installing `AWSSDK.S3` from [Part 1 of this series](https://dev.to/ahmedadel/aws-sdks-for-net-1-awssdk-s3-5e36)
☞let's use the easiest one, from Package Manager Console by using the Install-Package command. 
```csharp
PM> Install-Package AWSSDK.IdentityManagement
```
_________________________________________________________
🌟 Second step is to connect to our AWS account using __ Access keys (Access Key ID and Secret Access Key)__, this was explained before briefly in the [first article under (Get AWS Access keys) ](https://dev.to/ahmedadel/aws-sdks-for-net-1-awssdk-s3-5e36#%E2%9E%BDso-how-can-we-use-it-)
_________________________________________________________
#➽Let's now check what we can do with this SDK :
☞__1- Create IAM user:__
➤The following snippet creates an IAM user, adds the given managed security policy, and then creates and stores credentials for him.
```csharp
    // Create the user Method
    private static async Task<CreateUserResponse> CreateUser(
      IAmazonIdentityManagementService iamClient, string userName,
      string policyArn, string csvFilename)
    {
      // Create the user
      // Could also create a login profile for the user by using CreateLoginProfileAsync
      CreateUserResponse responseCreate =
        await iamClient.CreateUserAsync(new CreateUserRequest(userName));

      // Attach an existing managed policy
      await iamClient.AttachUserPolicyAsync(new AttachUserPolicyRequest{
        UserName = responseCreate.User.UserName,
        PolicyArn = policyArn});

      // Create credentials and write them to a CSV file.
      CreateAccessKeyResponse responseCreds =
        await iamClient.CreateAccessKeyAsync(new CreateAccessKeyRequest{
          UserName = responseCreate.User.UserName});
      using (FileStream s = new FileStream(csvFilename, FileMode.Create))
      using (StreamWriter writer = new StreamWriter(s))
      {
        writer.WriteLine("User name,Access key ID,Secret access key");
        writer.WriteLine("{0},{1},{2}", responseCreds.AccessKey.UserName,
          responseCreds.AccessKey.AccessKeyId,
          responseCreds.AccessKey.SecretAccessKey);
      }

      return responseCreate;
    }
```

☞__2- Display list of IAM users:__
➤ To display a list of existing users, as well as information about each user such as access key IDs and attached policies.
```csharp
    // Method to print out a list of the existing users and information about them
    private static async Task ListUsers(IAmazonIdentityManagementService iamClient)
    {
      // Get the list of users
      ListUsersResponse responseUsers = await iamClient.ListUsersAsync();
      Console.WriteLine("\nFull list of users...");
      foreach (var user in responseUsers.Users)
      {
        Console.WriteLine($"User {user.UserName}:");
        Console.WriteLine($"\tCreated: {user.CreateDate.ToShortDateString()}");

        // Show the list of groups this user is part of
        var responseGroups = await iamClient.ListGroupsForUserAsync(
            new ListGroupsForUserRequest(user.UserName));
        foreach (var group in responseGroups.Groups)
          Console.WriteLine($"\tGroup: {group.GroupName}");

        // Show the list of access keys for this user
        ListAccessKeysResponse responseAccessKeys =
          await iamClient.ListAccessKeysAsync(
            new ListAccessKeysRequest{UserName = user.UserName});
        foreach(AccessKeyMetadata accessKey in responseAccessKeys.AccessKeyMetadata)
          Console.WriteLine($"\tAccess key ID: {accessKey.AccessKeyId}");

        // Show the list of managed policies attached to this user
        var requestManagedPolicies = new ListAttachedUserPoliciesRequest{
          UserName = user.UserName};
        var responseManagedPolicies = await iamClient.ListAttachedUserPoliciesAsync(
            new ListAttachedUserPoliciesRequest{UserName = user.UserName});
        foreach(var policy in responseManagedPolicies.AttachedPolicies)
          Console.WriteLine($"\tManaged policy name: {policy.PolicyName}");

        // Show the list of inline policies attached to this user
        var responseInlinePolicies = await iamClient.ListUserPoliciesAsync(
            new ListUserPoliciesRequest(user.UserName));
        foreach(var policy in responseInlinePolicies.PolicyNames)
          Console.WriteLine($"\tInline policy name: {policy}");
      }
    }
```

☞__3- Delete IAM users:__
⛔ Before deleting a user, we should first __de-attach all his policies__ and __remove all his access keys__ using the following methods
```csharp
    // Method to detach managed policies from a user
    private static async Task DetachPolicies(
      IAmazonIdentityManagementService iamClient, string userName)
    {
      ListAttachedUserPoliciesResponse responseManagedPolicies =
        await iamClient.ListAttachedUserPoliciesAsync(
          new ListAttachedUserPoliciesRequest{UserName = userName});
      foreach(AttachedPolicyType policy in responseManagedPolicies.AttachedPolicies)
      {
        Console.WriteLine($"\tDetaching policy {policy.PolicyName}");
        await iamClient.DetachUserPolicyAsync(new DetachUserPolicyRequest{
          PolicyArn = policy.PolicyArn,
          UserName = userName});
      }
    }

    // Method to delete access keys from a user
    private static async Task DeleteAccessKeys(
      IAmazonIdentityManagementService iamClient, string userName)
    {
      ListAccessKeysResponse responseAccessKeys =
        await iamClient.ListAccessKeysAsync(
          new ListAccessKeysRequest{UserName = userName});
      foreach(AccessKeyMetadata accessKey in responseAccessKeys.AccessKeyMetadata)
      {
        Console.WriteLine($"\tDeleting Access key {accessKey.AccessKeyId}");
        await iamClient.DeleteAccessKeyAsync(new DeleteAccessKeyRequest{
          UserName = userName,
          AccessKeyId = accessKey.AccessKeyId});
      }
    }
```
➤ Now we can delete the user:
```csharp
    // Method to delete a user
    private static async Task DeleteUser(
      IAmazonIdentityManagementService iamClient, string userName)
    {
      // Remove items from the user
      // Detach any managed policies
      await DetachPolicies(iamClient, userName);

      // Delete any access keys
      await DeleteAccessKeys(iamClient, userName);

      // DeleteLoginProfileAsycn(), DeleteUserPolicyAsync(), etc.
      // See the description of DeleteUserAsync for a full list.

      // Delete the user
      await iamClient.DeleteUserAsync(new DeleteUserRequest(userName));
      Console.WriteLine("Done");
    }
``` 

☞__4- Creating IAM managed policies from JSON:__
✅ Let's assume that we have a policy file like this
```json
{
  "Version" : "2012-10-17",
  "Id"  : "DotnetTutorialPolicy",
  "Statement" : [
    {
      "Sid" : "DotnetTutorialPolicyS3",
      "Effect" : "Allow",
      "Action" : [
        "s3:Get*",
        "s3:List*"
      ],
      "Resource" : "*"
    },
    {
      "Sid" : "DotnetTutorialPolicyPolly",
      "Effect": "Allow",
      "Action": [
        "polly:DescribeVoices",
        "polly:SynthesizeSpeech"
      ],
      "Resource": "*"
    }
  ]
}
```
➤To read more about [IAM managed policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies)

➤ To create an IAM managed policy from a given policy document in `JSON` by creating an IAM client object, reads the policy document from a file, and then creates the policy.

```csharp
    // create an IAM policy from a JSON file
    private static async Task<CreatePolicyResponse> CreateManagedPolicy(
      IAmazonIdentityManagementService iamClient, string policyName, string jsonFilename)
    {
      return await iamClient.CreatePolicyAsync(new CreatePolicyRequest{
        PolicyName = policyName,
        PolicyDocument = File.ReadAllText(jsonFilename)});
    }
```

☞__5- Display the policy document of an IAM managed policy:__
➤ First, we need to find the default version of the given `IAM Policy`
```csharp
    // Method to determine the default version of an IAM policy
    // Returns a string with the version
    private static async Task<string> GetDefaultVersion(
      IAmazonIdentityManagementService iamClient, string policyArn)
    {
      // Retrieve all the versions of this policy
      string defaultVersion = string.Empty;
      ListPolicyVersionsResponse reponseVersions =
        await iamClient.ListPolicyVersionsAsync(new ListPolicyVersionsRequest{
          PolicyArn = policyArn});

      // Find the default version
      foreach(PolicyVersion version in reponseVersions.Versions)
      {
        if(version.IsDefaultVersion)
        {
          defaultVersion = version.VersionId;
          break;
        }
      }
      return defaultVersion;
    }
```
➤Then, display the policy document
```csharp
    // Method to retrieve and display the policy document of an IAM policy
    private static async Task ShowPolicyDocument(
      IAmazonIdentityManagementService iamClient, string policyArn, string defaultVersion)
    {
      // Retrieve the policy document of the default version
      GetPolicyVersionResponse responsePolicy =
        await iamClient.GetPolicyVersionAsync(new GetPolicyVersionRequest{
          PolicyArn = policyArn,
          VersionId = defaultVersion});

      // Display the policy document (in JSON)
      Console.WriteLine($"Version {defaultVersion} of the policy (in JSON format):");
      Console.WriteLine(
        $"{HttpUtility.UrlDecode(responsePolicy.PolicyVersion.Document)}");
    }
```