AWS Storage Blog

How Liberty Mutual uses AWS Transfer Family to manage financial data

Liberty Mutual is the sixth largest property and casualty insurer in the world based on 2019 gross written premium. We rank 77th on the Fortune 100 list of largest corporations in the US based on 2019 revenue, and as of December 31, 2019 we had $43.2 billion in annual consolidated revenue. As a part of the larger enterprise, our Global Retail Markets (GRM) business unit has $28 billion in net written premium and a workforce of 30,000 employees across 15 countries.

In early 2020, we completed the migration of our applications from physical data centers to AWS and our operations now span six AWS Regions. While we have many cloud-native applications, we found AWS Transfer Family capabilities, specifically AWS Transfer Family for SFTP, a useful and familiar means of integrating with existing and new partners to exchange financial and regulatory data from banks and other sources. Before migrating to the cloud, deploying an SFTP server took weeks or months to create and fully integrate with our core systems prior to sharing with our partners.

Since AWS Transfer Family runs on a managed platform, AWS does most of the heavy lifting. The consumer does not have any EC2 instances to manage or configure. The service works as a platform for consumers to provision their own AWS Transfer Family servers within the guidelines dictated by the platform.

In this blog post, we focus on how we enabled and used AWS Transfer Family through an end-to-end automation process and how it helped our business go live with AWS Transfer Family SFTP servers within minutes to hours. We also discuss how our journey started and transformed through our use of AWS Transfer Family, lessons learned, challenges, and significant benefits of using the service.

How our journey started and transformed with AWS Transfer Family

As part of the migration into the cloud, our workloads require SFTP to exchange financial and regulatory data and to integrate that data with the other core systems. Around the same time that we started our migration (April 2019), AWS released a new service called AWS Transfer for SFTP (later renamed to AWS Transfer Family when FTP and FTPS protocol support was added earlier this year). The AWS Transfer Family service supports Amazon S3 as its backend data store, which ensures high durability and security of our data. In addition, this backend is well integrated with the rest of the AWS ecosystem. When AWS Transfer for SFTP was released, it supported two endpoint types – PUBLIC and VPC_ENDPOINT. When we began exploring which endpoint type was best for us, our goal was to open the SFTP endpoint through the internet through a Network Load Balancer in the public subnet. The downside of this was that a Network Load Balancer does not support security groups.

Earlier this year, AWS developed the VPC endpoint type, not to be confused with VPC_ENDPOINT mentioned in the preceding paragraph. This endpoint type uses an Elastic IP address, which opens the AWS Transfer Family server endpoint URL to the internet. Access is controlled through security groups on the AWS Transfer Family VPC endpoint. When the AWS Transfer Family server is provisioned, AWS creates the VPC endpoint interface and attaches the VPC default security group to it. The default security group can then be replaced with one or more custom security groups to control access.

The following diagram is a depiction of AWS Transfer Family server enablement with endpoint type VPC:

Enabling AWS Transfer Family through a multi-phase model, with service_managed id provider and customer_managed id provider using API Gateway

We enabled AWS Transfer Family through a multi-phase model. In the first phase, we enabled it with the SERVICE_MANAGED identity provider. In the second phase, we are planning to enable the CUSTOM_MANAGED identity provider using API Gateway with Amazon Cognito user pools by federating the identities from Azure AD.

Key features of AWS Transfer Family

  • Available in all AWS Regions
  • Supports custom domain names
  • Supports service-managed users and custom-managed users
  • Open to the internet but incoming traffic is securely protected at the VPC endpoint interface through security groups
  • Amazon S3 is the backend for SFTP – S3 is the most performant cloud object storage
  • AWS Transfer Family can transfer to multiple S3 buckets through a single server
  • The consumer has options to enable S3 Lifecycle policies for data in Amazon S3

Benefits of AWS Transfer Family

  • Zero maintenance and administrative responsibility on consumer
  • Can completely automate the deployment
  • Meets all our global cyber security guidelines
  • Amazon S3 is integrated with AWS services and/or consumer data centers
  • AWS Transfer Family pricing is low when compared with running SFTP in a data center
  • Meets all our disaster recovery (DR) resilience guidelines

