AWS CDKのGrantsクラスを試してみた
AWS CDKでは、特定のAWSリソースから他のAWSリソースに対してgrantXxxメソッドを利用して権限を付与できます。
grantXxxメソッドを利用すれば、複雑な権限設定をとても簡単に書けます。
例えば、S3バケットに対してread権限を付与したいときは、次のように書けます。
export class CdkSampleStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const func = new NodejsFunction(this, 'Function', {
entry: path.join(__dirname, 'lambda', 'index.ts'),
handler: 'handler',
runtime: Runtime.NODEJS_22_X,
});
const bucket = new Bucket(this, 'Bucket');
// S3バケットがLambda関数に対してread許可を付与
bucket.grantRead(func);
}
}
次のようなIAMポリシーが作成され、S3バケットのreadに関する許可設定が付与されています。
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetBucket*",
"s3:GetObject*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::cdksample-bucketXXXXXXXXX",
"arn:aws:s3:::cdksample-bucketXXXXXXXXX/*"
],
"Effect": "Allow"
}
]
}
新たにGrantクラスを利用できるようになったとのことで調査してみました!
Grantsクラスが利用できるようになりました
2025年11月21日にCDKのバージョンがv2.227.0に更新され、S3・DynamoDB・Step FunctionsのGrantsオブジェクトが追加されています。
s3: add BucketGrants
dynamodb: add TableGrants and StreamGrants
stepfunctions: add StateMachineGrants
aws-cdk Releases/v2.227.0
このGrantsオブジェクトがどのように利用できるのか検証していきます。
仕様調査
AWS CDKのAPIリファレンスには、今のところあまり情報が載っていませんでした。
Collection of grant methods for a Bucket.
BucketGrantsA set of permissions to grant on a Table.
TableGrantsCollection of grant methods for a IStateMachineRef.
StateMachineGrants
AWS DevTools Hero 後藤さんによると、GrantsクラスはL1, L2どちらのConstructにも適用できるみたいです。
L1 Constructにも適用できることで、これまでL1しかなかったリソースや、L1のまま利用していたリソースにもGrantが利用できそうです!
また、これまで利用できていたgrantXxxメソッドは、引き続き利用できるみたいです。
これも後藤さんからの情報ですがgrantXxxメソッドは利用できるものの今後は非推奨になるみたいです。
やってみた
ということで新しい Grants クラスを利用してL1, L2 Constructに対して権限を付与してみます。
L2 Constructへの適用
まずは今までもgrantXxxメソッドが利用できていたL2 ConstructでGrantsクラスを利用してみます。
ドキュメントを見るとL2 Constructにgrantsメソッドが実装されています。
grants
Type: BucketGrants
Collection of grant methods for a Bucket.
BucketGrantsクラスには、readやdelete、publicAccessなど、今までgrantXxxメソッドとして存在していたメソッドが実装されています。
Collection of grant methods for a Bucket.
BucketGrants
概要がわかったので置き換えてみます。
これまで利用していたgrantXxxメソッドはこのように書けました。
(あとで比較できるように、ここでスナップショットテストを保存しています)
export class CdkSampleStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const func = new NodejsFunction(this, 'Function', {
entry: path.join(__dirname, 'lambda', 'index.ts'),
handler: 'handler',
runtime: Runtime.NODEJS_22_X,
});
const bucket = new Bucket(this, 'Bucket');
// read権限の付与
bucket.grantRead(func);
}
}
Grantsクラスに置き換えてみましたが、簡単に変更できました。
export class CdkSampleStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const func = new NodejsFunction(this, 'Function', {
entry: path.join(__dirname, 'lambda', 'index.ts'),
handler: 'handler',
runtime: Runtime.NODEJS_22_X,
});
const bucket = new Bucket(this, 'Bucket');
- bucket.grantRead(func);
+ bucket.grants.read(func);
}
}
スナップショットテストを実行してみましたが、変更なしでした。
> vitest
...
✓ test/cdk-sample.test.ts (1 test) 119ms
✓ Snapshot test 119ms
Test Files 1 passed (1)
Tests 1 passed (1)
...
L1 Constructへの適用
L1へ適用するためにBucketGrantsクラスのドキュメントをしばらく覗いていましたが、それらしき記述はありませんでした。
BucketGrantsクラスの実装を見てみると、_fromBucketというstaticメソッドが実装されていました。
/**
* Creates grants for an IBucketRef
*
* @internal
*/
static _fromBucket(bucket: IBucketRef): BucketGrants;
IBucketRefを受け取ってBucketGrantsメソッドを返すので、このメソッドを利用すれば権限が付与できそうです。
しかし、internalメソッドであるため、外部利用は本来想定されていないようです。
もし他に利用できる方法があれば教えてください!
外部利用は想定されていなさそうですが、利用できそうなので試してみます。
まず、S3バケットのL1を利用して、S3バケットread権限がついた状態を実装します。
(ここでスナップショットテストも更新してます)
export class CdkSampleStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const cfnBucket = new CfnBucket(this, 'Bucket');
const role = new Role(this, 'FunctionServiceRole', {
assumedBy: new ServicePrincipal('lambda.amazonaws.com'),
managedPolicies: [
ManagedPolicy.fromAwsManagedPolicyName(
'service-role/AWSLambdaBasicExecutionRole',
),
],
});
role.addToPolicy(
new PolicyStatement({
actions: ['s3:GetObject*', 's3:GetBucket*', 's3:List*'],
resources: [cfnBucket.attrArn, `${cfnBucket.attrArn}/*`],
}),
);
const func = new NodejsFunction(this, 'Function', {
entry: 'lib/lambda/index.ts',
handler: 'handler',
runtime: Runtime.NODEJS_22_X,
// read権限の付与
role,
});
}
}
BucketGrantsクラスの_fromBucketメソッドを利用して実装します。
こちらはかなりスッキリしましたね!
export class CdkSampleStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const cfnBucket = new CfnBucket(this, 'Bucket');
const func = new NodejsFunction(this, 'Function', {
entry: 'lib/lambda/index.ts',
handler: 'handler',
runtime: Runtime.NODEJS_22_X,
});
const grants = BucketGrants._fromBucket(cfnBucket);
// read権限の付与
grants.read(func);
}
}
スナップショットテストを実行してみると、変更がないことがわかります。
> vitest
...
✓ test/cdk-sample.test.ts (1 test) 119ms
✓ Snapshot test 119ms
Test Files 1 passed (1)
Tests 1 passed (1)
...
まとめ
新しく実装されたGrantsクラスを利用して権限の付与を試してみました。
L2での使い勝手はほぼ変わらず、L1でも使える様になりました!
L1のGrantsクラスは、今後_fromXxxメソッドが公開される形になるのでしょうか?
いずれにせよ続報を待つこととします!
Discussion