Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cdk exec policy linked envs #562

Merged
merged 10 commits into from
Jul 19, 2023
8 changes: 8 additions & 0 deletions backend/dataall/api/Objects/Environment/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@
test_scope='Environment',
)

getCDKExecPolicyPresignedUrl = gql.QueryField(
name='getCDKExecPolicyPresignedUrl',
args=[gql.Argument(name='organizationUri', type=gql.NonNullableType(gql.String))],
type=gql.String,
resolver=get_cdk_exec_policy_template,
test_scope='Environment',
)


getPivotRoleExternalId = gql.QueryField(
name='getPivotRoleExternalId',
Expand Down
44 changes: 44 additions & 0 deletions backend/dataall/api/Objects/Environment/resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,51 @@ def get_pivot_role_template(context: Context, source, organizationUri=None):
)
raise e

def get_cdk_exec_policy_template(context: Context, source, organizationUri=None):
dlpzx marked this conversation as resolved.
Show resolved Hide resolved
from ....utils import Parameter

with context.engine.scoped_session() as session:
ResourcePolicy.check_user_resource_permission(
session=session,
username=context.username,
groups=context.groups,
resource_uri=organizationUri,
permission_name=permissions.GET_ORGANIZATION,
dlpzx marked this conversation as resolved.
Show resolved Hide resolved
)
cdk_exec_policy_bucket = Parameter().get_parameter(
env=os.getenv('envname', 'local'), path='s3/resources_bucket_name'
)
cdk_exec_policy_bucket_key = Parameter().get_parameter(
env=os.getenv('envname', 'local'), path='s3/cdk_exec_policy_prefix'
)
if not cdk_exec_policy_bucket or not cdk_exec_policy_bucket_key:
raise exceptions.AWSResourceNotFound(
action='GET_CDK_EXEC_POLICY_TEMPLATE',
message='CDK Exec Yaml template file could not be found on Amazon S3 bucket',
)
dlpzx marked this conversation as resolved.
Show resolved Hide resolved
try:
s3_client = boto3.client(
's3',
region_name=os.getenv('AWS_REGION', 'eu-central-1'),
dlpzx marked this conversation as resolved.
Show resolved Hide resolved
config=Config(
signature_version='s3v4', s3={'addressing_style': 'virtual'}
),
)
presigned_url = s3_client.generate_presigned_url(
'get_object',
Params=dict(
Bucket=cdk_exec_policy_bucket,
Key=cdk_exec_policy_bucket_key,
),
ExpiresIn=15 * 60,
)
return presigned_url
except ClientError as e:
log.error(
f'Failed to get presigned URL for CDK Exec role template due to: {e}'
)
raise e

