@cloud-copilot/iam-simulate 0.1.107 → 0.1.108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/StatementAnalysis.d.ts.map +1 -1
- package/dist/cjs/StatementAnalysis.js +0 -18
- package/dist/cjs/StatementAnalysis.js.map +1 -1
- package/dist/cjs/analysis/analyzeResults.d.ts +33 -2
- package/dist/cjs/analysis/analyzeResults.d.ts.map +1 -1
- package/dist/cjs/analysis/analyzeResults.js +35 -15
- package/dist/cjs/analysis/analyzeResults.js.map +1 -1
- package/dist/cjs/evaluate.d.ts +17 -0
- package/dist/cjs/evaluate.d.ts.map +1 -1
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/services/DefaultServiceAuthorizer.d.ts +16 -0
- package/dist/cjs/services/DefaultServiceAuthorizer.d.ts.map +1 -1
- package/dist/cjs/services/DefaultServiceAuthorizer.js +149 -107
- package/dist/cjs/services/DefaultServiceAuthorizer.js.map +1 -1
- package/dist/esm/StatementAnalysis.d.ts.map +1 -1
- package/dist/esm/StatementAnalysis.js +0 -18
- package/dist/esm/StatementAnalysis.js.map +1 -1
- package/dist/esm/analysis/analyzeResults.d.ts +33 -2
- package/dist/esm/analysis/analyzeResults.d.ts.map +1 -1
- package/dist/esm/analysis/analyzeResults.js +35 -15
- package/dist/esm/analysis/analyzeResults.js.map +1 -1
- package/dist/esm/evaluate.d.ts +17 -0
- package/dist/esm/evaluate.d.ts.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/services/DefaultServiceAuthorizer.d.ts +16 -0
- package/dist/esm/services/DefaultServiceAuthorizer.d.ts.map +1 -1
- package/dist/esm/services/DefaultServiceAuthorizer.js +147 -107
- package/dist/esm/services/DefaultServiceAuthorizer.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,6 +2,69 @@ import { isAssumedRoleArn, isFederatedUserArn, isIamRoleArn, isIamUserArn, isSer
|
|
|
2
2
|
import {} from '../evaluate.js';
|
|
3
3
|
import {} from '../request/requestResource.js';
|
|
4
4
|
import {} from './ServiceAuthorizer.js';
|
|
5
|
+
/**
|
|
6
|
+
* This helper class keeps track of which factors are blocking a request and what the overall result is
|
|
7
|
+
* based on those blocks.
|
|
8
|
+
*/
|
|
9
|
+
class BlockedByLog {
|
|
10
|
+
/**
|
|
11
|
+
* Create the BlockedByLog
|
|
12
|
+
*
|
|
13
|
+
* @param coreResult the core result of the authorization. Is the request allowed or denied based on the core policies (identity, resource, session).
|
|
14
|
+
*/
|
|
15
|
+
constructor(coreResult) {
|
|
16
|
+
this.coreResult = coreResult;
|
|
17
|
+
this.blockedBy = new Set();
|
|
18
|
+
this.result = coreResult;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Add a blocking factor to the log and update the overall result accordingly.
|
|
22
|
+
*
|
|
23
|
+
* @param reason the reason for the block.
|
|
24
|
+
* @param result the result of the block (ImplicitlyDenied, ExplicitlyDenied)
|
|
25
|
+
*/
|
|
26
|
+
add(reason, result) {
|
|
27
|
+
if (this.coreResult === 'Allowed' && result !== 'Allowed') {
|
|
28
|
+
this.blockedBy.add(reason);
|
|
29
|
+
}
|
|
30
|
+
this.setResult(result);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Calculates and sets the new overall result based on the new block reason and the previous result.
|
|
34
|
+
*
|
|
35
|
+
* The result can only be modified down so Allowed -> ImplicitlyDenied -> ExplicitlyDenied.
|
|
36
|
+
*
|
|
37
|
+
* @param newResult the result of the new block reason being added.
|
|
38
|
+
*/
|
|
39
|
+
setResult(newResult) {
|
|
40
|
+
// Explicit denies override everything
|
|
41
|
+
if (this.result === 'ExplicitlyDenied') {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (newResult === 'ExplicitlyDenied') {
|
|
45
|
+
this.result = 'ExplicitlyDenied';
|
|
46
|
+
}
|
|
47
|
+
else if (newResult === 'ImplicitlyDenied') {
|
|
48
|
+
this.result = 'ImplicitlyDenied';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get the overall result after all blocks (if any) have been added.
|
|
53
|
+
*
|
|
54
|
+
* @returns the overall result after all blocks (if any) have been added.
|
|
55
|
+
*/
|
|
56
|
+
getResult() {
|
|
57
|
+
return this.result;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get the list of reasons that are blocking the request after the core result.
|
|
61
|
+
*
|
|
62
|
+
* @returns an array of reasons that are blocking the request after the core result.
|
|
63
|
+
*/
|
|
64
|
+
getBlockedBy() {
|
|
65
|
+
return Array.from(this.blockedBy);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
5
68
|
/**
|
|
6
69
|
* The default authorizer for services.
|
|
7
70
|
*/
|
|
@@ -15,7 +78,6 @@ export class DefaultServiceAuthorizer {
|
|
|
15
78
|
authorize(request) {
|
|
16
79
|
const scpResult = request.scpAnalysis.result;
|
|
17
80
|
const rcpResult = request.rcpAnalysis.result;
|
|
18
|
-
const sessionResult = request.sessionAnalysis?.result;
|
|
19
81
|
const identityStatementResult = request.identityAnalysis.result;
|
|
20
82
|
const resourcePolicyResult = request.resourceAnalysis?.result;
|
|
21
83
|
const permissionBoundaryResult = request.permissionBoundaryAnalysis?.result;
|
|
@@ -33,66 +95,26 @@ export class DefaultServiceAuthorizer {
|
|
|
33
95
|
permissionBoundaryAnalysis: request.permissionBoundaryAnalysis,
|
|
34
96
|
endpointAnalysis: request.endpointAnalysis
|
|
35
97
|
};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
if (rcpResult !== 'Allowed') {
|
|
43
|
-
return {
|
|
44
|
-
result: rcpResult,
|
|
45
|
-
...baseResult
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
if (sessionResult && sessionResult !== 'Allowed') {
|
|
49
|
-
return {
|
|
50
|
-
result: sessionResult,
|
|
51
|
-
...baseResult
|
|
52
|
-
};
|
|
53
|
-
}
|
|
98
|
+
const coreResult = this.initialEvaluationResult(request);
|
|
99
|
+
const blockedByLog = new BlockedByLog(coreResult);
|
|
100
|
+
blockedByLog.add('scp', scpResult);
|
|
101
|
+
blockedByLog.add('rcp', rcpResult);
|
|
54
102
|
if (endpointPolicyResult === 'ExplicitlyDenied' ||
|
|
55
103
|
endpointPolicyResult === 'ImplicitlyDenied') {
|
|
56
|
-
|
|
57
|
-
result: endpointPolicyResult,
|
|
58
|
-
...baseResult
|
|
59
|
-
};
|
|
104
|
+
blockedByLog.add('vpce', endpointPolicyResult);
|
|
60
105
|
}
|
|
61
106
|
if (resourcePolicyResult === 'ExplicitlyDenied' ||
|
|
62
107
|
resourcePolicyResult === 'DeniedForAccount') {
|
|
63
|
-
|
|
64
|
-
result: 'ExplicitlyDenied',
|
|
65
|
-
...baseResult
|
|
66
|
-
};
|
|
108
|
+
blockedByLog.add('resource', 'ExplicitlyDenied');
|
|
67
109
|
}
|
|
68
110
|
if (identityStatementResult === 'ExplicitlyDenied') {
|
|
69
|
-
|
|
70
|
-
result: 'ExplicitlyDenied',
|
|
71
|
-
...baseResult
|
|
72
|
-
};
|
|
111
|
+
blockedByLog.add('identity', 'ExplicitlyDenied');
|
|
73
112
|
}
|
|
74
113
|
if (permissionBoundaryResult === 'ExplicitlyDenied') {
|
|
75
|
-
|
|
76
|
-
result: 'ExplicitlyDenied',
|
|
77
|
-
...baseResult
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
// Service Principals
|
|
81
|
-
if (isServicePrincipal(request.request.principal.value())) {
|
|
82
|
-
// Service principals are allowed if the resource policy allows them
|
|
83
|
-
if (resourcePolicyResult === 'Allowed') {
|
|
84
|
-
return {
|
|
85
|
-
result: 'Allowed',
|
|
86
|
-
...baseResult
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
return {
|
|
90
|
-
result: 'ImplicitlyDenied',
|
|
91
|
-
...baseResult
|
|
92
|
-
};
|
|
114
|
+
blockedByLog.add('pb', 'ExplicitlyDenied');
|
|
93
115
|
}
|
|
94
116
|
//Same Account
|
|
95
|
-
if (
|
|
117
|
+
if (sameAccount) {
|
|
96
118
|
if (permissionBoundaryResult === 'ImplicitlyDenied') {
|
|
97
119
|
/**
|
|
98
120
|
* If the permission boundary is an implicit deny
|
|
@@ -106,80 +128,48 @@ export class DefaultServiceAuthorizer {
|
|
|
106
128
|
const principal = request.request.principal.value();
|
|
107
129
|
if (isIamRoleArn(principal) &&
|
|
108
130
|
request.simulationParameters.simulationMode === 'Discovery') {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
...baseResult
|
|
113
|
-
};
|
|
131
|
+
// Principal is a role and may match a session. Check since we are in Discovery mode.
|
|
132
|
+
if (!request.resourceAnalysis.allowStatements.some((statement) => statement.principalMatch === 'Match' && statement.ignoredRoleSessionName)) {
|
|
133
|
+
blockedByLog.add('pb', 'ImplicitlyDenied');
|
|
114
134
|
}
|
|
115
135
|
}
|
|
116
|
-
if (isAssumedRoleArn(principal) ||
|
|
136
|
+
else if (isAssumedRoleArn(principal) ||
|
|
117
137
|
isIamUserArn(principal) ||
|
|
118
138
|
isFederatedUserArn(principal)) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
};
|
|
139
|
+
// If the principal is an assumed role, IAM user, or federated user ARN, check if the resource
|
|
140
|
+
// policy allows the exact ARN.
|
|
141
|
+
if (!request.resourceAnalysis.allowStatements.some((statement) => statement.principalMatch === 'Match')) {
|
|
142
|
+
blockedByLog.add('pb', 'ImplicitlyDenied');
|
|
124
143
|
}
|
|
125
144
|
}
|
|
145
|
+
else {
|
|
146
|
+
// Not in discovery mode or doesn't match a session/user exactly, so the permission boundary implicit deny applies.
|
|
147
|
+
blockedByLog.add('pb', 'ImplicitlyDenied');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// Resource policy doesn't allow the principal, so the permission boundary implicit deny applies.
|
|
152
|
+
blockedByLog.add('pb', 'ImplicitlyDenied');
|
|
126
153
|
}
|
|
127
|
-
return {
|
|
128
|
-
result: 'ImplicitlyDenied',
|
|
129
|
-
...baseResult
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
/*
|
|
133
|
-
TODO: Implicit denies in identity policies
|
|
134
|
-
I think if the identity policy has an implicit deny for assumed roles or federated users,
|
|
135
|
-
then the resource policy must have the federated or assumed role ARN exactly.
|
|
136
|
-
|
|
137
|
-
That doesn't seem right though. I know many cases where the resource policy has the role ARN and it works
|
|
138
|
-
|
|
139
|
-
Need to add some tests for this.
|
|
140
|
-
*/
|
|
141
|
-
const trustedAccount = this.serviceTrustsPrincipalAccount(sameAccount, request.resourceAnalysis, request.request.resource);
|
|
142
|
-
if (resourcePolicyResult === 'Allowed' ||
|
|
143
|
-
(trustedAccount && identityStatementResult === 'Allowed')) {
|
|
144
|
-
return {
|
|
145
|
-
result: 'Allowed',
|
|
146
|
-
...baseResult
|
|
147
|
-
};
|
|
148
154
|
}
|
|
149
|
-
return {
|
|
150
|
-
result: 'ImplicitlyDenied',
|
|
151
|
-
...baseResult
|
|
152
|
-
};
|
|
153
155
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
...baseResult
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
if (resourcePolicyResult === 'Allowed' || resourcePolicyResult === 'AllowedForAccount') {
|
|
162
|
-
if (identityStatementResult === 'Allowed') {
|
|
163
|
-
return {
|
|
164
|
-
result: 'Allowed',
|
|
165
|
-
...baseResult
|
|
166
|
-
};
|
|
156
|
+
else {
|
|
157
|
+
//Cross Account
|
|
158
|
+
if (permissionBoundaryResult === 'ImplicitlyDenied') {
|
|
159
|
+
blockedByLog.add('pb', 'ImplicitlyDenied');
|
|
167
160
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
161
|
+
}
|
|
162
|
+
const blockedReasons = blockedByLog.getBlockedBy();
|
|
163
|
+
if (blockedReasons.length !== 0) {
|
|
164
|
+
baseResult.blockedBy = blockedReasons;
|
|
172
165
|
}
|
|
173
166
|
return {
|
|
174
|
-
result:
|
|
167
|
+
result: blockedByLog.getResult(),
|
|
175
168
|
...baseResult
|
|
176
169
|
};
|
|
177
170
|
/**
|
|
178
171
|
* Add checks for:
|
|
179
172
|
* * root user - can override resource policies for most resource types
|
|
180
|
-
* * service linked roles - ignore SCPs and RCPs
|
|
181
|
-
* * session policies
|
|
182
|
-
* * vpc endpoint policies
|
|
183
173
|
* * organization APIs and delegated admin policy
|
|
184
174
|
*/
|
|
185
175
|
}
|
|
@@ -196,5 +186,55 @@ export class DefaultServiceAuthorizer {
|
|
|
196
186
|
}
|
|
197
187
|
return resourceAnalysis.allowStatements.some((statement) => statement.principalMatch === 'AccountLevelMatch');
|
|
198
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Evaluations whether the minimum requirements for the request to be allowed are met based on the core policies
|
|
191
|
+
* - Identity
|
|
192
|
+
* - Resource
|
|
193
|
+
* - Session
|
|
194
|
+
*
|
|
195
|
+
* Depending on the service, and whether the principal and resources are in the same account, the requirements may differ.
|
|
196
|
+
* For same account requests, for most services an Allow in the resource policy or the identity policy is sufficient to
|
|
197
|
+
* allow the request, so this function will return 'Allowed'. If there is an explicit deny elsewhere, that is not considered.
|
|
198
|
+
* This function only determines if there are enough core policies to allow the request, and final determination of the
|
|
199
|
+
* request is done elsewhere.
|
|
200
|
+
*
|
|
201
|
+
* @param request the service authorization request containing all analyses
|
|
202
|
+
* @returns 'Allowed' if the core policies allow the request, otherwise may return 'ImplicitlyDenied' or 'ExplicitlyDenied' depending on the analyses
|
|
203
|
+
*/
|
|
204
|
+
initialEvaluationResult(request) {
|
|
205
|
+
const sessionResult = request.sessionAnalysis?.result;
|
|
206
|
+
const identityStatementResult = request.identityAnalysis.result;
|
|
207
|
+
const resourcePolicyResult = request.resourceAnalysis?.result;
|
|
208
|
+
const principalAccount = request.request.principal.accountId();
|
|
209
|
+
const resourceAccount = request.request.resource?.accountId();
|
|
210
|
+
const sameAccount = principalAccount === resourceAccount;
|
|
211
|
+
if (sessionResult && sessionResult !== 'Allowed') {
|
|
212
|
+
return sessionResult;
|
|
213
|
+
}
|
|
214
|
+
// Service Principals
|
|
215
|
+
if (isServicePrincipal(request.request.principal.value())) {
|
|
216
|
+
// Service principals are allowed if the resource policy allows them
|
|
217
|
+
if (resourcePolicyResult === 'Allowed') {
|
|
218
|
+
return 'Allowed';
|
|
219
|
+
}
|
|
220
|
+
return 'ImplicitlyDenied';
|
|
221
|
+
}
|
|
222
|
+
//Same Account
|
|
223
|
+
if (sameAccount) {
|
|
224
|
+
const trustedAccount = this.serviceTrustsPrincipalAccount(sameAccount, request.resourceAnalysis, request.request.resource);
|
|
225
|
+
if (resourcePolicyResult === 'Allowed' ||
|
|
226
|
+
(trustedAccount && identityStatementResult === 'Allowed')) {
|
|
227
|
+
return 'Allowed';
|
|
228
|
+
}
|
|
229
|
+
return 'ImplicitlyDenied';
|
|
230
|
+
}
|
|
231
|
+
//Cross Account
|
|
232
|
+
if (resourcePolicyResult === 'Allowed' || resourcePolicyResult === 'AllowedForAccount') {
|
|
233
|
+
if (identityStatementResult === 'Allowed') {
|
|
234
|
+
return 'Allowed';
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return 'ImplicitlyDenied';
|
|
238
|
+
}
|
|
199
239
|
}
|
|
200
240
|
//# sourceMappingURL=DefaultServiceAuthorizer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultServiceAuthorizer.js","sourceRoot":"","sources":["../../../src/services/DefaultServiceAuthorizer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,kBAAkB,EACnB,MAAM,0BAA0B,CAAA;AACjC,OAAO,
|
|
1
|
+
{"version":3,"file":"DefaultServiceAuthorizer.js","sourceRoot":"","sources":["../../../src/services/DefaultServiceAuthorizer.ts"],"names":[],"mappings":"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"}
|