https://github.com/k9securityio/k9-cdk
Provision strong AWS security policies easily using the AWS CDK, v1 or v2.
https://github.com/k9securityio/k9-cdk
aws cdk iam
Last synced: 10 days ago
JSON representation
Provision strong AWS security policies easily using the AWS CDK, v1 or v2.
- Host: GitHub
- URL: https://github.com/k9securityio/k9-cdk
- Owner: k9securityio
- License: apache-2.0
- Created: 2020-10-01T23:03:58.000Z (over 5 years ago)
- Default Branch: v2-main
- Last Pushed: 2025-01-20T20:09:47.000Z (about 1 year ago)
- Last Synced: 2025-10-09T05:16:30.062Z (4 months ago)
- Topics: aws, cdk, iam
- Language: TypeScript
- Homepage:
- Size: 1.13 MB
- Stars: 9
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-cdk - k9-cdk - Construct to generate secure S3 bucket policies easily. (Construct Libraries / Security)
README
# k9 AWS CDK policy library #
k9 Security's `k9-cdk` for CDKv2 ([CDKv1](https://github.com/k9securityio/k9-cdk/tree/main)) makes strong security usable and helps you provision best practice AWS security policies
defined using the simplified [k9 access capability model](https://k9security.io/docs/k9-access-capability-model/) and
safe defaults. In CDK terms, this library provides [Curated (L2) constructs](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html) that wrap core CloudFormation resources (L1) to simplify security.
Supported services:
* S3
* KMS
* DynamoDB
* SQS
This library [simplifies IAM as described in Effective IAM for AWS](https://www.effectiveiam.com/simplify-aws-iam) and is fully-supported by k9 Security. We're happy to answer questions or help you integrate it via a [GitHub issue](https://github.com/k9securityio/k9-cdk/issues) or email to [support@k9security.io](mailto:support@k9security.io?subject=k9-cdk).
## Usage
Use the k9 CDK to generate a policy and use it in your existing code base.
For example, the following code will:
1. provision an S3 Bucket
2. allow the `ci` and `person1` users to administer the bucket
3. allow administrators and `k9-auditor` to read bucket configuration
4. allow the `app-backend` role to write data into the bucket
5. allow the `app-backend` and `customer-service` role to read data in the bucket
```typescript
import * as cdk from "aws-cdk-lib";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as k9 from "@k9securityio/k9-cdk";
// Define which principals may access the bucket and what capabilities they should have
const administerResourceArns = [
"arn:aws:iam::123456789012:user/ci",
"arn:aws:iam::123456789012:user/person1"
];
const readConfigArns = administerResourceArns.concat([
"arn:aws:iam::123456789012:role/k9-auditor",
"arn:aws:iam::123456789012:role/aws-service-role/access-analyzer.amazonaws.com/AWSServiceRoleForAccessAnalyzer"
]);
const app = new cdk.App();
const stack = new cdk.Stack(app, 'K9Example');
const bucket = new s3.Bucket(stack, 'TestBucket', {});
const k9BucketPolicyProps: k9.s3.K9BucketPolicyProps = {
bucket: bucket,
k9DesiredAccess: new Array(
{ // declare access capabilities individually
accessCapability: k9.k9policy.AccessCapability.ADMINISTER_RESOURCE,
allowPrincipalArns: administerResourceArns,
},
{
accessCapability: k9.k9policy.AccessCapability.READ_CONFIG,
allowPrincipalArns: readConfigArns,
},
{ // or declare multiple access capabilities at once
accessCapabilities: [
k9.k9policy.AccessCapability.READ_DATA,
k9.k9policy.AccessCapability.WRITE_DATA
],
allowPrincipalArns: [
"arn:aws:iam::123456789012:role/app-backend",
],
},
{
accessCapability: k9.k9policy.AccessCapability.READ_DATA,
allowPrincipalArns: [
"arn:aws:iam::123456789012:role/customer-service"
],
}
// omit access spec for delete-data because it is unneeded
)
};
k9.s3.grantAccessViaResourcePolicy(stack, "S3Bucket", k9BucketPolicyProps);
```
Granting access to an SQS queue works the same way, using the `k9.sqs.grantAccessViaResourcePolicy` function:
```typescript
import * as sqs from 'aws-cdk-lib/aws-sqs';
const queue = new sqs.Queue(stack, 'Queue', {
queueName: 'app-queue-with-k9-policy',
});
const k9SQSResourcePolicyProps: K9SQSResourcePolicyProps = {
queue: queue,
// reuse bucket's desired access for brevity; configure k9DesiredAccess however you need
k9DesiredAccess: k9BucketPolicyProps.k9DesiredAccess,
};
k9.sqs.grantAccessViaResourcePolicy(k9SQSResourcePolicyProps);
```
Granting access to a KMS key is similar, but the custom resource policy is created first
so it can be set via `props` per CDK convention:
```typescript
import * as kms from "aws-cdk-lib/aws-kms";
import {PolicyDocument} from "aws-cdk-lib/aws-iam";
const k9KeyPolicyProps: k9.kms.K9KeyPolicyProps = {
k9DesiredAccess: k9BucketPolicyProps.k9DesiredAccess
};
const keyPolicy: PolicyDocument = k9.kms.makeKeyPolicy(k9KeyPolicyProps);
new kms.Key(stack, 'KMSKey', {
alias: 'app-key-with-k9-policy',
policy: keyPolicy
});
```
Protecting a DynamoDB table follows the same path as KMS, generating a policy then providing it to the DynamoDB table construct via props:
```typescript
import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
const ddbResourcePolicyProps: k9.dynamodb.K9DynamoDBResourcePolicyProps = {
k9DesiredAccess: k9BucketPolicyProps.k9DesiredAccess
};
const ddbResourcePolicy = k9.dynamodb.makeResourcePolicy(ddbResourcePolicyProps);
const table = new dynamodb.TableV2(stack, 'app-table-with-k9-policy', {
partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
resourcePolicy: ddbResourcePolicy,
});
```
## Example stack
The example stack demonstrates full use of the k9 S3, KMS, and DynamoDB policy generators. Generated policies:
S3 Bucket Policy:
* [Templatized Bucket Policy](examples/generated.bucket-policy.json)
* [BucketPolicy resource in CFn template](examples/K9Example.template.json)
SQS Queue Policy:
* [Templatized Queue Policy](examples/generated.queue-policy.json)
* [TestQueuePolicy resource in CFn template](examples/K9Example.template.json)
KMS Key Policy:
* [Templatized Key Policy](examples/generated.key-policy.json)
* [KeyPolicy attribute of Key resource in CFn template](examples/K9Example.template.json)
DynamoDB Resource Policy:
* [Templatized DynamoDB Resource Policy](examples/generated.dynamodb-policy.json)
* [ResourcePolicy attribute of GlobalTable resource in CFn template](examples/K9Example.template.json)
## Specialized Use Cases
k9-cdk can be configured to support specialized use cases, including:
* [Public Bucket](docs/use-case-public-bucket.md) - Publicly readable objects, least privilege for all other actions
## Local Development and Testing
The high level build commands for this project are driven by `make`:
* `make all` - build library, run tests, and deploy
* `make build` - build the library
* `make converge` - deploy the integration test resources
* `make destroy` - destroy the integration test resources
The low level build commands for this project are:
* `npx projen build` compile typescript to js, lint, transpile with JSII, execute tests
* `cdk synth` emits the synthesized CloudFormation template
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state