Sym helps developers solve painful access management problems with standard infrastructure tools.

Is your team experiencing:

Sym can help! This quickstart will help you launch a new access flow in under an hour. Your engineers will be able to safely and conveniently gain access to sensitive resources, all with the guardrails you need in place.

If you want to check out a demo, go here!

Workflow: GitHub Actions + Okta

We're going to walk through setting up an Otka-based Sym Flow that is provisioned and managed with GitHub Actions. By the end of this tutorial, you'll have the ability to provision, test and validate Sym Flows in a sandbox environment and then push the Flows to prod, all from GitHub Actions.

The complete code for this tutorial can be found at @symopsio/sym-github-actions-quickstart.

Video Walkthrough

Video Thumbnail

Check out this walkthrough companion to the quickstart if you'd like to see the workflow in action!

Users will interact with this Sym Flow via Slack. Slack connects to the Sym platform, which executes a Flow that use the Integrations we are wiring together in this tutorial.

End-User Workflow

Making Requests

This is what a request will look like.

Request Modal

Sym will send a request for approval to the appropriate users or channel based on your

Approval Request

Finally, upon approval, Sym gives you access to the Okta group and updates Slack.

Approved Access

Implementers push their changes to a sandbox branch, which updates the sandbox Sym Environment via GitHub Actions.

Testing Flow

When Implementers open a Pull Request to the main branch, we've provided a GitHub Action that includes a terraform plan of the changes as a comment. When you merge, the GitHub Action does a terraform apply that updates the prod Sym Environment.

GitHub Comment

This setup guide walks you through everything you need to get a Sym Okta workflow configured with GitHub Actions!

Key components:

  1. A GitHub AWS OIDC role that lets you run AWS operations from GitHub without access keys
  2. A GitHub action to create a Terraform state bucket to manage your Sym resource state
  3. A GitHub workflow to manage changes through sandbox and prod environments.
  4. A placeholder Cypress test to validate your Sandbox flow.

You can mix and match from these components if you want to manage Terraform state differently, don't want to use GitHub actions, or don't want to use the OIDC role.

What's Next

The environments directory includes sandbox, prod, and bootstrap Terraform configurations to get you up and running. Just configure a few variables in terraform.tfvars and you're on your way!

Here's what you'll need to do:

You'll need to work with the Sym team to get your organization set up with access to the Sym platform. Once you're onboarded, continue from here.

Install the symflow CLI

The symflow CLI is what you use to interact with Sym's control plane.

$ brew install symopsio/tap/symflow
==> Tapping symopsio/tap
Cloning into '/opt/homebrew/Library/Taps/symopsio/homebrew-tap'...
remote: Enumerating objects: 1148, done.
remote: Counting objects: 100% (285/285), done.
remote: Compressing objects: 100% (222/222), done.
remote: Total 1148 (delta 134), reused 156 (delta 59), pack-reused 863
Receiving objects: 100% (1148/1148), 324.27 KiB | 6.36 MiB/s, done.
Resolving deltas: 100% (530/530), done.
Tapped 14 formulae (43 files, 582.7KB).
==> Downloading
######################################################################## 100.0%
==> Installing symflow from symopsio/tap
🍺  /opt/homebrew/Cellar/symflow/1.3.7: 10,351 files, 198MB, built in 33 second


We'll have to login before we can do anything else. Sym also supports SSO, if your organization has set it up.

$ symflow login
Sym Org: healthy-health
Password: ************
MFA Token: ******

Success! Welcome, Sym Implementer. 🤓

Set your Org slug

You'll need to use the slug given to you by the Sym team, and set it in terraform.tfvars in your prod and sandbox environments.

# environments/prod/terraform.tfvars
# environments/sandbox/terraform.tfvars

sym_org_slug = "healthy-health"

Now that you've got symflow installed, you need to install Sym's Slack app into your workspace. Sym supports running multiple environments in a single Slack workspace, OR you can choose to install your sandbox flows into a test workspace.

Grab your Workspace ID

The easiest place to find this is in the URL you see when you run Slack in your web browser. It will start with a T, and look something like TABC123.

