Amazon Web Services (AWS)

Connect your AWS infrastructure to use Opal to manage and review access.

Opal's Amazon Web Services app lets you manage access to your AWS IAM Roles, EC2 instances, EKS instances, and RDS databases across AWS accounts, as well as your AWS IAM Identity Center groups and permission sets.

Our integration supports the following, and more:

  • Users can request time-bounded access to your IAM roles, EC2 instances, EKS instances, RDS databases, and Identity Center permission sets.
  • Auditors can initiate access reviews that assign managers or group admins to periodically review users with long-lived access to AWS resources.
  • All access changes are tracked in a permanent audit log that can notify a Slack channel or be exported to your favorite tools.

Configure Amazon Web Services app

Navigate to the Catalog page, and under the Apps tab, use the + App button in the top right corner to create a new app. Then, select Amazon Web Services.

You'll be presented with an External ID, which is unique to your Opal organization and will be needed for the following step. Opal uses this to safeguard Opal’s third-party access to your data.

You may also enable or disable management of different features. You can change these settings later from the app's Setup page.

  • AWS Organization management: Enables Opal to manage IAM roles, EC2 instances, EKS instances, RDS databases in Opal.
  • IAM Identity Center management: Enables Opal to manage AWS IAM Identity Center groups and permission sets in Opal.

πŸ“˜

Prerequisite for AWS Organizations management: Set up OIDC provider in Opal

Opal uses OpenID Connect (OIDC) to authenticate users when they start a non-Identity-Center AWS session. This adds an extra layer of security by preventing Opal from being able to give access to users that aren't registered with your Identity Provider.

Before enabling AWS Organization management in Opal, ensure that you have configured your OIDC identity provider in Organization Settings:

  1. Register Opal with your IdP to receive a Client ID and Client Secret that will be used to establish a trust relationship between Opal and your IdP. Use the callback URL http://{YOUR_OPAL_BASE_ URL}/callback/oidc, substituting in your Opal base URL (e.g. http://somecorp.opal.dev/callback/oidc).
    For more information about obtaining these credentials, refer to your IdP's documentation: Okta OIDC docs, Google OIDC docs
  2. In Opal, go to the Settings tab at the bottom of the left sidebar.
  3. Locate the OIDC Provider Settings tile under AWS Settings. Click Configure.
  4. If not already filled out, fill in the Client ID, Client Secret, and Issuer URL from your IdP.
  5. Take note of the Client ID, as you'll need it for subsequent steps.

Step 1: Configure your AWS management account

In order for Opal to manage access to your AWS infrastructure, you must configure an IAM Role in your AWS management account. In the AWS console, create a new IAM role called OpalIngester. Give your role the following trust policy, replacing ${EXTERNAL_ID} with the External ID from the Create App page in Opal:

πŸ“˜

Self-hosted customers only

If your Opal instance is self-hosted, please refer to the following prerequisites to set up the trust policy for the OpalIngester IAM role:

Once complete, come back to these instructions to add the permissions policy for the role and complete the other steps.

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::602387580983:user/OpalIngester"
			},
			"Action": [
				"sts:AssumeRole"
			],
			"Condition": {
				"StringEquals": {
					"sts:ExternalId": "${EXTERNAL_ID}"
				}
			}
		},
		{
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::602387580983:user/OpalIngester"
			},
			"Action": [
				"sts:TagSession"
			]
		}
	]
}

Next, attach the following permissions policy to the role. Note that some permissions are always required, some are required to manage non-Identity Center resources (like EC2 instances, IAM roles, etc.), and some are required specifically to manage Identity Center-managed roles.

πŸ“˜

