This is an AWS SAM template for an Automated policy orchestrator - Below is an explanation of how to deploy the template and build the Step Function state machine:
.
├── README.MD <-- This instructions file
├── src
│ └── askUser <-- Source code for askUser lambda function
│ └── PolicyChangeApprove <-- Source code for PolicyChangeApprove lambda function
│ └── RecieveUserAPI <-- Source code for RecieveUserAPI lambda function
│ └── RevertPolicy <-- Source code for RevertPolicy lambda function
│ └── ValidatePolicy <-- Source code for ValidatePolicy lambda function
├── template.yaml <-- SAM template
├── package.json <-- SAM package
├── padpolicy.json <-- Example policy document
- AWS CLI already configured with Administrator permission
- AWS SAM CLI installed - minimum version 0.48.
Follow the instructions below in order to deploy from this repository:
-
Create an AWS account if you do not already have one and login.
-
Clone the repo onto your local development machine:
git clone https://github.com/aws-samples/automating-a-security-incident-with-step-functions.git
- In the root directory, from the command line, run:
sam deploy --guided
Follow the prompts in the deploy process to set the applicaiton, email address and restrictedActions:
- Application name: an identifiable name for the application.
- EmailAddress: an administrator’s email address for receiving approval requests.
- restrictedActions: The IAM Policy actions you want to restrict.
Navigate to the Step Functions console and click on edit.
All states will be defined insite States{}
object:
{
"Comment": "Defect detection state machine",
"StartAt": "ModifyState",
"States": {
}
}
Re-structures the input data into a more usable format:
"ModifyState": {
"Type": "Pass",
"Parameters": {
"policy.$": "$.detail.requestParameters.policyDocument",
"accountId.$": "$.detail.userIdentity.accountId",
"region.$": "$.region",
"policyMeta.$":"$.detail.responseElements.policy"
},
"ResultPath": "$",
"Next": "ValidatePolicy"
},
Invokes the ValidatePolicy Lambda that checks the new policy document against the restricted actions:
"ValidatePolicy": {
"Type": "Task",
"ResultPath":"$.taskresult",
"Resource": "{Replace-This-With-ValidatePolicy-Arn}",
"Next": "ChooseAction"
},
Creates a new default version of the policy with only Log permissions and deletes previously created policy version:
"TempRemove": {
"Type": "Task",
"ResultPath":"$.taskresult",
"Resource": "{Replace-This-With-{RevertPolicy-Arn}",
"Next": "AskUser"
},
Choice state, branches depending on input from ValidatePolicy step:
"ChooseAction": {
"Type" : "Choice",
"Choices": [
{
"Variable": "$.taskresult.action",
"StringEquals": "remedy",
"Next": "TempRemove"
},
{
"Variable": "$.taskresult.action",
"StringEquals": "alert",
"Next": "AllowWithNotification"
}
],
"Default": "AllowWithNotification"
},
No restricted actions detected, user is still notified of change (via SNS email) then executions ends:
"AllowWithNotification": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Parameters": {
"TopicArn": "{Replace-This-With-{AlertTopic-Arn}",
"Subject": "Policy change detected!",
"Message.$": "$.taskresult.message"
},
"End": true
},
Restricted action detected, send approval email to user via SNS, with taskToken that initiates the callback pattern:
"AskUser":{
"Type": "Task",
"Resource":"arn:aws:states:::lambda:invoke.waitForTaskToken",
"Parameters":{
"FunctionName":"askUser",
"Payload":{
"token.$":"$$.Task.Token"
}
},
"ResultPath":"$.taskresult",
"Next": "usersChoice"
},
Branch based on user's approval/deny action:
"usersChoice": {
"Type" : "Choice",
"Choices": [
{
"Variable": "$.taskresult.action",
"StringEquals": "delete",
"Next": "denied"
},
{
"Variable": "$.taskresult.action",
"StringEquals": "allow",
"Next": "approved"
}
],
"Default": "denied"
},
User denied policy creation, end execution with no further action:
"denied": {
"Type": "Pass",
"End":true
},
Restore initial policy document by creating as a new version:
"approved": {
"Type": "Task",
"Resource": "{Replace-This-With-{PolicyChangerApproveARN}",
"TimeoutSeconds": 3600,
"End": true
}
Use the AWS CLI to create a new policy. An example policy document has been included in this repository named badpolicy.json
.
aws iam create-policy --policy-name my-bad-policy --policy-document file://badpolicy.json
In order to delete our Serverless Application recently deployed you can use the following AWS CLI Command:
aws cloudformation delete-stack --stack-name sam-app
Here are a few things you can try to get more acquainted with building serverless applications using SAM:
- Uncomment state machine definition
template.js
- Enable step-through debugging docs for supported runtimes
Next, you can use AWS Serverless Application Repository to deploy ready to use Apps that go beyond hello world samples and learn how authors developed their applications: AWS Serverless Application Repository main page
All commands used throughout this document
# create a bucket
aws s3 mb s3://BUCKET_NAME
# Build and package application
sam build && sam package \
--output-template-file package.yaml \
--s3-bucket BUCKET_NAME
Next, the following command will create a Cloudformation Stack and deploy your SAM resources.
# Deploy SAM application
sam deploy \
--template-file package.yaml \
--stack-name sam-app \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides EmailAddress={YOUR-EMAIL-ADDRESS}
# Creating a new Policy
aws iam create-policy --policy-name my-bad-policy --policy-document file://badpolicy.json