Skip to content

Commit

Permalink
change to grantinvoke
Browse files Browse the repository at this point in the history
  • Loading branch information
roger-zhangg committed Apr 18, 2024
1 parent aa9d4ca commit fc612e3
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 382 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Expand Up @@ -78,7 +78,7 @@
"PrincipalOrgID": "o-xxxxxxxxxx"
}
},
"MyLambdaInvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ48B59B4A": {
"MyLambdaInvokeiasez2Hq1vE2Fl1I4Yaq8UbNdwu1QsvuMXzIoTAF759EB93": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
Expand All @@ -92,7 +92,7 @@
"PrincipalOrgID": "o-yyyyyyyyyy2"
}
},
"MyLambdaInvokefy1YgRC9j8kJQBgyNsNsleYXOlPp4RTnXEx2NNmcs4CE101ED": {
"MyLambdaInvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c0F884F73": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Expand Up @@ -17,9 +17,9 @@ fn.grantInvoke(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy'));

fn.grantInvoke(new iam.OrganizationPrincipal('o-xxxxxxxxxx'));

fn.grantInvokeV2(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2'));
fn.grantInvoke(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2'), { onlyGrantLatestVersion: true });

fn.grantInvokeV2(new iam.OrganizationPrincipal('o-xxxxxxxxxx2'));
fn.grantInvoke(new iam.OrganizationPrincipal('o-xxxxxxxxxx2'), { onlyGrantLatestVersion: true });

const fnUrl = fn.addFunctionUrl();
const role = new iam.Role(stack, 'MyRole', {
Expand Down
Expand Up @@ -116,11 +116,8 @@ export class EdgeFunction extends Resource implements lambda.IVersion {
public addToRolePolicy(statement: iam.PolicyStatement): void {
return this.lambda.addToRolePolicy(statement);
}
public grantInvoke(identity: iam.IGrantable): iam.Grant {
return this.lambda.grantInvoke(identity);
}
public grantInvokeV2(identity: iam.IGrantable, grantVersionAccess?: boolean): iam.Grant {
return this.lambda.grantInvokeV2(identity, grantVersionAccess);
public grantInvoke(identity: iam.IGrantable, props?: lambda.GrantInvokeProps): iam.Grant {
return this.lambda.grantInvoke(identity, props);
}
public grantInvokeUrl(identity: iam.IGrantable): iam.Grant {
return this.lambda.grantInvokeUrl(identity);
Expand Down
5 changes: 2 additions & 3 deletions packages/aws-cdk-lib/aws-lambda/README.md
Expand Up @@ -201,15 +201,14 @@ You can also restrict permissions given to AWS services by providing
a source account or ARN (representing the account and identifier of the resource
that accesses the function or layer).

**Important**: Be aware that `fn.grantInvoke()` grants permission to the principal to call any version of the function, including all past ones. If you only want the principal to invoke the latest version, use `fn.grantInvokeV2()` instead.
**Important**: By default `fn.grantInvoke()` grants permission to the principal to invoke any version of the function, including all past ones. If you only want the principal to invoke the latest version, use `grantInvoke(grantee, { onlyGrantLatestVersion:true })`.

```ts
// Grant permissions to a service
declare const fn: lambda.Function;
const principal = new iam.ServicePrincipal('my-service');

fn.grantInvokeV2(principal, false);
// false is the default and can be omitted
grantInvoke(principal, { onlyGrantLatestVersion = true });
```

For more information, see
Expand Down
63 changes: 23 additions & 40 deletions packages/aws-cdk-lib/aws-lambda/lib/function-base.ts
Expand Up @@ -95,13 +95,7 @@ export interface IFunction extends IResource, ec2.IConnectable, iam.IGrantable {
/**
* Grant the given identity permissions to invoke this Lambda
*/
grantInvoke(grantee: iam.IGrantable): iam.Grant;

/**
* Grant the given identity permissions to invoke to $Latest version when grantVersionAccess is false
* Grant the given identity permissions to invoke All version when grantVersionAccess is true
*/
grantInvokeV2(grantee: iam.IGrantable, grantVersionAccess?: boolean): iam.Grant;
grantInvoke(grantee: iam.IGrantable, props?: GrantInvokeProps): iam.Grant;

/**
* Grant the given identity permissions to invoke this Lambda Function URL
Expand Down Expand Up @@ -233,6 +227,19 @@ export interface FunctionAttributes {
readonly architecture?: Architecture;
}

/**
* Parameters to pass into grantInvoke method
*/
export interface GrantInvokeProps {
/**
* Controls whether to grant invoke access to all function versions. Defaults to `false`.
* - When set to `false`, both the function and functions with specific versions can be invoked.
* - When set to `true`, only the function without a specific version (`$Latest`) can be invoked.
* @default false
*/
readonly onlyGrantLatestVersion?: boolean;
}

export abstract class FunctionBase extends Resource implements IFunction, ec2.IClientVpnConnectionHandler {
/**
* The principal this Lambda Function is running as
Expand Down Expand Up @@ -424,51 +431,27 @@ export abstract class FunctionBase extends Resource implements IFunction, ec2.IC

/**
* Grant the given identity permissions to invoke this Lambda
*/
public grantInvoke(grantee: iam.IGrantable): iam.Grant {
const hash = createHash('sha256')
.update(JSON.stringify({
principal: grantee.grantPrincipal.toString(),
conditions: grantee.grantPrincipal.policyFragment.conditions,
}), 'utf8')
.digest('base64');
const identifier = `Invoke${hash}`;

// Memoize the result so subsequent grantInvoke() calls are idempotent
let grant = this._invocationGrants[identifier];
if (!grant) {
grant = this.grant(grantee, identifier, 'lambda:InvokeFunction', this.resourceArnsForGrantInvoke);
this._invocationGrants[identifier] = grant;
}
return grant;
}

/**
* Grants the specified identity permissions to invoke this Lambda function.
*
* **Important:** Avoid using `grantInvokeV2` in conjunction with `grantInvoke`.
*
* @param grantee The principal (identity) to grant invocation permission.
* @param grantVersionAccess (Optional) Controls whether to grant access to all function versions. Defaults to `false`.
* - When set to `false`, only the function without a specific version (`$Latest`) can be invoked.
* - When set to `true`, both the function and functions with specific versions can be invoked.
* @param props onlyGrantLatestVersion (Optional) Controls whether to grant access only to latest function versions. Defaults to `false`.
* - When set to `false`, both the function and functions with specific versions can be invoked.
* - When set to `true`, only the function without a specific version (`$Latest`) can be invoked.
*/
public grantInvokeV2(grantee: iam.IGrantable, grantVersionAccess?: boolean): iam.Grant {
public grantInvoke(grantee: iam.IGrantable, props: GrantInvokeProps = {}): iam.Grant {
const hash = createHash('sha256')
.update(JSON.stringify({
principal: grantee.grantPrincipal.toString(),
conditions: grantee.grantPrincipal.policyFragment.conditions,
grantVersionAccess: grantVersionAccess,
onlyGrantLatestVersion: props.onlyGrantLatestVersion,
}), 'utf8')
.digest('base64');
const identifier = `Invoke${hash}`;

// Memoize the result so subsequent grantInvokeV2() calls are idempotent
// Memoize the result so subsequent grantInvoke() calls are idempotent
let grant = this._invocationGrants[identifier];
if (!grant) {
let resouceArns = [this.functionArn];
if (grantVersionAccess) {
resouceArns = this.resourceArnsForGrantInvoke;
let resouceArns = this.resourceArnsForGrantInvoke;
if (props.onlyGrantLatestVersion) {
resouceArns = [this.functionArn];
}
grant = this.grant(grantee, identifier, 'lambda:InvokeFunction', resouceArns);
this._invocationGrants[identifier] = grant;
Expand Down

0 comments on commit fc612e3

Please sign in to comment.