In certain cases, you may also need to add the iam:UpdateSAMLProvider action to the RequiredForIdentityCenterIAMRoleProvisioningInManagementAccountstatement. See AWS documentation.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AlwaysRequired",
      "Effect": "Allow",
      "Action": [
        "organizations:DescribeAccount",
        "organizations:ListAccounts",
        "organizations:ListTagsForResource",
        "account:ListRegions"
      ],
      "Resource": "*"
    },
    {
      "Sid": "RequiredToManageNonIdentityCenterResourcesInThisAccount",
      "Effect": "Allow",
      "Action": [
        "iam:ListRoleTags",
        "iam:ListRoles",
        "iam:ListPolicies",
        "iam:GetRolePolicy",
        "iam:GetPolicy",
        "iam:GetRole",
        "rds:DescribeDBInstances",
        "rds:DescribeDBClusters",
        "ec2:DescribeInstances",
        "eks:DescribeCluster",
        "eks:ListClusters",
        "ssm:DescribeSessions"
      ],
      "Resource": "*"
    },
    {
      "Sid": "RequiredToManageIdentityCenter",
      "Effect": "Allow",
      "Action": [
        "sso:ListPermissionSets",
        "sso:ListPermissionSetsProvisionedToAccount",
        "sso:DescribePermissionSet",
        "sso:ListAccountAssignments",
        "sso:CreateAccountAssignment",
        "sso:DeleteAccountAssignment",
        "sso:DescribeAccountAssignmentCreationStatus",
        "sso:DescribeAccountAssignmentDeletionStatus",
        "identitystore:ListUsers",
        "identitystore:ListGroups",
        "identitystore:DescribeUser",
        "identitystore:DescribeGroup",
        "identitystore:GetGroupMembershipId",
        "identitystore:ListGroupMemberships",
        "identitystore:CreateGroupMembership",
        "identitystore:DeleteGroupMembership"
      ],
      "Resource": "*"
    },
    {
      "Sid": "RequiredForIdentityCenterIAMRoleProvisioning",
      "Effect": "Allow",
      "Action": "iam:GetSAMLProvider",
      "Resource": "arn:aws:iam::*:saml-provider/AWSSSO_*_DO_NOT_DELETE"
    },
    {
      "Sid": "RequiredForIdentityCenterIAMRoleProvisioningInManagementAccount",
      "Effect": "Allow",
      "Action": [
        "iam:AttachRolePolicy",
        "iam:CreateRole",
        "iam:ListRolePolicies"
      ],
      "Resource": [
        "arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:PrincipalOrgMasterAccountId": "${aws:PrincipalAccount}"
        }
      }
    },
    {
      "Sid": "RequiredToReadUsageData",
      "Effect": "Allow",
      "Action": ["cloudtrail:LookupEvents"],
      "Resource": "*"
    }
  ]
}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      // This statement is required in all setups. 
      // The Opal AWS integration will not function correctly without it.
      "Sid": "AlwaysRequired",
      "Effect": "Allow",
      "Action": [
        // Required to show information about your AWS accounts in Opal.
        "organizations:DescribeAccount",
        "organizations:ListAccounts",
        "organizations:ListTagsForResource",
        // Required to filter out disabled regions when importing resources.
        "account:ListRegions"
      ],
      "Resource": "*"
    },
    {
      // Required to import your non-Identity Center resources from this account. 
      // This includes IAM Roles, EC2 instances, EKS clusters, and RDS databases. 
      // This statement can be removed for configurations that opt out of AWS 
      // Organization management in Opal.
      "Sid": "RequiredToManageNonIdentityCenterResourcesInThisAccount",
      "Effect": "Allow",
      "Action": [
        // Required to show IAM Roles in Opal.
        "iam:ListRoleTags",
        "iam:ListRoles",
        "iam:GetRolePolicy",
        "iam:GetPolicy",
        "iam:GetRole",
        // Required to show RDS databases in Opal
        "rds:DescribeDBInstances",
        "rds:DescribeDBClusters",
        // Required to show EC2 instances in Opal
        "ec2:DescribeInstances",
        // Required to show EKS clusters in Opal
        "eks:DescribeCluster",
        "eks:ListClusters",
        // Required to show EC2 instance sessions in Opal
        "ssm:DescribeSessions"
      ],
      "Resource": "*"
    },
    { 
      // Required to manage your Identity Center resources from all accounts. This statement
      // can be removed for configurations that opt out of Identity Center management in Opal.
      "Sid": "RequiredToManageIdentityCenter",
      "Effect": "Allow",
      "Action": [
        // Required to show Permission sets and their assignments in Opal
        "sso:ListPermissionSets",
        "sso:ListPermissionSetsProvisionedToAccount",
        "sso:DescribePermissionSet",
        "sso:ListAccountAssignments",
        // Required to populate user access to permission sets
        "sso:CreateAccountAssignment",
        "sso:DeleteAccountAssignment",
        "sso:DescribeAccountAssignmentCreationStatus",
        "sso:DescribeAccountAssignmentDeletionStatus",
        // Required to provision Identity Center group memberships
        "identitystore:ListUsers",
        "identitystore:ListGroups",
        "identitystore:DescribeUser",
        "identitystore:DescribeGroup",
        "identitystore:GetGroupMembershipId",
        "identitystore:ListGroupMemberships",
        "identitystore:CreateGroupMembership",
        "identitystore:DeleteGroupMembership"
      ],
      "Resource": "*"
    },
    {
      // Required to provision permission sets. When account assignments are modified,
      // iam:GetSAMLProvider is called under the hood by AWS. Permission Set provisioning
      // operations do not function without this permission. This statement can be removed
      // for configurations that opt out of IAM Identity Center management in Opal.
      "Sid": "RequiredForIdentityCenterIAMRoleProvisioning",
      "Effect": "Allow",
      "Action": "iam:GetSAMLProvider",
      "Resource": "arn:aws:iam::*:saml-provider/AWSSSO_*_DO_NOT_DELETE"
    },
    {
      // Required to provision permission sets in Management account. This statement
      // can be removed for configurations that do not require provisioning IAM 
      // Identity Center permission sets in their management account with Opal.
      "Sid": "RequiredForIdentityCenterIAMRoleProvisioningInManagementAccount",
      "Effect": "Allow",
      "Action": [
        // In certain cases, you may also need to add iam:UpdateSAMLProvider here.
        "iam:AttachRolePolicy",
        "iam:CreateRole",
        "iam:ListRoles",
        "iam:ListRolePolicies"
      ],
      "Resource": [
        "arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:PrincipalOrgMasterAccountId": "${aws:PrincipalAccount}"
        }
      }
    },
    {
      // Required to display usage data in Opal.
      "Sid": "RequiredToReadUsageData",
      "Effect": "Allow",
      "Action": ["cloudtrail:LookupEvents"],
      "Resource": "*"
    }
  ]
}