Some interesting things we learned in the process

  • SFTP users are not IAM identities (like IAM role or IAM User); they are more like logical objects. These logical objects are associated with a managed IAM policy as a scope down policy and an IAM role to control the user’s access to the S3 bucket.
  • AWS Transfer Family supports scope down policies to restrict the SFTP users to the designated S3 bucket and home directory.
  • AWS recently introduced a “restricted” option that enforces root directory scope where users are not able to see the S3 bucket or home directory names. This feature replaces the need for a scope down policy.
  • ${transfer:HomeFolder} and ${transfer:HomeDirectory} are scope down policy reserved variables. The difference between the two is that HomeFolder includes only the home directory, whereas HomeDirectory includes the bucket name plus the home directory.
  • When the endpoint type is VPC, AWS Transfer Family routes the traffic to the SFTP server through the VPC endpoint interface created using consumer public subnets.
  • There is a 1:1 ratio between the VPC endpoint interface and an AWS Transfer Family server. This is different from Amazon API Gateway and AWS Storage Gateway, where the VPC endpoint interface forwards communications to these services.
  • AWS Transfer Family server computing charges are $0.30 per hour from started state to terminated state. These charges apply even when the AWS Transfer Family server is in a stopped state.

Our solution

In this example, we show how we implemented the AWS Transfer Family solution using the VPC endpoint type with service-managed users. Our solution is composed of Jenkins pipeline jobs to deploy the AWS CloudFormation template and additional jobs with Groovy scripts to manage users in the SFTP server. We use separate AWS CloudFormation templates to deploy the AWS Transfer Family SFTP server, S3 bucket, and the user roles and policies.

Our S3 bucket AWS CloudFormation resource creates an S3 bucket with a lifecycle configuration that moves the documents to lower price modes of storage as the document ages.

SFTPS3Bucket:
  Type: AWS::S3::Bucket
  DeletionPolicy: Retain
  Properties:
    AccessControl: Private
    PublicAccessBlockConfiguration:
      BlockPublicAcls: true
      BlockPublicPolicy: true
      IgnorePublicAcls: true
      RestrictPublicBuckets: true
    BucketEncryption:
      ServerSideEncryptionConfiguration:
      - ServerSideEncryptionByDefault:
          SSEAlgorithm: AES256
    BucketName: !Ref S3BucketName
    LifecycleConfiguration:
      Rules:
        - Status: Enabled
          Id: IA_Rule
          Transitions:
            - StorageClass: STANDARD_IA
              TransitionInDays: 90 
        - Status: Enabled
          Id: Glacier_Rule
          Transitions:
            - StorageClass: GLACIER
              TransitionInDays: 365
        - Status: Enabled
          Id: Deep_archive  
          Transitions:
            - StorageClass: DEEP_ARCHIVE
              TransitionInDays: 720

The next AWS CloudFormation template we deploy is our user role and policy template. This template deploys the scope down policy and the user role with an inline policy. This gives the user access to perform get and put operations on their home directory in the S3 bucket. The Ref’s are string parameters passed into the template. The following are the resources from this template:

