This is the companion repo to this blog post.
The CDK stack creates a Dynamo Table with a table resource policy that denies reading the items unless the principal arn matches the leading key on the table. The table has the following schema:
| Partition Key (principal) | Sort Key (name) | Value (value) |
|---|---|---|
| arn:aws:iam::111111111111:role/github-webhook-processor-lambda-role | githubAppSecret | ghsecret-value |
| arn:aws:iam::111111111111:role/slack-bot-lambda-role | webhookUrl | https://hooks.slack.com/services/... |
| arn:aws:iam::111111111111:role/slack-bot-lambda-role | slackWebhookSecret | slackSecret |
This means, only the lambda with function-name-1 can read secret-name-1 under the principal arn:aws:iam::111111111111:role/function-name-1-lambda-role. Only the lambda with function-name-2 can read secret-name-1 and secret-name-2 under the principal arn:aws:iam::111111111111:role/function-name-2-lambda-role.
The lambda function attempts to read the secret from the table and returns a json object indicating whether the secret was successfully read or not.
For convenience the stack emits a function url to easily test the lambda function from your browser.
npm install
npx cdk bootstrap # Only if you've never used the CDK before
npx cdk deploy
Log into the console to the same account you deployed the stack with a principal that has permissions to write to dynamodb. Navigate to the console url listed under DirtySecretsStack.DDBCreateItemUrl in the stack outputs.
- Set
partitionto the value found in stack outputs called:DirtySecretsStack.FunctionPrincipal. - Set
nametosecret. - Click the 'Add new attribute' dropdown. Click
Stringand set the attribute name tovalueand set the value to any string you want. - Finally click the
Create itembutton on the bottom right.
Now your table will have a secret only readable by the lambda function.
Using the console, try and read any of the contents of the table using scan or query. All attempts will fail. You can also try to read it using the CLI. In the stack outputs, there is a sample command to call GetItem on your table called DirtySecretsStack.CLIGetItemCommand. Run it in your terminal to see that it gets denied.
Navigate to the url listed under DirtySecretsStack.FunctionUrl in the stack outputs. It should respond with true and a status code of 200.
npx cdk destroy
npx cdk deploydeploy this stack to your default AWS account/regionnpx cdk diffcompare deployed stack with current statenpx cdk synthemits the synthesized CloudFormation template