@@ -6,12 +6,14 @@ import { AWSError } from 'aws-sdk/lib/error'
66
77import IAM , {
88 AttachedPolicy ,
9+ GetAccountAuthorizationDetailsResponse ,
910 GetRoleResponse ,
1011 ListAttachedRolePoliciesResponse ,
1112 ListRolePoliciesResponse ,
1213 ListRolesResponse ,
1314 ListRoleTagsResponse ,
1415 Role ,
16+ RoleDetail ,
1517} from 'aws-sdk/clients/iam'
1618import { Config } from 'aws-sdk/lib/config'
1719
@@ -38,10 +40,12 @@ const customRetrySettings = setAwsRetryOptions({
3840} )
3941
4042export interface RawAwsIamRole extends Omit < Role , 'Tags' > {
41- Policies : string [ ]
4243 ManagedPolicies : AttachedPolicy [ ]
4344 region : string
4445 Tags ?: TagMap
46+ PermissionsBoundaryArn : string
47+ InlinePoliciesName : string [ ]
48+ InlinePoliciesDocuments : string [ ]
4549}
4650
4751const roleByRoleName = async (
@@ -154,10 +158,42 @@ const managedPoliciesByRoleName = async (
154158 )
155159 } )
156160
157- export const listIamRoles = async (
161+ export const getAccountAuthorizationDetails = async (
158162 iam : IAM ,
159163 marker ?: string
160- ) : Promise < RawAwsIamRole [ ] > =>
164+ ) : Promise < RoleDetail [ ] > =>
165+ new Promise ( resolve => {
166+ const result : RoleDetail [ ] = [ ]
167+ iam . getAccountAuthorizationDetails (
168+ { Filter : [ 'Role' ] , Marker : marker } ,
169+ async ( err : AWSError , data : GetAccountAuthorizationDetailsResponse ) => {
170+ if ( err ) {
171+ errorLog . generateAwsErrorLog ( {
172+ functionName : 'iam:getAccountAuthorizationDetails' ,
173+ err,
174+ } )
175+ }
176+ if ( ! isEmpty ( data ) && ! isEmpty ( data . RoleDetailList ) ) {
177+ const { Marker, IsTruncated, RoleDetailList } = data
178+ result . push ( ...RoleDetailList )
179+ if ( IsTruncated ) {
180+ result . push ( ...( await getAccountAuthorizationDetails ( iam , Marker ) ) )
181+ }
182+ resolve ( result )
183+ }
184+ }
185+ )
186+ } )
187+
188+ export const listIamRoles = async ( {
189+ iam,
190+ marker,
191+ roleAuthorizationDetails,
192+ } : {
193+ iam : IAM
194+ marker ?: string
195+ roleAuthorizationDetails : RoleDetail [ ]
196+ } ) : Promise < RawAwsIamRole [ ] > =>
161197 new Promise ( resolve => {
162198 const result : RawAwsIamRole [ ] = [ ]
163199 const policiesByRoleNamePromises = [ ]
@@ -196,7 +232,13 @@ export const listIamRoles = async (
196232
197233 result . push (
198234 ...roles . map (
199- ( { RoleName, AssumeRolePolicyDocument, Tags, ...role } ) => {
235+ ( {
236+ RoleName,
237+ AssumeRolePolicyDocument,
238+ PermissionsBoundary,
239+ Tags,
240+ ...role
241+ } ) => {
200242 return {
201243 RoleName,
202244 AssumeRolePolicyDocument : decodeURIComponent (
@@ -207,7 +249,7 @@ export const listIamRoles = async (
207249 RoleLastUsed : detailedRoles ?. find (
208250 r => r ?. RoleName === RoleName
209251 ) ?. Role . RoleLastUsed ,
210- Policies :
252+ InlinePoliciesName :
211253 policies
212254 ?. filter ( p => p ?. RoleName === RoleName )
213255 . map ( p => p . Policies )
@@ -218,13 +260,24 @@ export const listIamRoles = async (
218260 . map ( p => p . ManagedPolicies )
219261 . reduce ( ( current , acc ) => [ ...acc , ...current ] , [ ] ) || [ ] ,
220262 Tags : tags . find ( t => t ?. RoleName === RoleName ) ?. Tags || { } ,
263+ PermissionsBoundaryArn :
264+ PermissionsBoundary . PermissionsBoundaryArn ,
265+ InlinePoliciesDocuments : roleAuthorizationDetails
266+ . find ( rAD => rAD . RoleName === RoleName )
267+ . RolePolicyList . map ( rPl => rPl . PolicyDocument ) ,
221268 }
222269 }
223270 )
224271 )
225272
226273 if ( IsTruncated ) {
227- result . push ( ...( await listIamRoles ( iam , Marker ) ) )
274+ result . push (
275+ ...( await listIamRoles ( {
276+ iam,
277+ marker : Marker ,
278+ roleAuthorizationDetails,
279+ } ) )
280+ )
228281 }
229282
230283 resolve ( result )
@@ -259,8 +312,12 @@ export default async ({
259312
260313 logger . debug ( lt . lookingForIamRoles )
261314
315+ // Fetch role authorization details first
316+ const roleAuthorizationDetails = await getAccountAuthorizationDetails (
317+ client
318+ )
262319 // Fetch IAM Roles
263- rolesData = await listIamRoles ( client )
320+ rolesData = await listIamRoles ( { iam : client , roleAuthorizationDetails } )
264321
265322 errorLog . reset ( )
266323 logger . debug ( lt . foundRoles ( rolesData . length ) )
0 commit comments