Class: Cucloud::IamUtils

Inherits:
Object
  • Object
show all
Defined in:
lib/cucloud/iam_utils.rb

Overview

Utilities library for interacting with IAM

Defined Under Namespace

Classes: UnknownComparisonOperatorError

Instance Method Summary collapse

Constructor Details

#initialize(iam_client = Aws::IAM::Client.new) ⇒ IamUtils

Returns a new instance of IamUtils.



8
9
10
# File 'lib/cucloud/iam_utils.rb', line 8

def initialize(iam_client = Aws::IAM::Client.new)
  @iam = iam_client
end

Instance Method Details

#audit_password_policy(audit_criteria = []) ⇒ Array<Hash>

Check password policy against an options hash of audit criteria

Policy format - Array of checks example input: [{ key: "minimum_password_length", operator: "GT", value: 15 }] example output: [{ key: "minimum_password_length", passes: true }]

Parameters:

  • Policy (Array<Hash>)

    against which to audit

Returns:

  • (Array<Hash>)

    Results of each audit check



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/cucloud/iam_utils.rb', line 62

def audit_password_policy(audit_criteria = [])
  policy_hash = .to_h

  audit_criteria.map do |check|
    case check[:operator]
    when 'EQ'
      {
        key: check[:key],
        passes: policy_hash[check[:key].to_sym].nil? ? false : policy_hash[check[:key].to_sym] == check[:value]
      }
    when 'LTE'
      {
        key: check[:key],
        passes: policy_hash[check[:key].to_sym].nil? ? false : policy_hash[check[:key].to_sym] <= check[:value]
      }
    when 'GTE'
      {
        key: check[:key],
        passes: policy_hash[check[:key].to_sym].nil? ? false : policy_hash[check[:key].to_sym] >= check[:value]
      }
    else
      raise UnknownComparisonOperatorError.new, "Unknown operator #{check[:operator]}"
    end
  end
end

#cornell_provider_configured?Boolean

Is the Cornell SAML Identity Provider configured on this account?

Returns:

  • (Boolean)


105
106
107
# File 'lib/cucloud/iam_utils.rb', line 105

def cornell_provider_configured?
  get_saml_providers.select { |provider| provider[:saml_metadata_document].include? CORNELL_SAML_X509 }.any?
end

#get_account_aliasString

Get the alias set for this account if it exists

Returns:

  • (String)

    Account alias (nil if not set)



14
15
16
17
18
19
20
# File 'lib/cucloud/iam_utils.rb', line 14

def 
  # https://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/Client.html#list_account_aliases-instance_method
  # https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html
  # Per user guide: Account can have only one alias

  @iam..[0]
end

#get_account_password_policyAws::IAM::Types::PasswordPolicy

Get password policy for this account

Returns:

  • (Aws::IAM::Types::PasswordPolicy)


50
51
52
53
# File 'lib/cucloud/iam_utils.rb', line 50

def 
  # https://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/Client.html#get_account_password_policy-instance_method
  @iam..password_policy
end

#get_account_summaryHash<String,Integer>

Get report about IAM entity usage and quotas in this account

Returns:

  • (Hash<String,Integer>)

    A hash of key value pairs containing information about IAM entity usage and quotas.



24
25
26
27
28
# File 'lib/cucloud/iam_utils.rb', line 24

def 
  # https://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/Client.html#get_account_summary-instance_method
  # return https://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/Types/GetAccountSummaryResponse.html#summary_map-instance_method
  @iam..summary_map
end

#get_active_keys_older_than_n_days(n) ⇒ Array<Hash>

Get active access keys on account that are older than specified age (in days)

Parameters:

  • Days (Integer)

    old

Returns:

  • (Array<Hash>)


155
156
157
158
159
# File 'lib/cucloud/iam_utils.rb', line 155

def get_active_keys_older_than_n_days(n)
  get_users.map do |user|
    get_user_access_keys(user[:base_data].user_name).select { |k| k[:days_old] > n && k[:active] }
  end.flatten
end

#get_saml_providersArray<Hash>

Get SAML providers configured for this account

Returns:

  • (Array<Hash>)

    Array of hashes in form { arn: , metadata: }



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/cucloud/iam_utils.rb', line 90

def get_saml_providers
  # https://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/Client.html#list_saml_providers-instance_method
  # returns https://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/Types/SAMLProviderListEntry.html
  # https://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/Client.html#get_saml_provider-instance_method

  @iam.list_saml_providers.saml_provider_list.map do |provider|
    {
      arn: provider.arn,
      saml_metadata_document: @iam.get_saml_provider(saml_provider_arn: provider.arn).
    }
  end
end

#get_user_access_keys(user_name) ⇒ Array<Hash>

Get access keys for user

Parameters:

  • Username (String)

Returns:

  • (Array<Hash>)

    Array of key hashes - base key data + helper calculations for key age and active/inactive



140
141
142
143
144
145
146
147
148
149
150
# File 'lib/cucloud/iam_utils.rb', line 140

def get_user_access_keys(user_name)
  # https://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/Client.html#list_access_keys-instance_method

  @iam.list_access_keys(user_name: user_name)..map do |key|
    {
      base_data: key,
      active: key.status == 'Active',
      days_old: (Time.now - key.create_date).to_i / (24 * 60 * 60)
    }
  end
end

#get_usersArray<Hash>

Get users that are configured on this account

Returns:

  • (Array<Hash>)

    Array of user hashes - base user type + added lookups for convenience



111
112
113
114
115
116
117
118
119
# File 'lib/cucloud/iam_utils.rb', line 111

def get_users
  # https://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/Client.html#list_users-instance_method
  @iam.list_users.users.map do |user|
    {
      base_data: user, # https://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/Types/User.html
      has_password: user_has_password?(user.user_name)
    }
  end
end

#multiple_providers_configured?Boolean

Does this account have multiple identity providers configured?

Returns:

  • (Boolean)


44
45
46
# File 'lib/cucloud/iam_utils.rb', line 44

def multiple_providers_configured?
  ['Providers'] > 1
end

#root_user_has_api_key?Boolean

Does this account's root user have any API keys?

Returns:

  • (Boolean)


32
33
34
# File 'lib/cucloud/iam_utils.rb', line 32

def root_user_has_api_key?
  ['AccountAccessKeysPresent'] > 0
end

#root_user_mfa_enabled?Boolean

Does this account's root user have MFA enabled?

Returns:

  • (Boolean)


38
39
40
# File 'lib/cucloud/iam_utils.rb', line 38

def root_user_mfa_enabled?
  ['AccountMFAEnabled'] > 0
end

#user_has_password?(user_name) ⇒ Boolean

Does this user have a password configured?

Parameters:

  • Username (String)

Returns:

  • (Boolean)


124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/cucloud/iam_utils.rb', line 124

def user_has_password?(user_name)
  # https://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/Client.html#get_login_profile-instance_method
  password = true

  begin
    @iam.(user_name: user_name)
  rescue Aws::IAM::Errors::NoSuchEntity
    password = false
  end

  password
end