Boundary Access Strategy

📘

Did you configure your Boundary Integration?

Before continuing, make sure you followed the instructions on the main Boundary page to set up your Boundary system user and Integration.

Before continuing, you will need to have:

  • Connected Sym with AWS Secrets Manager
  • Configured your Boundary system user's credentials with Sym
  • Defined a Boundary Integration resource

Add Boundary Access Targets

Define sym_target resources with type = boundary_group for all of the Boundary Groups that you wish to manage access to.


resource "sym_target" "boundary_admins" {
  type  = "boundary_group"
  name  = "boundary-admins"
  label = "Admin Group"

  settings = {
    group_id = "g_123abc"
  }
}

resource "sym_target" "boundary_power_users" {
  type  = "boundary_group"
  name  = "boundary-power-users"
  label = "Power Users Group"

  settings = {
    group_id = "g_xyz789"
  }
}

Add a Boundary Access Strategy

Define a sym_strategy resource with type = boundary and include the Boundary Integration and Boundary Access Targets you defined above.

esource "sym_strategy" "boundary" {
  type           = "boundary"
  name           = "boundary-strategy"

  integration_id = sym_integration.boundary.id
  targets        = [sym_target.boundary_admins.id, sym_target.boundary_power_users.id]
}

Add the Boundary Strategy to your Flow

In your sym_flow resource, reference your Boundary sym_strategy as the strategy_id in your Flow Parameters.

resource "sym_flow" "this" {
  name  = "boundary"
  label = "Boundary Group Access"

  # ... other Flow attributes not shown

  params = {
    strategy_id = sym_strategy.boundary.id

    # ... other Flow params not shown
  }
}

Advanced Concepts

Supply the Boundary Group ID Dynamically

If you have many Boundary Groups and don't want to create a Boundary Access Target for each one, you can use Dynamic Targets and a Prefetch Reducer to pull Boundary Groups dynamically!

Add a Group ID Prompt Field

In your sym_flow configuration, add a new prompt field for group_id with prefetch = true. This will add an input field "Group ID" to the Slack Request Modal. The list of Groups that a user may select from will be provided via a prefetch reducer that we will implement in a later step.

Note, this prompt field must have name = "group_id", because we are using this prompt field to populate the required group_id setting of the Boundary Access Target.

resource "sym_flow" "this" {
  name  = "boundary"
  label = "Boundary Group Access"

  # ... other Flow attributes not shown

  implementation = file("${path.module}/impls/boundary-impl.py")

  params {
    strategy_id = sym_strategy.boundary.id

    prompt_field {
      name     = "group_id"
      label    = "Group ID"
      type     = "string"
  		prefetch = true
      required = true
    }
  
    # ... other prompt_fields and Flow params not shown
  }
}

Define a Dynamic Target

Define a single Boundary Access Target, with a special attribute called field_bindings. This attribute indicates that the group_id setting will be populated dynamically by the requester.

The field binding must be group_id, because this is the required setting that is being dynamically populated.

resource "sym_target" "dynamic_boundary_group" {
  type  = "boundary_group"

  name  = "boundary-group"
  label = "Boundary Group"

  # A special attribute that indicates the `group_id` setting is dynamic
  field_bindings = ["group_id"]
}

Define a Prefetch Reducer for the Group IDs

In the first step, we added a prompt field named group_id with prefetch = true. When a user runs this Flow, Sym will look for a method in your implementation annotated with @prefetch(field_name="group_id"). This reducer should return a list of FieldOption objects, which are value and label pairs.

We will want to define a method that returns a list of Group ID and Group Names for Users to select from.

🚧

Prefetch Reducer Limits

Prefetch reducers may return a maximum of 1000 items! If you have many Boundary Groups, you should utilize the filter parameter in list_groups to ensure that you do not return more than 1000 groups.

See Boundary's Documentation for more information about filter expression syntax. When writing filter expressions for list_groups, ensure that your filter expression is prepended with /item, as documented by Boundary's Resource listing documentation.

# Don't forget these imports!
from sym.sdk.annotations import prefetch
from sym.sdk.integrations import boundary
from sym.sdk.field_option import FieldOption

# ... Other reducers and hooks not shown

@prefetch(field_name="group_id")
def get_boundary_groups(event):
  # Prefetch reducers cannot return more than 1000 items! In this example, we are filtering
  # Boundary groups to get all groups that contain "Sym Managed" in the Group Name.
  groups = boundary.list_groups(scope_id="global", recursive=True, filter='"/item/name" contains "Sym Managed"')

  # Return a list of FieldOption, where the displayed label is the Group's Name,
  # and the value is the Group ID.
  return [
      FieldOption(value=group["id"], label=group["name"])
      for group
      in groups
  ]

With these changes, your requests should now have a type-ahead dropdown input allowing requesters to specify to which Boundary Group they wish to be escalated to.