This also goes in terraform.tfvars.

# environments/prod/terraform.tfvars
# environments/sandbox/terraform.tfvars

slack_workspace_id = "TABC123"

Provision your Slack app

symflow has a convenient way to provision an instance of Sym's Slack app. This command will generate an install link that you can either use directly, or forward on to your Workspace Administrator.

$ symflow services create --service-type slack --external-id T123ABC
Successfully set up service type slack with external ID TABC123!
Generated an installation link for the Sym Slack app:

Please send this URL to an administrator who has permission to install the app. Or, if that's you, we can open it now.

Would you like to open the Slack installation URL in a browser window? [Y/n]:

Once Slack is set up, try launching the Sym app with /sym in Slack.

You should see a welcome modal like this one, since we haven't set up a Flow yet:

Slack Welcome Modal

In order to run GitHub actions to deploy your flows, make a copy of the sym-github-actions-quickstart repo in your org. Once you have the repo copied, use symflow to configure a bot token that lets Sym authenticate from your GitHub action:

$ symflow bots create github
$ symflow tokens issue --username github --label "GitHub Actions" --expiry 365d
<token output here>

Configure a repository secret with the token value. Set the SYM_JWT key to the bot token value.

In order to deploy and run Sym, you'll need to provide AWS credentials to create Sym's dependencies in your infrastructure.

Positive : We've set up these GitHub actions to use an AWS Role instead of AWS Access Keys. Using GitHub OIDC, you can access resources in AWS without configuring access keys and secrets in your GitHub environment.

We provide you an AWS IAM Policy that includes all the permissions required to set up this repo. To wire this up with GitHub OIDC, update the AWS_ROLE_ARN value in the GitHub actions configs.

If you don't want to use GitHub OIDC, you can remove the AWS_ROLE_ARN and use standard AWS Access Keys.

Option 1: Use Terraform

If you have an existing Terraform pipeline you can include the environments/bootstrap configurations to create the required GitHub OIDC provider and IAM policy.

$ cd environments/bootstrap
$ terraform apply

Option 2: Provision with the AWS CLI or with other tooling

We have a gist with all the requirements you need to provision Sym's policies using your own tooling.

Create the Sym AWS IAM Policy

We'll create the policy that lets you provision Sym dependencies first, and then attach this to a role, group, or user as needed.

  1. Grab access-policy.json.
  2. Edit access-policy.json, replacing AWS_ACCOUNT_ID with the AWS Account ID you'll be provisioning into.
  3. Provision the policy:
$ aws iam create-policy --policy-name SymGitHubActionAccess \

GitHub Actions OIDC (Optional): Attach the policy to a GitHub Actions OIDC Role

GitHub Actions lets you configure an AWS IAM Role that Actions can assume, so you don't have to configure and/or rotate AWS Access Keys in your GitHub account.

In order to set this up, you need to create an AWS IAM Identity Provider and an AWS IAM Role that can assume this Identity Provider.

  1. Grab create-open-id-connect-provider.json and then run the following to create a GitHub OIDC Identity Provider in your account:
$ aws iam create-open-id-connect-provider --cli-input-json file://create-open-id-connect-provider.json
  1. Grab assume-role-policy-document.json and edit the following three values:
    • ACCOUNT_ID: Set the AWS Account ID where you're provisioning this Role
    • GITHUB_ORG: Set to the GitHub organization where your GitHub action will run
    • GITHUB_REPO: Set to the name of the GitHub repo where your GitHub action will run
  2. Provision the IAM Role with the edited assume-role-policy-document.json:
$ aws iam create-role --role-name SymGitHubActionAccess \
  --asume-role-policy-document file://assume-role-policy-document.json
  1. Attach the Sym access policy to your GitHub Actions role:
$ aws iam attach-role-policy --role-name SymGitHubActionAccess \
  --policy-arn arn:aws:iam::AWS_ACCOUNT_ID:policy/SymGitHubActionAccess
  1. Update the AWS_ROLE_ARN value in your GitHub Actions configs to use the ARN of the role you just created.