def get_external_id(context: Context, source, organizationUri=None):
with context.engine.scoped_session() as session:
ResourcePolicy.check_user_resource_permission(
Expand Down
280 changes: 280 additions & 0 deletions deploy/cdk_exec_policy/cdkExecPolicy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
AWSTemplateFormatVersion: 2010-09-09
dlpzx marked this conversation as resolved.
Show resolved Hide resolved
Description: Custom least privilege IAM policy for linking environments to dataall
Parameters:
AwsAccountId:
Description: AWS AccountId of the account that we wish to link.
Type: String
PolicyName:
Description: IAM policy name (The same name must be used during CDK bootstrapping. Default is DataAllCustomCDKPolicy.)
Type: String
Default: 'DataAllCustomCDKPolicy'
EnvironmentResourcePrefix:
dlpzx marked this conversation as resolved.
Show resolved Hide resolved
Description: The resource prefix value of the dataall environment. It MUST match the resource prefix that we use when we create the environment.
Type: String
Resources:
CDKCustomExecutionPolicy0:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
ManagedPolicyName: !Ref PolicyName
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: KMS
Action:
- 'kms:CreateKey'
Effect: Allow
Resource: '*'
- Sid: ec2
Action:
- 'ec2:DescribeSecurityGroups'
- 'ec2:CreateSecurityGroup'
- 'ec2:createTags'
- 'ec2:DeleteSecurityGroup'
- 'ec2:RevokeSecurityGroupEgress'
- 'ec2:AuthorizeSecurityGroupIngress'
- 'ec2:AuthorizeSecurityGroupEgress'
noah-paige marked this conversation as resolved.
Show resolved Hide resolved
Effect: Allow
Resource: '*'
- Sid: Athena
Effect: Allow
Action: 'athena:CreateWorkGroup'
Resource:
- !Sub 'arn:aws:athena:*:${AWS::AccountId}:workgroup/*'
- Sid: IAM
Action:
- 'iam:CreatePolicy'
- 'iam:GetPolicy'
Effect: Allow
Resource:
- !Sub 'arn:aws:iam::${AWS::AccountId}:policy/*'
- Sid: IAMRole
Action:
- 'iam:AttachRolePolicy'
- 'iam:CreateRole'
- 'iam:CreateServiceLinkedRole'
dlpzx marked this conversation as resolved.
Show resolved Hide resolved
- 'iam:GetRole'
- 'iam:GetRolePolicy'
- 'iam:PutRolePolicy'
- 'iam:TagRole'
- 'iam:UnTagRole'
- 'iam:DeleteRole'
- 'iam:DetachRolePolicy'
- 'iam:DeleteRolePolicy'
- 'iam:PassRole'
- 'iam:UpdateAssumeRolePolicy'
- 'iam:ListPolicyVersions'
- 'iam:DeletePolicy'
- 'iam:ListPolicies'
- 'iam:ListAttachedRolePolicies'
- 'iam:ListGenerateServiceLastAccessedDetails'
- 'iam:ListEntitiesForPolicy'
- 'iam:ListPoliciesGrantingServiceAccess'
- 'iam:ListRoles'
- 'iam:GetServiceLastAccessedDetails'
- 'iam:ListAccountAliases'
- 'iam:ListRolePolicies'
Effect: Allow
noah-paige marked this conversation as resolved.
Show resolved Hide resolved
Resource: '*'
- Sid: IAMQuickSight
Effect: Allow
Action:
- 'iam:CreatePolicyVersion'
- 'iam:DeletePolicyVersion'
Resource:
- !Sub 'arn:aws:iam::${AWS::AccountId}:policy/service-role/AWSQuickSight*'
- Sid: QuickSight
Effect: Allow
Action:
- 'ds:AuthorizeApplication'
- 'ds:UnauthorizeApplication'
- 'ds:CheckAlias'
- 'ds:CreateAlias'
- 'ds:DescribeDirectories'
- 'ds:DescribeTrusts'
- 'ds:DeleteDirectory'
- 'ds:CreateIdentityPoolDirectory'
- 'quicksight:CreateAdmin'
- 'quicksight:CreateUser'
- 'quicksight:Subscribe'
- 'quicksight:GetGroupMapping'
- 'quicksight:SearchDirectoryGroups'
- 'quicksight:SetGroupMapping'
- 'quicksight:RegisterUser'
- 'quicksight:GetDashboardEmbedUrl'
- 'quicksight:DescribeDashboardPermissions'
Resource: '*'
- Sid: QuickSightDeny
Effect: Deny
Action:
- 'quicksight:Unsubscribe'
Resource: '*'
- Sid: KMSCreateAlias
Action:
- 'kms:CreateAlias'
Effect: Allow
Resource:
- !Sub 'arn:aws:kms:*:${AWS::AccountId}:alias/*'
- Sid: KMSKey
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this statement, what is it for?

Action:
- 's3:PutBucketAcl'
- 's3:PutBucketNotification'
Effect: Allow
Resource:
- !Sub 'arn:aws:s3:::${EnvironmentResourcePrefix}-logging-*'
- Sid: ReadBuckets
Action:
- 'kms:CreateAlias'
- 'kms:CreateGrant'
- 'kms:Decrypt'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need Encrypt/Decrypt permissions for this role. It is a role to create resources right?

- 'kms:DescribeKey'
- 'kms:EnableKeyRotation'
- 'kms:Encrypt'
- 'kms:GetKeyPolicy'
- 'kms:GetKeyRotationStatus'
- 'kms:ListResourceTags'
- 'kms:PutKeyPolicy'
- 'kms:TagResource'
Effect: Allow
Resource: !Sub 'arn:aws:kms:*:${AWS::AccountId}:key/*'
- Sid: Lambda
Action:
- 'lambda:AddPermission'
- 'lambda:CreateFunction'
- 'lambda:GetFunction'
- 'lambda:GetFunctionCodeSigningConfig'
- 'lambda:GetRuntimeManagementConfig'
- 'lambda:PutFunctionEventInvokeConfig'
- 'lambda:InvokeFunction'
- 'lambda:RemovePermission'
Effect: Allow
Resource: '*'
- Sid: LambdaPublishLayer
Effect: Allow
Action:
- 'lambda:PublishLayerVersion'
Resource:
- !Sub 'arn:aws:lambda:*:${AWS::AccountId}:layer:*'
- Sid: S3
Action:
- 's3:CreateBucket'
- 's3:GetBucketPolicy'
- 's3:PutBucketCORS'
- 's3:PutBucketLogging'
- 's3:PutBucketPolicy'
- 's3:PutBucketPublicAccessBlock'
- 's3:PutBucketTagging'
- 's3:PutBucketVersioning'
- 's3:PutEncryptionConfiguration'
- 's3:PutLifecycleConfiguration'
- 's3:DeleteBucketPolicy'
- 's3:DeleteBucket'
Effect: Allow
Resource: 'arn:aws:s3:::*'
- Sid: SQS
Effect: Allow
Action:
- 'sqs:CreateQueue'
- 'sqs:SetQueueAttributes'
Resource: !Sub 'arn:aws:sqs:*:${AWS::AccountId}:*'
- Sid: SSM
Effect: Allow
Action:
- 'ssm:GetParameters'
- 'ssm:PutParameter'
Resource: '*'
- Sid: Logs
Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
- 'logs:DescribeLogStreams'
Resource: 'arn:aws:logs:*:*:*'
- Sid: STS
Effect: Allow
Action:
- 'sts:AssumeRole'
- 'iam:*Role*'
Resource: !Sub 'arn:aws:iam::${AWS::AccountId}:role/cdk-*'
- Sid: CloudFormation
Effect: Allow
Action:
- 'cloudformation:*'
Resource: !Sub 'arn:aws:cloudformation:*:${AWS::AccountId}:stack/CDKToolkit/*'
- Sid: ECR
Effect: Allow
Action:
- 'ecr:SetRepositoryPolicy'
- 'ecr:GetLifecyclePolicy'
- 'ecr:PutImageScanningConfiguration'
- 'ecr:DescribeRepositories'
- 'ecr:CreateRepository'
- 'ecr:DeleteRepository'
Resource: !Sub 'arn:aws:ecr:*:${AWS::AccountId}:repository/cdk-*'
- Sid: SSMTwo
Effect: Allow
Action:
- 'ssm:GetParameter'
- 'ssm:PutParameter'
- 'ssm:DeleteParameter'
Resource: !Sub 'arn:aws:ssm:*:${AWS::AccountId}:parameter/cdk-bootstrap/*'
- Sid: CloudformationTwo
Effect: Allow
Action:
- '*'
Resource: '*'
Condition:
'ForAnyValue:StringEquals':
'aws:CalledVia': 'cloudformation.amazonaws.com'
- Sid: S3Staging
Effect: Allow
Action:
- 's3:*'
Resource:
- !Sub 'arn:aws:s3:::cdktoolkit-stagingbucket-*'
- Sid: Pipelines
Effect: Allow
Action:
- 'codepipeline:TagResource'
- 'codepipeline:UntagResource'
- 'codepipeline:CreatePipeline'
- 'codepipeline:UpdatePipeline'
- 'codepipeline:StartPipelineExecution'
- 'codepipeline:GetPipeline'
- 'codepipeline:GetPipelineState'
- 'codepipeline:GetPipelineExecution'
- 'codepipeline:ListPipelineExecutions'
- 'codepipeline:ListActionExecutions'
- 'codepipeline:ListActionTypes'
- 'codepipeline:ListPipelines'
- 'codepipeline:ListTagsForResource'
- 'codepipeline:DeletePipeline'
- 'codestar-notifications:ListNotificationRules'
- 'codestar-notifications:ListEventTypes'
- 'codestar-notifications:ListTargets'
Resource: '*'
- Sid: PipelinesS3
Effect: Allow
Action:
- 's3:GetObject'
- 's3:ListBucket'
- 's3:GetBucketPolicy'
Resource:
- 'arn:aws:s3::*:codepipeline-*'
- Sid: CodeStarNotificationsReadOnly
Effect: Allow
Action:
- 'codestar-notifications:DescribeNotificationRule'
Resource: '*'
Condition:
'StringLike':
'codestar-notifications:NotificationsForResource': 'arn:aws:codepipeline:*'
- Sid: Eventrules
Effect: Allow
Action:
- 'events:PutRule'
- 'events:DescribeRule'
- 'events:PutTargets'
- 'events:RemoveTargets'
- 'events:DeleteRule'
Resource: '*'
19 changes: 19 additions & 0 deletions deploy/stacks/s3_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ def __init__(self, scope, id, envname='dev', resource_prefix='dataall', **kwargs
os.path.abspath(os.path.join(__file__, '..', '..', 'pivot_role'))
)

cdk_exec_policy = os.path.realpath(
os.path.abspath(os.path.join(__file__, '..', '..', 'cdk_exec_policy'))
)

s3d.BucketDeployment(
self,
f'PivotRoleDeployment{envname}',
Expand All @@ -70,6 +74,21 @@ def __init__(self, scope, id, envname='dev', resource_prefix='dataall', **kwargs
string_value='roles/pivotRole.yaml',
)

s3d.BucketDeployment(
self,
f'CDKExecutionPolicyDeployment{envname}',
sources=[s3d.Source.asset(cdk_exec_policy)],
destination_bucket=self.bucket,
destination_key_prefix='policies',
)

ssm.StringParameter(
self,
f'S3ResourcesBucketKeyParam{envname}',
parameter_name=f'/dataall/{envname}/s3/cdk_exec_policy_prefix',
string_value='policies/cdkExecPolicy.yaml',
)

CfnOutput(
self,
f'{resource_prefix}-{envname}-resources-bucket-output',
Expand Down
14 changes: 14 additions & 0 deletions frontend/src/api/Environment/getCDKExecPolicyPresignedUrl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { gql } from 'apollo-boost';

const getCDKExecPolicyPresignedUrl = (organizationUri) => ({
variables: {
organizationUri
},
query: gql`
query getCDKExecPolicyPresignedUrl($organizationUri: String!) {
getCDKExecPolicyPresignedUrl(organizationUri: $organizationUri)
}
`
});

export default getCDKExecPolicyPresignedUrl;
Loading