At Tines, we concentrate on enabling the primitives of joining together products and services and making those primitives as accessible to anyone as possible. Primitives like receiving data, modifying text, checking for specific conditions, and making HTTP requests are the broad, but powerful capabilities of our available Actions to build Stories with. As with all choices, we are routinely balancing our ethos when deciding between creating tools that optimize for the broadest use cases and strategically choosing which narrowly-focused capabilities to create in the platform, which would be overly burdensome when just left with basic tools. It should be no surprise that the exercise usually leaves you in a vast grey area of options with correct answers being few and far between... even for the smallest of features!
For example, recently we looked to measure the Levenshtein distance between two pieces of data in order to evaluate domains or email senders to enable additional signals when searching for phishing attempts. This is quite possibly the first time you may have even heard of the Levenshtein distance, so no one would probably qualify it as a building block of the internet as it is today. I hope I won't ruin anyone's day conclusively ruling out that the next Action in Tines will not be the Levenshtein distance Action! On the flip side, Levenshtein distance could make for a handy Liquid filter, but it can be computationally intense which could affect Action performance. While we continue to weigh our options, I wanted to highlight how creatively using the tools that do exist can help solve problems like these.
Function-as-a-Service
Quite often 'the cloud' is seen as a farm of full computers doing complex workloads, but one of the most powerful capabilities of providers like AWS is the ability to abstract everything away and provide a spot to run business logic that might only be a few lines of code very cheaply. These few lines of code are generally described as 'functions' that can be accessed at any time and on-demand. One of the pioneers of FaaS is the AWS Lambda service. Lambda excels for its flexibility to perform short and computationally intensive jobs which sounds exactly like our Levenshtein distance problem!
AWS makes Lambda functions available in their REST API via the 'Invoke' capability which Tines can easily work with. Recently, we've seen our customers utilize Lambda services to validate complex signing signatures and perform complex operations with objects stored in AWS S3, referencing or moving them between their Tines enabled services. The possibilities are practically unlimited!
Solving the Levenshtein Problem
Now let's dig into what it takes to create an AWS Lambda function and utilize it from Tines. AWS Lambda functions can be written in many languages. For my purposes, I chose Python which has a library named 'FuzzyWuzzy' that allows for a fuzzy-style evaluation of the similarities between two pieces of data. For example, when measuring the ratio of similarity between "Tines" and "Tones" it would result in 80% similarity because of the single character change.
Here is what the Lambda function could look like:
from fuzzywuzzy import fuzz
def lambda_handler(event, context):
data = {}
data['str1'] = event['str1']
data['str2'] = event['str2']
data['ratio'] = fuzz.ratio(data['str1'], data['str2'])
return data
Very simply, Lambda will receive data as an 'event' with structured JSON, send it through FuzzyWuzzy's ratio function, and return back our result as 'data'. The Lambda functions will then be packaged and uploaded to AWS in order to be run. More information for creating Lambda functions can be found here: https://docs.aws.amazon.com/lambda/latest/dg/python-package.html.
Once created, you can reference the function simply by using the function's name in a Tines Action, like my example 'Levenshtein'.
Pivoting in to Tines, the public template "Invoke AWS Lambda Function" can be pulled on to the Storyboard.
Once on the Storyboard, the Action will require a couple things to be filled out:
AWS Region the function is located in
The function name
An "AWS" credential created in Tines with the ability to use the Lambda service
I'll edit this template and fill in details for our function.
The Tines AWS credential should contain information from an AWS IAM user. It should look similar to the picture below when creating it (but also including the "secret key" of the user).
After filling everything out, including setting the function name in the Action and setting our payload with arguments for 'str1' and 'str2' as needed by the function, let's give it a run and see what we get back:
Awesome, just what we expected! Now let's put this to some actual use. Because I could see myself using this function in a variety of ways, I'm going to activate this workflow as a "Send to Story". This allows me to utilize this Tines Story in many other workflows and return the result back to that Story.
What I want to do now is give the Story an email address that came in as an external sender email address ("e0in@tones.io" in our example) to check for VIP impersonation in order to give an additional signal to analysts that emails sourced from that address could be malicious.
I will also need to populate a list of our VIPs. I can do this using the 'Global Resources' feature of Tines to have a lookup list handy.
Then I will use the 'explode' feature of the Event Transformation Action to iterate over the list of VIPs and check our sender email address for similarity. We can also choose to only report back events that have a similarity over '75'. This is what the results could look like:
Invoke Wrap Up
AWS Lambda is a powerful resource that can be utilized by Tines efficiently. By leveraging the AWS REST API, Lambda functions do not require an API gateway or need to be exposed to the internet ( there are great arguments in favor of going that route also!). Furthermore, in a pinch, AWS Lambda functions can be created to serve as small but powerful APIs for Tines to leverage and empower other solutions.
*Please note we recently updated our terminology. Our "agents" are now known as "Actions," but some visuals might not reflect this.*