Extensible Platform

Use our SDK to support the full breadth of your platform

We know that your organization has special business rules and integrations that only make sense to you… because every organization does. Sym supports dynamic access and approval flows for the full breadth of your platform with our extensible, SDK-driven approach.

Our out of the box integrations (such as Slack, AWS, Okta, and PagerDuty) make it easy to provision just-in-time access flows for common production scenarios. You can generate one of these flows in minutes, and have users piloting the new process in hours.

📘

Learn more about getting started here!

Once you have your first flow configured, you can dive deeper into our SDK to support the parts of your business that don’t fit into cookie-cutter strategies. Your implementers get a consistent approach to define workflows regardless of the target systems and resources.

AWS Lambda Integration

With our AWS Lambda Integration, Sym takes care of the undifferentiated heavy lifting of managing a Slack app, administering users, defining access rules and routing logic, auditing, and more. You get to focus on “last mile” Lambda Functions that manage services in your VPC or 3rd Party Services that Sym doesn’t support out of the box.

Sym’s Lambda integration has a strong security posture. You don’t need to poke holes in your firewall for Sym to integrate with internal systems. Instead, you grant Sym the permissions to invoke specific Lambda functions that you host. Sym interfaces with the AWS APIs to invoke these functions, supplying a JSON payload with request context.

Your last-mile Lambda implementation might start off with something like this:

def lambda_handler(event, context):
    # The full structure of the Payload sent is described in the Sym Docs:
    # https://docs.symops.com/docs/aws-lambda#payload
    print(event)

    event_type = event["event"]["type"]
    requester = event["run"]["actors"]["request"]["username"]

    # This Lambda is invoked for both escalate and de-escalate, so we must branch logic based on the event type.
    if event_type == "escalate":
        return grant_access(requester)
    elif event_type == "deescalate":
        return remove_access(requester)


def grant_access(requester):
    if is_human(requester):
        # ... some custom escalate logic ...

        # The AWS Lambda Strategy enforces a specific response body format.
        # It must contain two top-level keys `body` and `errors`
        return {
            # A JSON-object containing whatever values you wish to pass back to your `impl.py`.
            # These values can be retrieved with `get_step_output("escalate")` and `get_step_output("deescalate")`
            "body": {
                "message": (
                    "You've been granted access to the super secret Aperture Science Heavy Duty Super-Colliding Super Button! "
                    "Access it here: https://www.valvearchive.com/web_archive/aperturescience.com/2007-10-17.html"
                )
            },

            # A list of errors encountered while executing your Lambda.
            # If this is non-empty, then the Request will be marked as "errored" and the error messages
            # will be sent to the configured error channel.
            "errors": []
        }
    else:
        return {
            "body": {},

            # This error message will be sent to the error channel.
            "errors": ["Access Denied: Humans Only!"]
        }


def remove_access(requester):
    # ... some custom de-escalate logic ...
    return {
        "body": {
            "message": f"{requester}, your access to the super secret Aperture Science Heavy Duty Super-Colliding Super Button has ended"
        },
        "errors": []
    }


def is_human(username):
    return username.lower() != "glados"

Use Lambdas in the SDK

You can also invoke Lambda functions from the SDK to enrich your Flows with context from internal systems.

@hook
def on_request(event):
    """Synchronously invoke your AWS lambda."""
    lambda_arn = event.flow.vars["lambda_arn"]
    response = aws_lambda.invoke(lambda_arn, {"event": "on_request", "email": event.user.email})
    print(f"Invoked {lambda_arn} synchronously! Response:")
    print(response)

HTTP Integration

If you want to hit services on the internet, you can use Sym’s HTTP integration directly within our SDK. Our HTTP integration lets you get context and manage escalations for services without requiring an AWS Lambda deployment.