Step 2 [AWS Organizations Management only]: Configure additional AWS accounts to be managed by Opal

If you are only setting up AWS IAM Identity Center, you can skip to Step 3.

For each AWS account besides the management account that you want Opal to manage, you must add an Identity Provider and 2 IAM Roles with different permission scopes. Perform steps 2a-2c for each account.

Step 2a: Ingester Role

Note: This step can be skipped for your management account as its ingester role has already been configured in the management account in step 1.

The ingester role allows Opal to read your configuration and populate it within Opal. Create a role called OpalIngester, with the same trust policy as above:

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::602387580983:user/OpalIngester"
			},
			"Action": [
				"sts:AssumeRole"
			],
			"Condition": {
				"StringEquals": {
					"sts:ExternalId": "${EXTERNAL_ID}"
				}
			}
		},
		{
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::602387580983:user/OpalIngester"
			},
			"Action": [
				"sts:TagSession"
			]
		}
	]
}

Then, attach the following permissions policy to it:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "OpalRequiredToManageAccount",
      "Effect": "Allow",
      "Action": [
        "iam:ListRoleTags",
        "iam:ListRoles",
        "iam:GetRolePolicy",
        "iam:GetPolicy",
        "iam:GetRole",
        "rds:DescribeDBInstances",
        "rds:DescribeDBClusters",
        "ec2:DescribeInstances",
        "eks:DescribeCluster",
        "eks:ListClusters",
        "account:ListRegions"
      ],
      "Resource": "*"
    }
  ]
}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      // Required to import IAM Roles, EC2 instances, EKS clusters and RDS databases into Opal.
      "Sid": "OpalRequiredToManageAccount",
      "Effect": "Allow",
      "Action": [
        "iam:ListRoleTags",
        "iam:ListRoles",
        "iam:GetRolePolicy",
        "iam:GetPolicy",
        "iam:GetRole",
        "rds:DescribeDBInstances",
        "rds:DescribeDBClusters",
        "ec2:DescribeInstances",
        "eks:DescribeCluster",
        "eks:ListClusters",
        // Required to filter out disabled regions when importing resources.
				"account:ListRegions"
      ],
      "Resource": "*"
    }
  ]
}

