docs
0
# Permissions and Policies
1
2
Comprehensive permission management for Lambda functions through resource-based policies, enabling fine-grained access control for AWS services, accounts, and external entities to invoke functions.
3
4
## Capabilities
5
6
### Function Permission Management
7
8
Manages resource-based IAM policies that control who can invoke Lambda functions and under what conditions.
9
10
#### Add Permission
11
12
Grants permission for AWS services, accounts, or other entities to invoke a Lambda function.
13
14
```java { .api }
15
/**
16
* Grants permission for AWS service or account to invoke Lambda function
17
* @param request Permission grant parameters including principal, action, and conditions
18
* @return AddPermissionResult containing statement ID and updated policy
19
* @throws ServiceException if service encounters an error
20
* @throws ResourceNotFoundException if function does not exist
21
* @throws ResourceConflictException if statement ID already exists
22
* @throws PolicyLengthExceededException if policy exceeds maximum size limit
23
* @throws PreconditionFailedException if revision ID mismatch
24
*/
25
AddPermissionResult addPermission(AddPermissionRequest request);
26
27
public class AddPermissionRequest {
28
/** Function name (required) - name, ARN, or partial ARN */
29
private String functionName;
30
/** Statement ID (required) - unique identifier for permission statement */
31
private String statementId;
32
/** Action (required) - lambda:InvokeFunction or lambda:* */
33
private String action;
34
/** Principal (required) - AWS service, account ID, or "*" */
35
private String principal;
36
/** Source ARN (optional) - ARN of AWS resource triggering invocation */
37
private String sourceArn;
38
/** Source account (optional) - AWS account ID for additional security */
39
private String sourceAccount;
40
/** Event source token (optional) - token for Alexa Smart Home skills */
41
private String eventSourceToken;
42
/** Function version or alias (optional) - defaults to $LATEST */
43
private String qualifier;
44
/** Revision ID for optimistic locking (optional) */
45
private String revisionId;
46
/** Principal organization ID (optional) - restrict to specific organization */
47
private String principalOrgId;
48
/** Function URL auth type (optional) - AWS_IAM or NONE */
49
private FunctionUrlAuthType functionUrlAuthType;
50
}
51
52
public class AddPermissionResult {
53
/** JSON representation of updated policy statement */
54
private String statement;
55
}
56
```
57
58
#### Remove Permission
59
60
Revokes previously granted permission from a Lambda function's resource-based policy.
61
62
```java { .api }
63
/**
64
* Revokes permission from Lambda function resource-based policy
65
* @param request Permission revocation parameters including statement ID
66
* @return RemovePermissionResult indicating successful removal
67
* @throws ServiceException if service encounters an error
68
* @throws ResourceNotFoundException if function or statement does not exist
69
* @throws PreconditionFailedException if revision ID mismatch
70
*/
71
RemovePermissionResult removePermission(RemovePermissionRequest request);
72
73
public class RemovePermissionRequest {
74
/** Function name (required) - name, ARN, or partial ARN */
75
private String functionName;
76
/** Statement ID (required) - identifier of permission statement to remove */
77
private String statementId;
78
/** Function version or alias (optional) - defaults to $LATEST */
79
private String qualifier;
80
/** Revision ID for optimistic locking (optional) */
81
private String revisionId;
82
}
83
84
public class RemovePermissionResult {
85
// Empty result indicating successful removal
86
}
87
```
88
89
#### Get Policy
90
91
Retrieves the complete resource-based IAM policy for a Lambda function.
92
93
```java { .api }
94
/**
95
* Retrieves complete resource-based IAM policy document for Lambda function
96
* @param request Policy retrieval parameters including function name
97
* @return GetPolicyResult containing policy document and revision ID
98
* @throws ServiceException if service encounters an error
99
* @throws ResourceNotFoundException if function or policy does not exist
100
*/
101
GetPolicyResult getPolicy(GetPolicyRequest request);
102
103
public class GetPolicyRequest {
104
/** Function name (required) - name, ARN, or partial ARN */
105
private String functionName;
106
/** Function version or alias (optional) - defaults to $LATEST */
107
private String qualifier;
108
}
109
110
public class GetPolicyResult {
111
/** Resource-based policy document in JSON format */
112
private String policy;
113
/** Revision ID for optimistic locking */
114
private String revisionId;
115
}
116
```
117
118
## Usage Examples
119
120
### Granting Service Permissions
121
122
```java
123
AWSLambda lambdaClient = AWSLambdaClientBuilder.defaultClient();
124
125
// Allow S3 to invoke function for bucket notifications
126
AddPermissionRequest s3Permission = new AddPermissionRequest()
127
.withFunctionName("document-processor")
128
.withStatementId("allow-s3-invoke")
129
.withAction("lambda:InvokeFunction")
130
.withPrincipal("s3.amazonaws.com")
131
.withSourceArn("arn:aws:s3:::my-document-bucket")
132
.withSourceAccount("123456789012");
133
134
AddPermissionResult result = lambdaClient.addPermission(s3Permission);
135
System.out.println("Added S3 permission: " + result.getStatement());
136
```
137
138
### Granting Cross-Account Access
139
140
```java
141
// Allow another AWS account to invoke function
142
AddPermissionRequest crossAccountPermission = new AddPermissionRequest()
143
.withFunctionName("shared-api-function")
144
.withStatementId("allow-partner-account")
145
.withAction("lambda:InvokeFunction")
146
.withPrincipal("987654321098"); // Partner account ID
147
148
lambdaClient.addPermission(crossAccountPermission);
149
150
// Allow specific account with additional organization restriction
151
AddPermissionRequest orgRestrictedPermission = new AddPermissionRequest()
152
.withFunctionName("internal-service")
153
.withStatementId("allow-internal-account")
154
.withAction("lambda:InvokeFunction")
155
.withPrincipal("555666777888")
156
.withPrincipalOrgId("o-example12345"); // Must be in our organization
157
158
lambdaClient.addPermission(orgRestrictedPermission);
159
```
160
161
### API Gateway Integration
162
163
```java
164
// Grant API Gateway permission to invoke function
165
AddPermissionRequest apiGatewayPermission = new AddPermissionRequest()
166
.withFunctionName("api-backend")
167
.withStatementId("allow-api-gateway")
168
.withAction("lambda:InvokeFunction")
169
.withPrincipal("apigateway.amazonaws.com")
170
.withSourceArn("arn:aws:execute-api:us-east-1:123456789012:abcd123456/*/GET/users");
171
172
lambdaClient.addPermission(apiGatewayPermission);
173
174
// For REST API with wildcard path
175
AddPermissionRequest restApiPermission = new AddPermissionRequest()
176
.withFunctionName("rest-api-handler")
177
.withStatementId("allow-rest-api")
178
.withAction("lambda:InvokeFunction")
179
.withPrincipal("apigateway.amazonaws.com")
180
.withSourceArn("arn:aws:execute-api:us-east-1:123456789012:*/*/ANY/*");
181
182
lambdaClient.addPermission(restApiPermission);
183
```
184
185
### EventBridge (CloudWatch Events) Integration
186
187
```java
188
// Allow EventBridge to invoke function
189
AddPermissionRequest eventBridgePermission = new AddPermissionRequest()
190
.withFunctionName("event-processor")
191
.withStatementId("allow-eventbridge")
192
.withAction("lambda:InvokeFunction")
193
.withPrincipal("events.amazonaws.com")
194
.withSourceArn("arn:aws:events:us-east-1:123456789012:rule/my-scheduled-rule");
195
196
lambdaClient.addPermission(eventBridgePermission);
197
```
198
199
### CloudWatch Logs Integration
200
201
```java
202
// Allow CloudWatch Logs to invoke function for log processing
203
AddPermissionRequest logsPermission = new AddPermissionRequest()
204
.withFunctionName("log-analyzer")
205
.withStatementId("allow-cloudwatch-logs")
206
.withAction("lambda:InvokeFunction")
207
.withPrincipal("logs.amazonaws.com")
208
.withSourceArn("arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/my-function:*");
209
210
lambdaClient.addPermission(logsPermission);
211
```
212
213
### Alexa Skills Integration
214
215
```java
216
// Allow Alexa Skills Kit to invoke function
217
AddPermissionRequest alexaPermission = new AddPermissionRequest()
218
.withFunctionName("alexa-skill-handler")
219
.withStatementId("allow-alexa")
220
.withAction("lambda:InvokeFunction")
221
.withPrincipal("alexa-appkit.amazon.com")
222
.withEventSourceToken("amzn1.ask.skill.12345678-1234-1234-1234-123456789012");
223
224
lambdaClient.addPermission(alexaPermission);
225
```
226
227
### Function URL Permissions
228
229
```java
230
// Configure function URL with IAM authentication
231
AddPermissionRequest functionUrlPermission = new AddPermissionRequest()
232
.withFunctionName("public-api")
233
.withStatementId("allow-function-url")
234
.withAction("lambda:InvokeFunctionUrl")
235
.withPrincipal("*")
236
.withFunctionUrlAuthType(FunctionUrlAuthType.NONE); // Public access
237
238
lambdaClient.addPermission(functionUrlPermission);
239
```
240
241
### Managing Permissions for Aliases
242
243
```java
244
// Grant permission specifically for production alias
245
AddPermissionRequest prodAliasPermission = new AddPermissionRequest()
246
.withFunctionName("my-function")
247
.withQualifier("PROD")
248
.withStatementId("allow-prod-s3-invoke")
249
.withAction("lambda:InvokeFunction")
250
.withPrincipal("s3.amazonaws.com")
251
.withSourceArn("arn:aws:s3:::production-bucket");
252
253
lambdaClient.addPermission(prodAliasPermission);
254
255
// Different permission for staging alias
256
AddPermissionRequest stagingAliasPermission = new AddPermissionRequest()
257
.withFunctionName("my-function")
258
.withQualifier("STAGING")
259
.withStatementId("allow-staging-s3-invoke")
260
.withAction("lambda:InvokeFunction")
261
.withPrincipal("s3.amazonaws.com")
262
.withSourceArn("arn:aws:s3:::staging-bucket");
263
264
lambdaClient.addPermission(stagingAliasPermission);
265
```
266
267
### Policy Management and Auditing
268
269
```java
270
public class PolicyManager {
271
private final AWSLambda lambdaClient;
272
273
public PolicyManager(AWSLambda lambdaClient) {
274
this.lambdaClient = lambdaClient;
275
}
276
277
/**
278
* Audit function permissions and print policy details
279
*/
280
public void auditFunctionPermissions(String functionName) {
281
try {
282
GetPolicyRequest request = new GetPolicyRequest()
283
.withFunctionName(functionName);
284
285
GetPolicyResult result = lambdaClient.getPolicy(request);
286
System.out.println("Function: " + functionName);
287
System.out.println("Policy Revision: " + result.getRevisionId());
288
System.out.println("Policy Document:");
289
290
// Parse and pretty-print JSON policy
291
ObjectMapper mapper = new ObjectMapper();
292
JsonNode policy = mapper.readTree(result.getPolicy());
293
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(policy));
294
295
} catch (ResourceNotFoundException e) {
296
System.out.println("No resource-based policy found for function: " + functionName);
297
} catch (Exception e) {
298
System.err.println("Error retrieving policy: " + e.getMessage());
299
}
300
}
301
302
/**
303
* Bulk remove permissions by statement ID pattern
304
*/
305
public void removePermissionsByPattern(String functionName, String statementIdPattern) {
306
try {
307
GetPolicyResult policyResult = lambdaClient.getPolicy(
308
new GetPolicyRequest().withFunctionName(functionName));
309
310
ObjectMapper mapper = new ObjectMapper();
311
JsonNode policy = mapper.readTree(policyResult.getPolicy());
312
JsonNode statements = policy.get("Statement");
313
314
if (statements.isArray()) {
315
for (JsonNode statement : statements) {
316
String sid = statement.get("Sid").asText();
317
if (sid.matches(statementIdPattern)) {
318
RemovePermissionRequest removeRequest = new RemovePermissionRequest()
319
.withFunctionName(functionName)
320
.withStatementId(sid);
321
322
lambdaClient.removePermission(removeRequest);
323
System.out.println("Removed permission: " + sid);
324
}
325
}
326
}
327
328
} catch (ResourceNotFoundException e) {
329
System.out.println("No policy found for function: " + functionName);
330
} catch (Exception e) {
331
System.err.println("Error managing permissions: " + e.getMessage());
332
}
333
}
334
335
/**
336
* Safely update permission with revision checking
337
*/
338
public void updatePermission(String functionName, String statementId,
339
String newPrincipal, String sourceArn) {
340
try {
341
// Get current policy revision
342
GetPolicyResult currentPolicy = lambdaClient.getPolicy(
343
new GetPolicyRequest().withFunctionName(functionName));
344
345
// Remove old permission
346
RemovePermissionRequest removeRequest = new RemovePermissionRequest()
347
.withFunctionName(functionName)
348
.withStatementId(statementId)
349
.withRevisionId(currentPolicy.getRevisionId());
350
351
lambdaClient.removePermission(removeRequest);
352
353
// Add new permission
354
AddPermissionRequest addRequest = new AddPermissionRequest()
355
.withFunctionName(functionName)
356
.withStatementId(statementId)
357
.withAction("lambda:InvokeFunction")
358
.withPrincipal(newPrincipal)
359
.withSourceArn(sourceArn);
360
361
lambdaClient.addPermission(addRequest);
362
System.out.println("Updated permission: " + statementId);
363
364
} catch (PreconditionFailedException e) {
365
System.err.println("Policy was modified concurrently. Retry required.");
366
} catch (Exception e) {
367
System.err.println("Error updating permission: " + e.getMessage());
368
}
369
}
370
}
371
```
372
373
### Removing Permissions
374
375
```java
376
// Remove specific permission by statement ID
377
RemovePermissionRequest removeRequest = new RemovePermissionRequest()
378
.withFunctionName("my-function")
379
.withStatementId("allow-s3-invoke");
380
381
lambdaClient.removePermission(removeRequest);
382
System.out.println("Removed S3 invoke permission");
383
384
// Remove permission from specific alias
385
RemovePermissionRequest removeAliasRequest = new RemovePermissionRequest()
386
.withFunctionName("my-function")
387
.withQualifier("PROD")
388
.withStatementId("allow-prod-s3-invoke");
389
390
lambdaClient.removePermission(removeAliasRequest);
391
```
392
393
## Exception Handling
394
395
Common exceptions when managing permissions:
396
397
- **ResourceNotFoundException**: Function, version, alias, or statement does not exist
398
- **ResourceConflictException**: Statement ID already exists during permission addition
399
- **PolicyLengthExceededException**: Policy document exceeds 20 KB size limit
400
- **PreconditionFailedException**: Revision ID mismatch during concurrent modifications
401
- **InvalidParameterValueException**: Invalid principal, action, or ARN format
402
- **ServiceException**: General service errors
403
- **TooManyRequestsException**: Rate limiting exceeded
404
405
## Best Practices
406
407
### Security Principles
408
- Follow least privilege principle - grant minimal necessary permissions
409
- Use specific source ARNs rather than wildcard principals when possible
410
- Include source account restrictions for additional security layer
411
- Regularly audit and review function permissions
412
413
### Statement Management
414
- Use descriptive, consistent statement IDs for easier management
415
- Include version or date in statement IDs for tracking changes
416
- Document the purpose and business justification for each permission
417
- Implement automated permission cleanup for unused statements
418
419
### Cross-Service Integration
420
- Understand service-specific principal formats (e.g., "s3.amazonaws.com")
421
- Use appropriate source ARN patterns for different AWS services
422
- Test permissions thoroughly in non-production environments
423
- Monitor failed invocations due to permission issues
424
425
### Policy Organization
426
- Keep policies organized and well-documented
427
- Use consistent naming conventions for statement IDs
428
- Implement version control for policy changes
429
- Set up monitoring and alerting for policy modifications