Resources:
  UserS3Policy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: !Ref UserS3PolicyName
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: AllowListingOfUserFolder
            Effect: Allow
            Action:
              - s3:ListBucket
              - s3:GetBucketLocation
            Resource:
              - !Sub arn:aws:s3:::${S3BucketName}
          - Sid: HomeDirObjectAccess
            Effect: Allow
            Action:
              - s3:PutObject
              - s3:GetObject
              - s3:DeleteObjectVersion
              - s3:DeleteObject
              - s3:GetObjectVersion
            Resource:
              - !Sub arn:aws:s3:::${S3BucketName}/*
      Roles: 
        - !Ref UserS3Role

  UserScopeDownPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: !Ref ScopeDownPolicyName
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: AllowListingOfUserFolder
            Effect: Allow
            Action:
              - s3:ListBucket
            Resource:
              - arn:aws:s3:::${transfer:HomeBucket}
            Condition:
              StringLike:
                S3:prefix:
                  - ${transfer:HomeFolder}/*
                  - ${transfer:HomeFolder}

          - Sid: HomeDirObjectAccess
            Effect: Allow
            Action:
              - s3:PutObject
              - s3:GetObject
              - s3:DeleteObjectVersion
              - s3:DeleteObject
              - s3:GetObjectVersion
            Resource:
              - arn:aws:s3:::${transfer:HomeDirectory}*

  UserS3Role:
    Type: AWS::IAM::Role    
    Properties:
      Description: Role that will be assigned to users giving them access to an S3 bucket
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service: transfer.amazonaws.com
          Action: sts:AssumeRole
      
      RoleName: !Ref UserS3RoleName

Given the VPC and public subnet IDs, this AWS CloudFormation template creates the Elastic IP address, Amazon CloudWatch logging policy, and AWS Transfer Family SFTP server.

Resources:  
  CloudwatchPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: 'Allow'
            Action:
              - 'logs:CreateLogStream'
              - 'logs:DescribeLogStreams'
              - 'logs:CreateLogGroup'
              - 'logs:PutLogEvents'
            Resource: '*'
      PolicyName: !Ref 'LoggingRolePolicy'
      Roles:
        - Ref: 'SFTPLoggingRole'

  SFTPLoggingRole:
    Type: AWS::IAM::Role    
    Properties:
      Description: Cloudwatch logging role for the SFTP server to assume when logging connection and transfer activity
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: 'Allow'
          Principal:
            Service: 'transfer.amazonaws.com'
          Action: 'sts:AssumeRole'      
      RoleName: !Ref 'LoggingRoleName'           

  ElasticIp:
    Type: AWS::EC2::EIP
    Properties:
      Domain: 'vpc'    

  SFTPServer:
    Type: AWS::Transfer::Server
    Properties:
      EndpointType: 'VPC'
      EndpointDetails:
        VpcId: !Ref 'VPC'
        SubnetIds:
          - !Ref 'PublicSubnet'
        AddressAllocationIds:
          - !GetAtt 'ElasticIp.AllocationId'  
      IdentityProviderType: 'SERVICE_MANAGED'
      LoggingRole:
        !GetAtt 'SFTPLoggingRole.Arn'

When the AWS Transfer Family server is created through this AWS CloudFormation template or through the AWS Management Console, the default security group is automatically attached to the VPC endpoint. Since we use Jenkins as our pipeline tool, we have written a script that we call the Jenkinsfile to replace the default security group with our custom security group. In this custom group, only IP addresses that need access to this server are contained within the CIDR blocks we have specified. We use the AWS Java SDK to achieve this replacement.

Adding users

With the service-managed AWS Transfer Family server created, we look to add users. Since our countries of operation are consumers of this service, they are ultimately responsible for adding users to their own AWS Transfer Family servers. We provided Jenkins pipeline utilities to make it easier to manage users in their servers.

With the service-managed AWS Transfer Family server created, we look to add users. We provided Jenkins popeline utilities to make it easier to manage users.

The util_sftp_add_user script takes a single parameter. This parameter is a text file that provides the Jenkinsfile with the server ID, user name, public key, home directory, role ARN, and restrict directory path. For the purposes of this example, we only discuss a user who is restricted through a scope down policy.

stage('sftp add user') {

  try {
    println("Adding user ${userName} to server ${sftpServer}.")
      def user = sftpAddUser(
                 serverId:"${sftpServer}",
                 userName:"${userName}",
                 publicKey:"${publicKey}",
                 role:"${roleArn}",
                 scopeDownPolicyArn:"${scopeDownPolicyArn}",
                 homeDir:"${homeDirectory}")
      if (user.length() != 0) {
          println("Successfully Added user: ${user} to SFTP server:
                 ${sftpServer}")
      } else {
          error("Failed to create user: ${userName} in SFTP server:
                 ${sftpServer}")
      }
    } catch (Exception e) {
        error("Failed to create user: ${userName} in SFTP server:
      ${sftpServer}")
    }      
 }

The preceding Jenkinsfile code snippet uses a utility library written in Groovy. This groovy script uses the AWS Java SDK to add the user to the AWS Transfer Family server. Part of that script is shown here:

. . .

CreateUserRequest request = new CreateUserRequest()
     .withServerId(serverId)
     .withUserName(userName)
     .withSshPublicKeyBody(publicKey)
     .withRole(role)
     .withHomeDirectory(homeDir)
     .withPolicy(policyArn)               
     .withTags(tags)                                      

CreateUserResult result = client.createUser(request)
return result.getUserName() 

. . .

Conclusion

Stable, secure, and cost-effective solutions are the primary focus in everything that we do at Liberty Mutual. We often achieve these goals by using purpose-built, fully managed, and fully featured services from AWS, like AWS Transfer Family. AWS Transfer Family comes “ready-to-consume,” is easy to deploy, and provides countless advantages from an operational perspective.

The content and opinions in this post are those of the third-party author and AWS is not responsible for the content or accuracy of this post.
Yoga Thirumalasetti

Yoga Thirumalasetti

Yoga Thirumalasetti is a Cloud Solutions Architect for Liberty Mutual. He is part of the Global Tech Enablement team which focuses on – enabling things in the cloud, migrating apps and data from local DCs to cloud, refactoring legacy apps to cloud native (and 12 Factor App Guidelines) patterns, and developing brand new apps using complete cloud native services and solutions. Yoga considers himself a “Voyager of the AWS Ecosystem."

Linda Mosca

Linda Mosca

Linda Mosca is a Cloud Principal Software Engineer for Liberty Mutual. She works on the Global Tech Enablement team defining solutions using AWS services that assist international application teams in managing all aspects of their deployments in the cloud.