Skip to content

Commit 55563c0

Browse files
committed
assume the entra role for entra actions
1 parent 48db13c commit 55563c0

File tree

8 files changed

+802
-182
lines changed

8 files changed

+802
-182
lines changed

cloudformation/iam.yml

Lines changed: 149 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,102 @@ Parameters:
1717
Type: String
1818

1919
Resources:
20-
SqsLambdaIAMRole:
20+
# Managed Policy for Common Lambda Permissions
21+
CommonLambdaManagedPolicy:
22+
Type: AWS::IAM::ManagedPolicy
23+
Properties:
24+
ManagedPolicyName: CommonLambdaPolicy
25+
PolicyDocument:
26+
Version: "2012-10-17"
27+
Statement:
28+
- Action:
29+
- logs:CreateLogGroup
30+
- logs:CreateLogStream
31+
- logs:PutLogEvents
32+
Effect: Allow
33+
Resource:
34+
- Fn::Sub: arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${LambdaFunctionName}:*
35+
36+
- Action:
37+
- secretsmanager:GetSecretValue
38+
Effect: Allow
39+
Resource:
40+
- Fn::Sub: arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:infra-core-api-config
41+
42+
- Action:
43+
- dynamodb:DescribeLimits
44+
Effect: Allow
45+
Resource: "*"
46+
47+
# Common DynamoDB Permissions
48+
- Sid: DynamoDBTableAccess
49+
Effect: Allow
50+
Action:
51+
- dynamodb:BatchGetItem
52+
- dynamodb:BatchWriteItem
53+
- dynamodb:ConditionCheckItem
54+
- dynamodb:PutItem
55+
- dynamodb:DescribeTable
56+
- dynamodb:DeleteItem
57+
- dynamodb:GetItem
58+
- dynamodb:Scan
59+
- dynamodb:Query
60+
- dynamodb:UpdateItem
61+
Resource:
62+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-events
63+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-merchstore-purchase-history
64+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-events-tickets
65+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-events-ticketing-metadata
66+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-merchstore-metadata
67+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-iam-userroles
68+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-iam-grouproles
69+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-stripe-links
70+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-membership-provisioning
71+
72+
- Sid: DynamoDBCacheAccess
73+
Effect: Allow
74+
Action:
75+
- dynamodb:BatchGetItem
76+
- dynamodb:BatchWriteItem
77+
- dynamodb:ConditionCheckItem
78+
- dynamodb:PutItem
79+
- dynamodb:DescribeTable
80+
- dynamodb:DeleteItem
81+
- dynamodb:GetItem
82+
- dynamodb:Scan
83+
- dynamodb:Query
84+
- dynamodb:UpdateItem
85+
Resource:
86+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-cache
87+
Condition:
88+
StringNotLike:
89+
"dynamodb:LeadingKeys": "entra_*"
90+
91+
- Sid: DynamoDBIndexAccess
92+
Effect: Allow
93+
Action:
94+
- dynamodb:Query
95+
Resource:
96+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-stripe-links/index/*
97+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-events/index/*
98+
99+
- Sid: DynamoDBStreamAccess
100+
Effect: Allow
101+
Action:
102+
- dynamodb:GetShardIterator
103+
- dynamodb:DescribeStream
104+
- dynamodb:GetRecords
105+
- dynamodb:ListStreams
106+
Resource:
107+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-stripe-links/stream/*
108+
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-events/stream/*
109+
110+
# API Lambda IAM Role
111+
ApiLambdaIAMRole:
21112
Type: AWS::IAM::Role
22113
Properties:
23114
ManagedPolicyArns:
24-
- arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole
115+
- !Ref CommonLambdaManagedPolicy
25116
AssumeRolePolicyDocument:
26117
Version: "2012-10-17"
27118
Statement:
@@ -31,75 +122,71 @@ Resources:
31122
Principal:
32123
Service:
33124
- lambda.amazonaws.com
34-
Policies:
35-
- PolicyName: ses-membership
36-
PolicyDocument:
37-
Version: "2012-10-17"
38-
Statement:
39-
- Action:
40-
- ses:SendEmail
41-
- ses:SendRawEmail
42-
Effect: Allow
43-
Resource: "*"
44-
Condition:
45-
StringEquals:
46-
ses:FromAddress:
47-
Fn::Sub: "membership@${SesEmailDomain}"
48-
ForAllValues:StringLike:
49-
ses:Recipients:
50-
- "*@illinois.edu"
125+
- Action:
126+
- sts:AssumeRole
127+
Effect: Allow
128+
Resource: !GetAtt EntraLambdaIAMRole.Arn
51129

52-
- PolicyName: lambda-logs
130+
Policies:
131+
- PolicyName: lambda-sqs
53132
PolicyDocument:
54133
Version: "2012-10-17"
55134
Statement:
56135
- Action:
57-
- logs:CreateLogGroup
58-
- logs:CreateLogStream
59-
- logs:PutLogEvents
136+
- sqs:SendMessage
60137
Effect: Allow
61138
Resource:
62-
- Fn::Sub: arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${LambdaFunctionName}:*
139+
- Fn::Sub: "${SqsQueueArn}"
63140

64-
- PolicyName: lambda-db-secrets
141+
EntraLambdaIAMRole:
142+
Type: AWS::IAM::Role
143+
Properties:
144+
ManagedPolicyArns:
145+
- !Ref CommonLambdaManagedPolicy
146+
AssumeRolePolicyDocument:
147+
Version: "2012-10-17"
148+
Statement:
149+
- Action:
150+
- sts:AssumeRole
151+
Effect: Allow
152+
Principal:
153+
Service:
154+
- lambda.amazonaws.com
155+
Policies:
156+
- PolicyName: lambda-get-entra-secret
65157
PolicyDocument:
66158
Version: "2012-10-17"
67159
Statement:
68160
- Action:
69161
- secretsmanager:GetSecretValue
70162
Effect: Allow
71163
Resource:
72-
- Fn::Sub: arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:infra-core-api-config*
73-
74-
- PolicyName: lambda-dynamo
75-
PolicyDocument:
76-
Version: "2012-10-17"
77-
Statement:
78-
- Sid: DynamoDBTableAccess
79-
Effect: Allow
80-
Action:
164+
- Fn::Sub: arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:infra-core-api-entra
165+
- Action:
81166
- dynamodb:BatchGetItem
167+
- dynamodb:GetItem
168+
- dynamodb:Scan
169+
- dynamodb:Query
170+
- dynamodb:DescribeTable
82171
- dynamodb:BatchWriteItem
83172
- dynamodb:ConditionCheckItem
84173
- dynamodb:PutItem
85-
- dynamodb:DescribeTable
86174
- dynamodb:DeleteItem
87-
- dynamodb:GetItem
88-
- dynamodb:Scan
89-
- dynamodb:Query
90175
- dynamodb:UpdateItem
176+
Effect: Allow
91177
Resource:
92178
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-cache
179+
Condition:
180+
"StringLike":
181+
"dynamodb:LeadingKeys": "entra_*"
93182

94-
- Sid: DynamoDBDescribeLimitsAccess
95-
Effect: Allow
96-
Action:
97-
- dynamodb:DescribeLimits
98-
Resource: "*"
99-
100-
ApiLambdaIAMRole:
183+
# SQS Lambda IAM Role
184+
SqsLambdaIAMRole:
101185
Type: AWS::IAM::Role
102186
Properties:
187+
ManagedPolicyArns:
188+
- arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole
189+
- !Ref CommonLambdaManagedPolicy
103190
AssumeRolePolicyDocument:
104191
Version: "2012-10-17"
105192
Statement:
@@ -110,103 +197,32 @@ Resources:
110197
Service:
111198
- lambda.amazonaws.com
112199
Policies:
113-
- PolicyName: lambda-sqs
114-
PolicyDocument:
115-
Version: "2012-10-17"
116-
Statement:
117-
- Action:
118-
- sqs:SendMessage
119-
Effect: Allow
120-
Resource:
121-
- Fn::Sub: "${SqsQueueArn}"
122-
123-
- PolicyName: lambda-logs
124-
PolicyDocument:
125-
Version: "2012-10-17"
126-
Statement:
127-
- Action:
128-
- logs:CreateLogGroup
129-
- logs:CreateLogStream
130-
- logs:PutLogEvents
131-
Effect: Allow
132-
Resource:
133-
- Fn::Sub: arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${LambdaFunctionName}:*
134-
135-
- PolicyName: lambda-db-secrets
200+
- PolicyName: ses-membership
136201
PolicyDocument:
137202
Version: "2012-10-17"
138203
Statement:
139204
- Action:
140-
- secretsmanager:GetSecretValue
141-
Effect: Allow
142-
Resource:
143-
- Fn::Sub: arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:infra-core-api-config*
144-
145-
- PolicyName: lambda-dynamo
146-
PolicyDocument:
147-
Version: "2012-10-17"
148-
Statement:
149-
- Sid: DynamoDBIndexAccess
150-
Effect: Allow
151-
Action:
152-
- dynamodb:Query
153-
Resource:
154-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-stripe-links/index/*
155-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-events/index/*
156-
157-
- Sid: DynamoDBStreamAccess
158-
Effect: Allow
159-
Action:
160-
- dynamodb:GetShardIterator
161-
- dynamodb:DescribeStream
162-
- dynamodb:GetRecords
163-
- dynamodb:ListStreams
164-
Resource:
165-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-stripe-links/stream/*
166-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-events/stream/*
167-
168-
- Sid: DynamoDBTableAccess
169-
Effect: Allow
170-
Action:
171-
- dynamodb:BatchGetItem
172-
- dynamodb:BatchWriteItem
173-
- dynamodb:ConditionCheckItem
174-
- dynamodb:PutItem
175-
- dynamodb:DescribeTable
176-
- dynamodb:DeleteItem
177-
- dynamodb:GetItem
178-
- dynamodb:Scan
179-
- dynamodb:Query
180-
- dynamodb:UpdateItem
181-
Resource:
182-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-events
183-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-cache
184-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-merchstore-purchase-history
185-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-events-tickets
186-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-events-ticketing-metadata
187-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-merchstore-metadata
188-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-iam-userroles
189-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-iam-grouproles
190-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-stripe-links
191-
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-membership-provisioning
192-
193-
- Sid: DynamoDBDescribeLimitsAccess
205+
- ses:SendEmail
206+
- ses:SendRawEmail
194207
Effect: Allow
195-
Action:
196-
- dynamodb:DescribeLimits
197208
Resource: "*"
209+
Condition:
210+
StringEquals:
211+
ses:FromAddress:
212+
Fn::Sub: "membership@${SesEmailDomain}"
213+
ForAllValues:StringLike:
214+
ses:Recipients:
215+
- "*@illinois.edu"
198216

199217
Outputs:
200218
MainFunctionRoleArn:
201219
Description: Main API IAM role ARN
202-
Value:
203-
Fn::GetAtt:
204-
- ApiLambdaIAMRole
205-
- Arn
220+
Value: !GetAtt ApiLambdaIAMRole.Arn
206221

207222
SqsFunctionRoleArn:
208-
Description: Sqs IAM role ARN
209-
Value:
210-
Fn::GetAtt:
211-
- SqsLambdaIAMRole
212-
- Arn
223+
Description: SQS IAM role ARN
224+
Value: !GetAtt SqsLambdaIAMRole.Arn
225+
226+
EntraFunctionRoleArn:
227+
Description: Entra IAM role ARN
228+
Value: !GetAtt EntraLambdaIAMRole.Arn

cloudformation/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ Resources:
177177
Environment:
178178
Variables:
179179
RunEnvironment: !Ref RunEnvironment
180+
EntraRoleArn: !GetAtt AppSecurityRoles.Outputs.EntraFunctionRoleArn
180181
VpcConfig:
181182
Ipv6AllowedForDualStack: !If [ShouldAttachVpc, True, !Ref AWS::NoValue]
182183
SecurityGroupIds:

src/api/functions/entraId.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
officersGroupTestingId,
99
} from "../../common/config.js";
1010
import {
11+
BaseError,
1112
EntraFetchError,
1213
EntraGroupError,
1314
EntraInvitationError,
@@ -37,7 +38,7 @@ export async function getEntraIdToken(
3738
scopes: string[] = ["https://graph.microsoft.com/.default"],
3839
) {
3940
const secretApiConfig =
40-
(await getSecretValue(clients.smClient, genericConfig.ConfigSecretName)) ||
41+
(await getSecretValue(clients.smClient, genericConfig.EntraSecretName)) ||
4142
{};
4243
if (
4344
!secretApiConfig.entra_id_private_key ||
@@ -90,6 +91,9 @@ export async function getEntraIdToken(
9091
}
9192
return result?.accessToken ?? null;
9293
} catch (error) {
94+
if (error instanceof BaseError) {
95+
throw error;
96+
}
9397
throw new InternalServerError({
9498
message: `Failed to acquire token: ${error}`,
9599
});

0 commit comments

Comments
 (0)