Skip to content

Commit 34222ad

Browse files
committed
Made it possible to exclude functions or override access list locally
Updated lifecycle hook, so resources are properly generated with package command Introduced tests
1 parent acbf032 commit 34222ad

File tree

8 files changed

+450
-30
lines changed

8 files changed

+450
-30
lines changed

.eslintignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
coverage/
2+
node_modules/

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
.nyc_output/
2+
coverage
13
node_modules
24
*.log

README.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,38 @@ plugins:
1515
- serverless-plugin-lambda-account-access
1616

1717
provider:
18-
permitAccounts: 000001,000002 # CSV list of AWS account numbers
18+
allowAccounts: # can be defined as a single value or an array
19+
- 111111111111 # principal as accountId
20+
- 'arn:aws:iam::222222222222:root' # principal as ARN
1921

2022
functions:
2123
function1:
2224
function2:
25+
allowAccess: false # excludes specific function
26+
function3:
27+
allowAccess: 333333333333 # allows access from these principals instead of the globally defined ones
2328
```
2429
25-
The above allows all functions to be invoked from the listed accounts.
30+
The above allows all functions to be invoked from the principals listed in `provider` section, unless access is explicitly forbidden inside function config (`function2`), or accounts list is overridden locally (`function3`).
2631

2732
Permissions are granted by adding resources of the form:
2833

2934
```yaml
3035
resources:
3136
Resources:
32-
Function1LambdaFunctionPermitInvokeFromAccount000001:
33-
Type: AWS::Lambda::Permission
37+
Function1LambdaFunctionPermitInvokeFrom111111111111:
38+
Type: AWS::Lambda::Permission
3439
Properties:
3540
Action: lambda:InvokeFunction
3641
FunctionName:
3742
Fn::GetAtt:
3843
- Function1LambdaFunction
3944
- Arn
40-
Principal: 000001
45+
Principal: '111111111111'
4146
```
47+
48+
## Migration From 1.x
49+
50+
Version 2 has the following breaking changes:
51+
- `permitAccounts` field was changed to `allowAccess`
52+
- multiple principals can be defined as an array, instead of CSV list

add-permissions.js

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,56 @@ module.exports = class AwsAddLambdaAccountPermissions {
1111
this.options = options;
1212
this.provider = this.serverless.getProvider('aws');
1313
this.hooks = {
14-
'before:deploy:deploy': () => this.beforeDeploy(),
14+
'before:deploy:createDeploymentArtifacts': () => this.beforeDeploy(),
1515
};
1616
}
1717

18-
addPoliciesForAccount(account) {
18+
addPoliciesForFunctions(globalAllowAccess) {
1919
const service = this.serverless.service;
2020
if (typeof service.functions !== 'object') {
2121
return;
2222
}
23+
2324
const resources = service.resources = service.resources || {};
2425
if (!resources.Resources) {
2526
resources.Resources = {};
2627
}
28+
2729
Object.keys(service.functions).forEach(functionName => {
28-
const functionLogicalId = this.provider.naming
29-
.getLambdaLogicalId(functionName);
30-
const resourceName = account.replace(/\b\w/g, l => l.toUpperCase()).replace(/[_\W]+/g, "");
31-
resources.Resources[`${functionLogicalId}PermitInvokeFrom${resourceName}`] = {
32-
Type: 'AWS::Lambda::Permission',
33-
Properties: {
34-
Action: 'lambda:InvokeFunction',
35-
FunctionName: {
36-
'Fn::GetAtt': [ functionLogicalId, 'Arn' ],
37-
},
38-
Principal: account,
39-
}
40-
};
30+
let localAllowAccess = service.functions[functionName].allowAccess;
31+
if (localAllowAccess === false || (globalAllowAccess.length === 0 && !localAllowAccess)) {
32+
return;
33+
}
34+
35+
const functionAllowAccess = localAllowAccess
36+
? [].concat(localAllowAccess)
37+
: globalAllowAccess;
38+
39+
const functionLogicalId = this.provider.naming.getLambdaLogicalId(functionName);
40+
41+
functionAllowAccess.forEach(principal => {
42+
principal = principal.toString();
43+
const resourceName = principal.replace(/\b\w/g, l => l.toUpperCase()).replace(/[_\W]+/g, "");
44+
resources.Resources[`${functionLogicalId}PermitInvokeFrom${resourceName}`] = {
45+
Type: 'AWS::Lambda::Permission',
46+
Properties: {
47+
Action: 'lambda:InvokeFunction',
48+
FunctionName: {
49+
'Fn::GetAtt': [ functionLogicalId, 'Arn' ],
50+
},
51+
Principal: principal
52+
}
53+
};
54+
});
4155
});
4256
}
4357

4458
beforeDeploy() {
4559
const service = this.serverless.service;
46-
const permitAccounts =
47-
service.provider &&
48-
service.provider.permitAccounts &&
49-
service.provider.permitAccounts.toString();
60+
let globalAllowAccess = service.provider && service.provider.allowAccess
61+
? [].concat(service.provider.allowAccess)
62+
: [];
5063

51-
if (permitAccounts) {
52-
permitAccounts.split(',').map(this.addPoliciesForAccount.bind(this));
53-
}
64+
this.addPoliciesForFunctions(globalAllowAccess);
5465
}
5566
};

package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"name": "serverless-plugin-lambda-account-access",
3-
"version": "1.1.1",
3+
"version": "2.0.0",
44
"engines": {
55
"node": ">=4.0"
66
},
77
"description": "A Serverless plugin to allow other accounts to invoke your Lambda functions",
88
"main": "add-permissions.js",
99
"scripts": {
10-
"test": "echo \"No tests yet\"",
10+
"test": "nyc --reporter=lcov --reporter=text mocha",
1111
"posttest": "eslint .",
1212
"preversion": "npm test",
1313
"postversion": "git push --follow-tags"
@@ -23,7 +23,12 @@
2323
],
2424
"license": "MIT",
2525
"devDependencies": {
26-
"eslint": "^3.11.1"
26+
"chai": "^3.5.0",
27+
"eslint": "^3.11.1",
28+
"eslint-plugin-mocha": "^4.9.0",
29+
"mocha": "^3.3.0",
30+
"nyc": "^10.2.0",
31+
"sinon": "^2.1.0"
2732
},
2833
"dependencies": {
2934
"semver": "^5.3.0"

test/.eslintrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
env:
2+
mocha: true
3+
4+
plugins: ["mocha"]

0 commit comments

Comments
 (0)