Step 2b: Identity Provider

Follow AWS's instructions to register your identity provider in your AWS account. Fill in the Audience field using the Client ID configured in Opal.

Step 2c: User Role

The User role is used to grant your authenticated users access to the resources that have been allocated to them.

Create a new role called OpalUser with the following trust policy, substituting in your management account ID, IDP issuer URL, and the Client ID used for your OIDC configuration, substituting as follows:

  • ${ACCOUNT_ID}: The account ID of the account being configured.
  • ${IDP_ISSUER_URL}: The Identity Provider's issuer URL
  • ${OPAL_CLIENT_ID}: The Client ID you used in Step 2b.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${IDP_ISSUER_URL}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "${IDP_ISSUER_URL}:aud": "${OPAL_CLIENT_ID}"
        }
      }
    }
  ]
}

This trust policy ensures that only users authenticated with your identity provider can be granted access to the role.

Next, add the following permissions policy to the role:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "OpalRequiredToManageUserSessions",
      "Effect": "Allow",
      "Action": [
        "access-analyzer:ValidatePolicy",
        "ec2:DescribeInstances",
        "eks:DescribeCluster",
        "eks:ListClusters",
        "iam:GetRole",
        "iam:ListRoleTags",
        "iam:GetRolePolicy",
        "iam:DeleteRolePolicy",
        "iam:PutRolePolicy",
        "iam:ListRoles",
        "iam:TagRole",
        "rds-db:connect",
        "rds:DescribeDBClusters",
        "rds:DescribeDBInstances",
        "sts:TagSession",
        "ssm:DescribeInstanceProperties",
        "ssm:SendCommand",
        "ssm:GetConnectionStatus",
        "ssm:TerminateSession",
        "ssm:StartSession"
      ],
      "Resource": "*"
    }
  ]
}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      // Required to:
      // * Revoke user sessions in this account
      // * Grant users session-based access to:
      //   * IAM Roles 
      //   * EC2 instances
      //   * EKS clusters 
      //   * RDS databases
      "Sid": "OpalRequiredToManageUserSessions",
      "Effect": "Allow",
      "Action": [
        // Required to read/validate AWS configuration
        "access-analyzer:ValidatePolicy",
        "ec2:DescribeInstances",
        "eks:DescribeCluster",
        "eks:ListClusters",
        "iam:GetRole",
        "iam:ListRoles",
        "iam:ListRoleTags",
        "iam:GetRolePolicy",
        "rds:DescribeDBClusters",
        "rds:DescribeDBInstances",
        "ssm:DescribeInstanceProperties",
        "ssm:DescribeSessions",
        "ssm:GetConnectionStatus",
        // Required to tag roles and sessions
        "sts:TagSession",
        "iam:TagRole",
        // Required to revoke sessions before expiration, e.g. if a user's access
        // is removed by admin in Opal.
        "iam:DeleteRolePolicy",
        "iam:PutRolePolicy",
        // Required to grant end-users session credentials.
        "rds-db:connect",
        "ssm:SendCommand",
        "ssm:TerminateSession",
        "ssm:StartSession"
      ],
      "Resource": "*"
    }
  ]
}

Step 3: Fill out Opal form

Back in the Create App form in Opal, fill in the details of your AWS configuration.

If you're setting up AWS Identity Center, you can find the additional settings you must input in your AWS console under IAM Identity Center > Settings.

Authentication model

Below is a high level summary of how Opal authenticates for two major workflows:

  1. Synchronizing your AWS Organizations resources in Opal
  2. Granting Opal users sessions to AWS resources