More Implementation Examples
Below is an assortment of additional examples and snippets using the Sym Python SDK.
Restrictions Apply
Your
impl.py
will be executed inside of a RestrictedPython environment, and as a result certain methods might not be available (e.g.all()
,next()
).In addition, imports are allowed from the following modules only:
sym.sdk
requests
json
datetime
Overview
This section provides some basic examples of customized routing logic in a Flow's impl.py
.
Customizing approval behavior
allow_self
allow_self
The slack.channel
method allows you to specify whether or not a request should allow self-approvals. This is generally useful for testing, or for resources that don't require a second party for approval.
In the following implementation, all requests for the Flow are routed to the #sym-requests
Slack channel and the requester may approve their own requests.
from sym.sdk.annotations import reducer
from sym.sdk.integrations import slack
@reducer
def get_approvers(event):
return slack.channel("#sym-requests", allow_self=True)
Modify allow_self
depending on the Target
allow_self
depending on the TargetIn this example, the allow_self
attribute is set based on the Target selected by the requester.
The Target of a request can be found in the fields
attribute of the event Payload
. The Target returned is a sym.sdk.target.AccessTarget
object, containing attributes configured by the sym_target
in main.tf
from sym.sdk.annotations import reducer
from sym.sdk.integrations import slack
@reducer
def get_approvers(event):
# event.payload.fields["target"] returns a Sym SDK Target ojbect
target = event.payload.fields["target"]
allow_self = target.name == "not-so-sensitive-db"
# Only allow_self if the target is "not-so-sensitive-db"
return slack.channel(
"#sym-requests",
allow_self=allow_self,
)
Auto-approve requests
While many Sym requests will benefit from the default human-in-the-middle approval workflow, there may be some workflows that want to move a bit more seamlessly, but without losing Sym's benefits of:
- Request context
- Access revocation
- Audit for compliance
For this common scenario, the on_request
Hook is your friend in automated expedience
from sym.sdk.annotations import hook
from sym.sdk.templates import ApprovalTemplate
@hook
def on_request(event):
# When a request is made in this Flow, automatically approve it.
return ApprovalTemplate.approve()
Customizing Slack logic
Send requests to the channel they came from
Some Sym workflows will be best served in their originating context -- that is to say, they should be sent into the same channel from which they were made.
Sym's Slack Integration makes this easy by providing both access to your initiating channel (evt.run.source_channel.identifier
), and a method to define a fallback
channel in case our Slack App doesn't have access to the originating channel:
from sym.sdk.annotations import reducer
from sym.sdk.integrations import slack
@reducer
def get_approvers(event):
return slack.fallback(slack.channel(event.run.source_channel.identifier), slack.channel("#sym-access"))
Passing Variables from Terraform
Sometimes you will have variable defined in your Terraform that you want to access in your Flow. These could be values set by terraform.tfvars
, or even resource attributes like the ARN of an AWS Lambda!
These variables are set by the vars
attribute in your sym_flow
Terraform resource. They are then exposed as event.flow.vars
in your impl.py
.
In the following example, the request_channel
of the request is passed into the impl.py
as a variable set in Terraform:
resource "sym_flow" "phi" {
name = "phi-access"
label = "PHI Access"
implementation = file("${path.module}/impl.py")
environment_id = var.sym_environment_id
vars = {
request_channel = "#sym-requests"
# An example of a variable that is not known until apply-time!
dynamo_arn = aws_dynamodb_table.my_table.arn
}
params { ... } # truncated
}
from sym.sdk.annotations import reducer
from sym.sdk.integrations import slack
@reducer
def get_approvers(event):
fvars = event.flow.vars
return slack.channel(fvars["request_channel"], allow_self=True)
Updated about 1 month ago