AWS IAM Identity Center (SSO) Access Strategy
Use Sym to seamlessly shift users in and out of AWS SSO roles.
Sym's AWS SSO Strategy enables you to have:
- Just-in-time permission set assignments to a given AWS Account
- Just-in-time access to a given AWS SSO Group
You can generate this!
You can automatically generate an AWS SSO Flow with
symflow generate aws-sso
!Otherwise, follow the AWS Runtime Setup tutorial to set up your AWS dependencies.
Connect the Sym Runtime with your AWS Account
Follow the AWS Runtime Setup tutorial on the main AWS page to set up your runtime_connector
module.
Add a AWS SSO Integration
Define the SSO Connector
The AWS SSO Access Strategy relies on a special module sso-connector
. This module defines the AWS IAM Resources that enable Sym to manage SSO Permission Sets in your AWS Account.
provider "aws" {
alias = "sso"
region = "us-east-1"
# Change this profile name to a valid AWS profile for the AWS account where
# your AWS SSO instance lives.
profile = "sso"
}
# Get the AWS Account ID for the SSO profile.
data "aws_caller_identity" "sso" {
provider = aws.sso
}
module "sso_connector" {
source = "symopsio/sso-connector/aws"
version = ">= 1.0.0"
# Provision the SSO connector in the AWS account where your AWS
# SSO instance lives.
providers = {
aws = aws.sso
}
environment = local.environment_name
runtime_role_arns = [module.runtime_connector.sym_runtime_connector_role.arn]
}
Define the AWS SSO Permission Context Integration
Define a sym_integration
resource with type = permission_context
. This tells Sym to assume the AWS IAM Role defined by the SSO Connector module when managing your SSO Permission Sets, and will be referenced in the sym_strategy
resource later.
external_id
: Theinstance_arn
output frommodule.sso_connector.settings
settings
: Thesettings
output frommodule.sso_connector
resource "sym_integration" "sso_context" {
type = "permission_context"
name = "sso-context-main"
external_id = module.sso_connector.settings.instance_arn
settings = module.sso_connector.settings
}
Allow the Sym Runtime to Assume Roles in your SSO Account
The sso-connector
module will create an AWS IAM Role in your SSO Account that has the permissions to create and remove account assignments. You will need to grant the Sym Runtime permissions to assume this role. In the runtime_connector
module, add an account_id_safelist
input containing your SSO Account ID.
module "runtime_connector" {
source = "symopsio/runtime-connector/aws"
version = "~> 2.0"
environment = local.environment_name
# Allow the Runtime Connector Role to assume IAM Roles in the SSO Account as well.
account_id_safelist = [data.aws_caller_identity.sso.account_id]
}
Add AWS SSO Access Targets
AWS SSO Permission Set Targets
Sym Targets with a type of aws_sso_permission_set
enables just in time account assignments for a given permission set and AWS account.
Define sym_target
resources with type = "aws_sso_permission_set"
for all of the AWS SSO Permission Sets that you wish to manage.
account_id
: The AWS Account ID for the AWS SSO Permission Setpermission_set_arn
: The ARN of the AWS SSO Permission Set.
resource "sym_target" "sso_permission_set" {
type = "aws_sso_permission_set"
name = "aws-sso-target-main"
label = "AWS SSO Permission Set Test Target"
settings = {
account_id = var.aws_sso_account_id
permission_set_arn = aws_ssoadmin_permission_set.this.arn
}
}
AWS SSO Group Targets
Sym Targets with a type of aws_sso_group
enables just in time access to AWS SSO Groups.
Define sym_target
resources with type = "aws_sso_group"
for all of the AWS SSO groups that you wish to manage.
group_id
: The ID of the AWS SSO Group. If you manage this group as anaws_identitystore_group
resource in Terraform, you can use thegroup_id
attribute to populate this value!
# An AWS SSO group to escalate users to
resource "aws_identitystore_group" "sso_group" {
provider = aws.sso
display_name = "My AWS SSO Group"
identity_store_id = one(data.aws_ssoadmin_instances.ingen_sso.identity_store_ids)
}
# AWS SSO Group Sym Target
resource "sym_target" "sso_group" {
type = "aws_sso_group"
name = "aws-sso-group-main"
label = aws_identitystore_group.sso_group.display_name
settings = {
# The group ID to escalate users to
group_id = aws_identitystore_group.sso_group.group_id
}
}
Add an AWS SSO Access Strategy
Define a sym_strategy
resource with type = aws_sso
and include the AWS SSO Permission Context and AWS SSO Access Targets you defined above.
instance_arn
= Theinstance_arn
output frommodule.sso_connector.settings
resource "sym_strategy" "aws_sso" {
type = "aws_sso"
name = "aws-sso-strategy-main"
integration_id = sym_integration.sso_context.id
# A list of `aws_sso_permission_set` and/or `aws_sso_group` targets
targets = [sym_target.sso_permission_set.id, sym-target.sso_group.id]
settings = {
instance_arn = module.sso_connector.settings.instance_arn
}
}
Add the AWS SSO Strategy to your Flow
resource "sym_flow" "this" {
name = "sso-access-main"
label = "AWS SSO Access"
# ... other Flow attributes not shown
params {
strategy_id = sym_strategy.aws_sso.id
# ... other Flow params not shown
}
}
Full Example
You can find the complete code for this example in our AWS IAM Identity Center (SSO) Strategy Example.
Consider your session lengths
Sym access will provide your users with the keys to access escalated permissions, but AWS still governs the bounding sessions. This means:
- If your Sym access is shorter than your default session length, users who access an escalated role will retain that role until their session times out.
- Conversely, if your Sym access is longer than your default session length, users may be logged out and have to re-authenticate.
Advanced Concepts
Supply the AWS Account ID Dynamically
If you have many AWS Account IDs and don't want to create a Permission Set/Account ID combination for each one, you can use Dynamic Targets and a Prefetch Reducer to pull AWS Accounts dynamically!
Add an Account ID Prompt Field
In your sym_flow
configuration, add a new prompt field for account_id
with prefetch = true
. This will add an input field "Account ID" to the Slack Request Modal. The list of accounts 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 = "account_id"
, because we are using this prompt field to populate the required account_id
setting of the AWS SSO Access Target.
resource "sym_flow" "this" {
name = "aws_sso_access"
label = "AWS SSO Access"
# ... other Flow attributes not shown
implementation = file("${path.module}/impls/aws-sso-impl.py")
params {
strategy_id = sym_strategy.this.id
prompt_field {
name = "account_id"
label = "Account ID"
type = "string"
prefetch = true
required = true
}
# ... other prompt_fields and Flow params not shown
}
}
Define a Dynamic Target
Define a target for each AWS SSO Permission Set, but with a special attribute called field_bindings
. This attribute indicates that the account_id
setting will be populated dynamically by the requester.
The field binding must be account_id
, because this is the required setting that is being dynamically populated.
resource "sym_target" "permission-set" {
type = "aws_sso_permission_set"
name = "permission-set-name"
label = "Permission Set Name"
# A special attribute that indicates the `account_id` setting is dynamic
field_bindings = ["account_id"]
settings = {
permission_set_arn = "arn:aws:sso:::permissionSet/ssoins-aaaaaaaaaaaaaaaa/ps-aaaaaaaaaaaaaaaa"
}
}
Define a Prefetch Reducer for the Account IDs
In the first step, we added a prompt field named account_id
with prefetch = true
. When a user runs this Flow, Sym will look for a method in your implementation annotated with @prefetch(field_name="account_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 Account ID and Account Names for Users to select from.
# Don't forget these imports!
from sym.sdk.annotations import prefetch
from sym.sdk.integrations import aws_sso
# ... Other reducers and hooks not shown
@prefetch(field_name="account_id")
def get_account_ids(event):
# This gets all AWS Accounts that are direct children of this Organizational Unit.
# If you wish to get all accounts, you may call aws_sso.list_accounts() with no parameters.
# See: https://sdk.docs.symops.com/doc/sym.sdk.integrations.aws_sso.list_accounts.html
all_accounts = aws_sso.list_accounts(organizational_unit_id="ou-abcd-123456789")
# Return a list of FieldOption, where the displayed label is the Account's Name,
# and the value is the Account ID.
return [
FieldOption(value=account["Id"], label=account["Name"])
for account
in all_accounts
]
With these changes, your requests should now have a type-ahead dropdown input allowing requesters to specify to which AWS Account they wish to be escalated to.
Updated 7 days ago