No GitHub Actions OIDC: Create an AWS IAM User

If setting up the GitHub AWS OIDC connection is not for you, then you can simply create an AWS IAM user that can bootstrap Sym workflows, or attach the required permissions to an existing users.

If you're taking this path, you should update your GitHub Actions configs to not use AWS_ROLE_ARN and instead rely on an AWS Access Key and Secret.

This repo includes a bootstrap workflow that you can use to set up Terraform state management directly from GitHub actions.

To run the bootstrap workflow, make sure you've edited the AWS_ROLE_ARN value in main.yml and terraform-bootstrap.yml to the right value, or that you've removed it entirely if you plan to use an AWS Access Key and Secret.

  1. Manually trigger the bootstrap workflow from the GitHub Actions console
  2. The bootstrap workflow will create a Pull Request with the updates to use S3 to manage your Terraform state.
  3. When you merge the workflow, your prod e2e flow will be provisioned!

Try out a request!

You should be able to make a request now with /sym req, though you'll get an error when you try to approve access, since we haven't configured Okta yet.

Check in your errors_channel and you should see something like this:


Now that the prod workflow is set up, lets finishing configuring flows so that we have a sandbox flow where we can test stuff out!

  1. From your local console, create a sandbox branch and push it to remote
$ git checkout -b sandbox
$ git push -u sandbox
  1. This will trigger a GitHub action to set up your sandbox flow! If you go back to Slack, you'll now see a "Show all environments" option that lets you run your sandbox flow.

Negative : Now that you have a sandbox flow set up, we recommend adding branch protection rules for your main branch!

This Flow is set up to route access requests to the #sym-requests channel. You can change this channel in—wait for it—terraform.tfvars.

Sym will also send any errors that happen during a Run (due to external failures or config issues) to a configurable error channel. You'll never guess where you can configure this.

# environments/prod/terraform.tfvars
# environments/sandbox/terraform.tfvars

flow_vars = {
  request_channel = "#sym-requests"

You can also change the channel that errors are routed to, which defaults to #sym-errors.

# environments/prod/terraform.tfvars
# environments/sandbox/terraform.tfvars

error_channel = "#sym-errors"

Sym stores your Okta API token in an AWS Secrets Manager value. By default, the sym-runtime module sets up a shared AWS Secrets Manager secret that you add key/value pairs to for the secrets that your Runtime needs to access.

Create your API token

Follow our Okta setup instructions to create an Okta API token that has access to manage your target groups.

Set your API token in Sym

Configure the API key in the AWS Secrets Manager secret configured by your sym-runtime module like so.

$ aws secretsmanager put-secret-value \
  --secret-id / \
  --secret-string "{\"okta_api_token\": \"$OKTA_API_TOKEN\"}"
$ aws secretsmanager put-secret-value \
  --secret-id / \
  --secret-string "{\"okta_api_token\": \"$OKTA_API_TOKEN\"}"

Positive : You are free to define your secrets in separate AWS Secret Manager resources if you choose, you'll just need to update where your Flow grabs its secret from.

Identify the initial Okta groups that Sym will move users in and out of. You can always change and modify these groups later, so we recommend starting with an existing group or creating a temporary group for testing.

Set Group IDs

Get the IDs of the Okta groups that you'll be starting with. Configure these in okta_targets in terraform.tfvars.

# environments/prod/terraform.tfvars
# environments/sandbox/terraform.tfvars

okta_targets = [
    label    = "AWS Ops Admin",
    group_id = "CHANGEME"

Set Okta domain

Set your Okta domain as well.

# environments/prod/terraform.tfvars
# environments/sandbox/terraform.tfvars

okta_org_domain = ""

We've included a placeholder Cypress test that will run when you open a PR against the main branch.

  1. Update your tfvar configurations in step 7 and push the changes to the sandbox branch.
  2. You should see that your changes get updated in the sandbox environment.
  3. Now open a PR against main. You should see a plan of your changes against the prod environment, as well as a cypress run that you can use to test the sandbox version of the flow!

Here are some next steps to consider: