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

Email Integration #5

Open
InasK6 opened this issue Nov 14, 2024 · 1 comment
Open

Email Integration #5

InasK6 opened this issue Nov 14, 2024 · 1 comment

Comments

@InasK6
Copy link
Contributor

InasK6 commented Nov 14, 2024

Option 1: Emails through SNS and Amazon DataZone
The architecture illustrates one SNS topic per DataZone project, which enables a group of members to collaborate on various business use cases. To find out more about the concept of projects inside DataZone use thislink. The user must be subscribed to the SNS topic in order to be notified. This will allow the subscribed email to receive a notification when something is published to the related topic. The goal of having one SNS Topic per DataZone project is to respect the least privilege principle in terms of security and allow segregation in the emails that can be subscribed to receive information on the subscriptions data in a specific DataZone project. Another approach could involve establishing email groups for each project, incorporating the data owners' email addresses associated with the project's data. Then, configure SNS subscriptions for the corresponding SNS topic using these email groups. When the data owners receives the email notification containing the link to the incoming subscription requests in the Amazon DataZone portal, they can access it to accept or reject the subscription. Amazon DataZone by definition enforces that only members of a DataZone project have the authority to accept or decline subscriptions requested for data assets within that project.
Limitiation: Need to manage the synchronization between members of a project and members of the mailing list. This solution was implemented in the context of datazone project membership done through IAM roles
dz-email-integration (1)

Handler class

import logging

import boto3

from data_zone_subscription import DataZoneSubscription

logger = logging.getLogger()
logger.setLevel(logging.INFO)


class EmailWorkflow:
    '''A workflow that just sends SNS notifications instead of creating an issue.'''
    def __init__(self, stage_name) -> None:
        self.stage_name = stage_name

    def create_issue(self, dz_subscription: DataZoneSubscription, assignee) -> dict:
        """Sent an email after a subscription request is created in DataZone

        Args:
            event (dict): an object with info about the lambda event that triggered this function

        Returns:
            str: a message to be sent in the email to the subscribers of the SNS topic
                with all the information about the subscription request and the requested data.
        """


        message = (
            f"DataZone Subscription for data {dz_subscription.table_catalog_name} from project {dz_subscription.owner_project_name} requested by project {dz_subscription.project_name} on domain Id: {dz_subscription.domain_id}\n"
            + "\n"
        )
        request_info = (
            "\n"
            + "\n"
            + "With request information :\n"
            + f"Request Id: {dz_subscription.subscription_req_id}\n"
            + f"Requester Type: {dz_subscription.requester_type}\n"
            + f"Project subscriber: {dz_subscription.project_name}\n"
            + f"Request Date: {dz_subscription.request_date}\n"
            + f"Request Reason: {dz_subscription.request_reason}"
        )
        message = message + request_info
        requested_data = (
            "\n"
            + "\n"
            + "Details about requested data:\n"
            + f"Target Data Type: {dz_subscription.data_type}\n"
            + f"Data Technical Name: {dz_subscription.table_tech_name}\n"
            + f"Data Table Arn: {dz_subscription.table_arn}\n"
            + f"Data Database Name: {dz_subscription.db_name}\n"
            + f"Data Project Name: {dz_subscription.owner_project_name}"
        )
        message = message + requested_data

        session = boto3.session.Session()
        region = session.region_name
        account = session.client('sts').get_caller_identity()['Account']
        
        link = f"https://{dz_subscription.domain_id}.DataZone.{region}.on.aws/projects/{dz_subscription.data_owner_project}/data/publishedData/incomingRequests"
        message = message + "\n \n Accept or Reject the subscription request at: \n" + link

        sns_client = boto3.client("sns")
        
        # dz-subscription-sns-topic-${project.role}_${project.useCase}-${props.stageName}
        sns_topic = f'arn:aws:sns:{region}:{account}:dz-subscription-sns-topic-{dz_subscription.owner_project_name}-{self.stage_name}'

        response = sns_client.publish(TopicArn=sns_topic, Message=message)

        logger.info(f"Email Workflow: sent SNS notification to topic with email details {sns_topic}")
            
        return response 

CDK class

import {
  aws_sns,
} from 'aws-cdk-lib';
import * as cdk from 'aws-cdk-lib';
import * as kms from 'aws-cdk-lib/aws-kms';
import * as sns from 'aws-cdk-lib/aws-sns';
import { Construct } from 'constructs';
import { subscriptionConfig } from '../config/SubscriptionConfig';
import { IDataZoneProject } from '../config/Types';

interface Props extends cdk.StackProps {
  applicationName: string;
  encryptionKey: kms.Key;
  DZ_PROJECTS: IDataZoneProject[];
}

export class DataZoneSubscriptionEmailStack extends cdk.Stack {
  public readonly snsTopic: aws_sns.Topic[] = [] ;
  constructor(scope: Construct, id: string, props: Props) {
    super(scope, id, props);
    /*****
      1. Target SNS topic for publishing subscription details, subscribers can receive email notifications
    ******/
    // Amazon SNS provides in-transit encryption by default

    const allowedEmailDomains = subscriptionConfig().EMAIL_DOMAINS;

    for (let project of props.DZ_PROJECTS) {
      const topic = new sns.Topic(this, `DzSubscriptionTopic-${project.name}`, {
        topicName: `dz-subscription-sns-topic-${project.name}`,
        displayName: `DataZone Subscription SNS Topic for ${project.name}`,
        masterKey: props.encryptionKey,
      });

      // Removal policies control what happens to stack resources when the CDK app's stack is deleted
      topic.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);

      // Add permissions to subscribe for all roles in current account
      topic.addToResourcePolicy(
        new cdk.aws_iam.PolicyStatement({
          effect: cdk.aws_iam.Effect.ALLOW,
          principals: [
            new cdk.aws_iam.AccountPrincipal(this.account),
          ],
          actions: ['sns:Subscribe'],
          resources: [topic.topicArn],
        }),
      );

      topic.addToResourcePolicy(
        new cdk.aws_iam.PolicyStatement({
          effect: cdk.aws_iam.Effect.DENY,
          principals: [
            new cdk.aws_iam.AccountPrincipal(this.account),
          ],
          actions: ['sns:Subscribe'],
          resources: [topic.topicArn],
          conditions: {
            StringNotEquals: {
              'sns:Protocol': 'email',
            },
          },
        }),
      );

      topic.addToResourcePolicy(
        new cdk.aws_iam.PolicyStatement({
          effect: cdk.aws_iam.Effect.DENY,
          principals: [
            new cdk.aws_iam.AccountPrincipal(this.account),
          ],
          actions: ['sns:Subscribe'],
          resources: [topic.topicArn],
          conditions: {
            StringNotLike: {
              'SNS:Endpoint': allowedEmailDomains,
            },
          },
        }),
      );

      this.snsTopic.push(topic);

    }

  }

}


Option 2: Emails through AWS IAM Identity Center, Amazon SES and Amazon DataZone
Limitation: IAM Identity Center might be present in an AWS account different from the one of Amazon DataZone domain
Screenshot 2024-08-13 at 15 09 13
Option 3: Emails to members of a project
Similar to previous architecture but without going through IAM Identity center. One can get the emails of the SSO users member of a project using get user DataZone API call
Limitation: can't get emails of SSO groups

@naveen1487
Copy link

Can you give give the difference between option 2 and option 2 more information . please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants