Skip to content

Commit

Permalink
Cloudformation direct access key (#2123)
Browse files Browse the repository at this point in the history
  • Loading branch information
moukoublen authored Apr 16, 2024
1 parent 8f30981 commit 72baecd
Show file tree
Hide file tree
Showing 5 changed files with 283 additions and 1 deletion.
67 changes: 67 additions & 0 deletions .github/workflows/cloudformation-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ on:
paths:
- deploy/cloudformation/*.yml
- .github/workflows/cloudformation-ci.yml
push:
branches:
- main
- "[0-9]+.[0-9]+"
paths:
- deploy/cloudformation/*.yml
- .github/workflows/cloudformation-ci.yml

env:
WORKING_DIR: deploy/test-environments
Expand Down Expand Up @@ -115,3 +122,63 @@ jobs:
terraform destroy --auto-approve -target="module.ec_deployment" -target="module.ec_project"
aws cloudformation delete-stack --stack-name ${{ env.CNVM_STACK_NAME }}
aws cloudformation wait stack-delete-complete --stack-name ${{ env.CNVM_STACK_NAME }}
Deploy-CloudFormation-DirectKeys:
name: "Deploy CloudFormation DirectKeys"
runs-on: ubuntu-latest
timeout-minutes: 40
steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Hermit Environment
uses: ./.github/actions/hermit
with:
init-tools: 'true'

- name: Set up unique deployment names
run: |
suffix="$(date +%s | tail -c 3)"
echo "DIRECT_KEY_STACK_NAME=direct-key-stack-pr${{ github.event.number }}-$suffix" >> $GITHUB_ENV
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_TEST_ACC }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_TEST_ACC }}
aws-region: "eu-west-1"

- name: Deploy CloudFormation stack
env:
CF_FILE: 'deploy/cloudformation/elastic-agent-direct-access-key-cspm.yml'
run: |
aws cloudformation validate-template --template-body file://${{ env.CF_FILE }}
aws cloudformation create-stack --stack-name ${{ env.DIRECT_KEY_STACK_NAME }} --template-body file://${{ env.CF_FILE }} --capabilities CAPABILITY_NAMED_IAM
aws cloudformation wait stack-create-complete --stack-name ${{ env.DIRECT_KEY_STACK_NAME }}
- name: Get Direct Keys
id: direct-keys
shell: bash
run: |
BODY="$(aws cloudformation describe-stacks --stack-name ${{ env.DIRECT_KEY_STACK_NAME }} --query 'Stacks[0].Outputs' --output json)"
NEW_ACCESS_KEY_ID="$(echo "${BODY}" | jq -r '.[] | select(.OutputKey | test("AccessKeyId")) | .OutputValue')"
echo "::add-mask::$NEW_ACCESS_KEY_ID"
NEW_SECRET_ACCESS_KEY="$(echo "${BODY}" | jq -r '.[] | select(.OutputKey | test("SecretAccessKey")) | .OutputValue')"
echo "::add-mask::$NEW_SECRET_ACCESS_KEY"
echo "NEW_ACCESS_KEY_ID=${NEW_ACCESS_KEY_ID}" >> $GITHUB_OUTPUT
echo "NEW_SECRET_ACCESS_KEY=${NEW_SECRET_ACCESS_KEY}" >> $GITHUB_OUTPUT
- name: Run AWS integration tests
uses: ./.github/actions/aws-ci
with:
elk-version: ${{ env.ELK_VERSION }}
aws-access-key-id: ${{ steps.direct-keys.outputs.NEW_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ steps.direct-keys.outputs.NEW_SECRET_ACCESS_KEY }}
aws-account-type: single-account

- name: Cleanup Environment
if: always()
run: |
aws cloudformation delete-stack --stack-name ${{ env.DIRECT_KEY_STACK_NAME }}
aws cloudformation wait stack-delete-complete --stack-name ${{ env.DIRECT_KEY_STACK_NAME }}
2 changes: 1 addition & 1 deletion deploy/aws/cloudbeat-aws.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cloudbeat:
credentials:
access_key_id: ${AWS_ACCESS_KEY_ID:""}
secret_access_key: ${AWS_SECRET_ACCESS_KEY:""}
account_type: ${AWS_ACCOUNT_TYPE:""}
account_type: ${AWS_ACCOUNT_TYPE:""}
type: cloudbeat/cis_aws
# Defines how often an event is sent to the output
period: 30s
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
AWSTemplateFormatVersion: "2010-09-09"

Description: Creates elastic-agent cspm user, role, and access key, and outputs the access key

Parameters:
OrganizationalUnitIds:
Description: |
Comma-separated list of organizational units to deploy the IAM roles to.
Specify the unique IDs of the organizational units where the roles should be deployed.
Example: ou-abc123,ou-def456,ou-ghi789
Type: CommaDelimitedList
AllowedPattern: ^(ou-[0-9a-z]{4,32}-[a-z0-9]{8,32}|r-[0-9a-z]{4,32})$

ScanManagementAccount:
Description: |
When set to "Yes", the Management Account resources will be scanned,
regardless of selected Organizational Unit IDs. Likewise, when set to
"No", the Management Account resources will not be scanned, even if
the Management Account belongs to a selected Organizational Unit.
Type: String
AllowedValues:
- "Yes"
- "No"
Default: "Yes"
ConstraintDescription: Must specify "Yes" or "No"

Conditions:
ScanManagementAccountEnabled: !Equals
- !Ref ScanManagementAccount
- "Yes"

Resources:
ElasticCSPMUser:
Type: AWS::IAM::User
Properties:
UserName: !Join
- '-'
- - elasticagent-user-cspm
- !Select
- 2
- !Split
- /
- !Ref AWS::StackId
Path: /

CloudbeatRootRole:
Type: AWS::IAM::Role
Properties:
RoleName: cloudbeat-root
Description: Role that cloudbeat uses to assume roles in other accounts
Tags:
- Key: cloudbeat_scan_management_account
Value: !Ref ScanManagementAccount
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
AWS: !Ref AWS::AccountId
Action:
- sts:AssumeRole
- Effect: Allow
Principal:
AWS: !GetAtt ElasticCSPMUser.Arn
Action:
- sts:AssumeRole
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: cloudbeat-root-permissions
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- iam:GetRole
- iam:ListAccountAliases
- iam:ListGroup
- iam:ListRoles
- iam:ListUsers
Resource: '*'
- Effect: Allow
Action:
- organizations:List*
- organizations:Describe*
Resource: '*'
- Effect: Allow
Action:
- sts:AssumeRole
Resource: '*'

CloudbeatRoleStackSet:
Type: AWS::CloudFormation::StackSet
Properties:
StackSetName: cloudbeat-role-stackset
Description: StackSet for deploying the cloudbeat-securityaudit IAM role to member accounts in the specified organizational units.
AutoDeployment:
Enabled: true
RetainStacksOnAccountRemoval: false
Capabilities:
- CAPABILITY_NAMED_IAM
ManagedExecution:
Active: true
Parameters:
- ParameterKey: RootRoleArn
ParameterValue: !GetAtt CloudbeatRootRole.Arn
PermissionModel: SERVICE_MANAGED
StackInstancesGroup:
- DeploymentTargets:
OrganizationalUnitIds: !Ref OrganizationalUnitIds
Regions:
- !Ref AWS::Region
TemplateBody: |
AWSTemplateFormatVersion: '2010-09-09'
Description: Creates IAM roles needed for multi-account access
Parameters:
RootRoleArn:
Type: String
Resources:
CloudbeatMemberRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: cloudbeat-securityaudit
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Ref RootRoleArn
Action:
- sts:AssumeRole
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/SecurityAudit
CloudbeatManagementAccountAuditRole:
Type: AWS::IAM::Role
Properties:
RoleName: cloudbeat-securityaudit
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
AWS: !GetAtt CloudbeatRootRole.Arn
Action:
- sts:AssumeRole
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/SecurityAudit
Condition: ScanManagementAccountEnabled

ElasticCSPMAccessKey:
Type: AWS::IAM::AccessKey
Properties:
UserName: !Ref ElasticCSPMUser

Outputs:
AccessKeyId:
Description: Access Key ID
Value: !Ref ElasticCSPMAccessKey
Export:
Name: AccessKeyId

SecretAccessKey:
Description: Secret Access Key
Value: !GetAtt ElasticCSPMAccessKey.SecretAccessKey
Export:
Name: SecretAccessKey
39 changes: 39 additions & 0 deletions deploy/cloudformation/elastic-agent-direct-access-key-cspm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
AWSTemplateFormatVersion: "2010-09-09"

Description: Creates elastic-agent cspm user, role, and access key, and outputs the access key

Parameters: {}

Resources:
ElasticCSPMUser:
Type: AWS::IAM::User
Properties:
UserName: !Join
- '-'
- - elasticagent-user-cspm
- !Select
- 2
- !Split
- /
- !Ref AWS::StackId
ManagedPolicyArns:
- arn:aws:iam::aws:policy/SecurityAudit
Path: /

ElasticCSPMAccessKey:
Type: AWS::IAM::AccessKey
Properties:
UserName: !Ref ElasticCSPMUser

Outputs:
AccessKeyId:
Description: Access Key ID
Value: !Ref ElasticCSPMAccessKey
Export:
Name: AccessKeyId

SecretAccessKey:
Description: Secret Access Key
Value: !GetAtt ElasticCSPMAccessKey.SecretAccessKey
Export:
Name: SecretAccessKey
2 changes: 2 additions & 0 deletions scripts/publish_cft.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ version=$(grep defaultBeatVersion version/version.go | cut -f2 -d "\"")
upload_file deploy/cloudformation/elastic-agent-ec2-cnvm.yml "cloudformation-cnvm" "$version"
upload_file deploy/cloudformation/elastic-agent-ec2-cspm.yml "cloudformation-cspm-single-account" "$version"
upload_file deploy/cloudformation/elastic-agent-ec2-cspm-organization.yml "cloudformation-cspm-organization-account" "$version"
upload_file deploy/cloudformation/elastic-agent-direct-access-key-cspm.yml "cloudformation-cspm-direct-access-key-single-account" "$version"
upload_file deploy/cloudformation/elastic-agent-direct-access-key-cspm-organization.yml "cloudformation-cspm-direct-access-key-organization-account" "$version"

0 comments on commit 72baecd

Please sign in to comment.