From 779d8c730a535d25f5223a5b4dd8dd5e680385c1 Mon Sep 17 00:00:00 2001 From: Jarrod Lowe <41766555+jarrod-lowe@users.noreply.github.com> Date: Sun, 11 Aug 2024 15:46:17 +1200 Subject: [PATCH] Cognito Setup part 1 (#21) --- .github/workflows/environment-main-plan.yaml | 1 + README.md | 41 +++++++++- terraform/environment/aws/policy.tf | 85 +++++++++++++++++++- terraform/environment/wildsea/cognito.tf | 81 +++++++++++++++++++ terraform/environment/wildsea/main.tf | 11 +++ 5 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 terraform/environment/wildsea/cognito.tf diff --git a/.github/workflows/environment-main-plan.yaml b/.github/workflows/environment-main-plan.yaml index 49bfe1e5..c973dc72 100644 --- a/.github/workflows/environment-main-plan.yaml +++ b/.github/workflows/environment-main-plan.yaml @@ -33,6 +33,7 @@ jobs: aws_region="${{ vars.AWS_REGION }}" state_bucket="${{ vars.STATE_BUCKET }}" environment="${{ vars.ENVIRONMENT }}" + saml_metadata_url="${{ secrets.SAML_METADATA_URL }}" backend_config: bucket=${{ vars.STATE_BUCKET }} key=${{ vars.ENVIRONMENT }}/terraform.tfstate diff --git a/README.md b/README.md index 6614be4b..632ca5ce 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,8 @@ Wildsea companion app * Add `token = ""` to the vars file * Add `workspace = ""` to the vars file * Run `.AWS_PROFILE= ./terraform/environment/github/deploy.sh ` - * Install into the repo +* Go into the two environments, and set a secret called `SAML_METADATA_URL` with the metadata URL for you SAML (See Jumpcloud for an example) To automate: @@ -42,3 +42,42 @@ To automate: * Enable everything except Dependabot version updates * Set up CodeQL to default * Set the Protection rules to Any/Any + +## Jumpcloud + +To integrate with Jumpcloud as your SAML Provider, get the output User Pool Id +and domain, and: + +* Log into Jumpcloud as an admin +* Go to "SSO Applications" under "User Authentication" +* "+ Add new application" +* Search for and select "Cognito" +* "Next" +* Display Label: Wildsea +* Description: Wildsea character sheets +* Use Portal Image: Color Indicator: Green +* Tick "Show this application in User Portal" +* You do not need to set any advanced settings +* Save Application +* Configure Application +* Modify the SP Entity IDm replacing `YOUR_USER_POOL_ID` with the id you got earlier +* In the ACS URLs, change the value to `http:///saml2/idpresponse`, using the domain you obtained earlier +* Set the Login URL to the URL of the app (see the graphql url output) +* Copy the metadata URL for later +* Go to the "User Groups" tab +* Select the user groups for access +* "Save" +* Go back to "SSO Applications" under "User Authentication", and select the "Wildsea" application +* Go to the "SSO" tab +* Under "User Attribute Mapping", add the following attributes + * `email` = `email` (this may already be there) + * `firstname` = `firstname` + * `lastname` - `lastname` +* Under "Constant Attributes", add the attribute `emailVerified` = `true` +* Click "save" + +In the github repo, on both the environments, set the secret `SAML_METADATA_URL` +to the URL you got earlier. + +Since you require the details of the Cognito pool before creating the Jumpcloud +setup, you will need to re-run the deployment after adding the secrets. diff --git a/terraform/environment/aws/policy.tf b/terraform/environment/aws/policy.tf index b105578b..d088e923 100644 --- a/terraform/environment/aws/policy.tf +++ b/terraform/environment/aws/policy.tf @@ -29,6 +29,30 @@ data "aws_iam_policy_document" "ro" { "arn:${data.aws_partition.current.id}:dynamodb:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:table/${var.app_name}-${var.environment}" ] } + + statement { + sid = "CognitoIdp" + actions = [ + "cognito-idp:List*", + "cognito-idp:Describe*", + "cognito-idp:Get*", + ] + resources = [ + "arn:${data.aws_partition.current.id}:cognito-idp:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:userpool/${var.app_name}-${var.environment}", + ] + } + + statement { + sid = "CognitoIdentity" + actions = [ + "cognito-identity:List*", + "cognito-identity:Describe*", + "cognito-identity:Get*", + ] + resources = [ + "arn:${data.aws_partition.current.id}:cognito-idp:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:identitypool/${var.app_name}-${var.environment}", + ] + } } data "aws_iam_policy_document" "rw" { @@ -43,7 +67,7 @@ data "aws_iam_policy_document" "rw" { } statement { - sid = "DynamodbNoItem" + sid = "DynamodbNoItem" effect = "Deny" actions = [ "dynamodb:DeleteItem", @@ -67,6 +91,32 @@ data "aws_iam_policy_document" "rw" { "arn:${data.aws_partition.current.id}:dynamodb:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:table/${var.app_name}-${var.environment}" ] } + + statement { + sid = "CognitoIdp" + actions = [ + "cognito-idp:Create*", + "cognito-idp:Delete*", + "cognito-idp:TagResource", + "cognito-idp:UntagResource", + ] + resources = [ + "arn:${data.aws_partition.current.id}:cognito-idp:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:userpool/${var.app_name}-${var.environment}", + ] + } + statement { + sid = "CognitoIdentity" + actions = [ + "cognito-identity:Create*", + "cognito-identity:Update*", + "cognito-identity:Delete*", + "cognito-identity:TagResource", + "cognito-identity:UntagResource", + ] + resources = [ + "arn:${data.aws_partition.current.id}:cognito-idp:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:identitypool/${var.app_name}-${var.environment}", + ] + } } data "aws_iam_policy_document" "rw_boundary" { @@ -112,4 +162,37 @@ data "aws_iam_policy_document" "rw_boundary" { "arn:${data.aws_partition.current.id}:dynamodb:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:table/${var.app_name}-${var.environment}" ] } + + statement { + sid = "CognitoIdp" + actions = [ + "cognito-idp:List*", + "cognito-idp:Describe*", + "cognito-idp:Get*", + "cognito-idp:Create*", + "cognito-idp:Delete*", + "cognito-idp:TagResource", + "cognito-idp:UntagResource", + ] + resources = [ + "arn:${data.aws_partition.current.id}:cognito-idp:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:userpool/${var.app_name}-${var.environment}", + ] + } + + statement { + sid = "CognitoIdentity" + actions = [ + "cognito-identity:List*", + "cognito-identity:Describe*", + "cognito-identity:Get*", + "cognito-identity:Create*", + "cognito-identity:Update*", + "cognito-identity:Delete*", + "cognito-identity:TagResource", + "cognito-identity:UntagResource", + ] + resources = [ + "arn:${data.aws_partition.current.id}:cognito-idp:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:identitypool/${var.app_name}-${var.environment}", + ] + } } diff --git a/terraform/environment/wildsea/cognito.tf b/terraform/environment/wildsea/cognito.tf new file mode 100644 index 00000000..da76baae --- /dev/null +++ b/terraform/environment/wildsea/cognito.tf @@ -0,0 +1,81 @@ +resource "aws_cognito_user_pool" "cognito" { + name = local.prefix + + admin_create_user_config { + allow_admin_create_user_only = true + } +} + +resource "aws_cognito_identity_provider" "idp" { + user_pool_id = aws_cognito_user_pool.cognito.id + provider_name = "SAML" + provider_type = "SAML" + + provider_details = { + MetadataURL = var.saml_metadata_url + } + + attribute_mapping = { + email = "email" + email_verified = "emailVerified" + family_name = "lastname" + given_name = "firstname" + } +} + +resource "aws_cognito_user_pool_client" "cognito" { + name = local.prefix + user_pool_id = aws_cognito_user_pool.cognito.id + generate_secret = true + explicit_auth_flows = ["USER_PASSWORD_AUTH", "ALLOW_USER_PASSWORD_AUTH", "ALLOW_USER_SRP_AUTH"] + allowed_oauth_flows_user_pool_client = true + callback_urls = ["TODO"] + logout_urls = ["TODO"] + allowed_oauth_flows = ["code", "implicit"] + allowed_oauth_scopes = ["openid"] + supported_identity_providers = [aws_cognito_identity_provider.idp.provider_name] +} + +resource "aws_cognito_identity_pool" "cognito" { + identity_pool_name = local.prefix + allow_unauthenticated_identities = false + allow_classic_flow = false + + cognito_identity_providers { + client_id = aws_cognito_user_pool_client.cognito.id + provider_name = "cognito-idp.${data.aws_region.current.id}.${data.aws_partition.current.dns_suffix}/${aws_cognito_user_pool.cognito.id}" + server_side_token_check = true + } +} + +resource "aws_cognito_identity_pool_roles_attachment" "cognito" { + identity_pool_id = aws_cognito_identity_pool.cognito.id + roles = { + "authenticated" = "TODO" + } +} + +resource "aws_cognito_user_pool_domain" "cognito" { + domain = local.prefix + user_pool_id = aws_cognito_user_pool.cognito.id +} + +output "user_pool_id" { + description = "Cognito User Pool ID" + value = aws_cognito_user_pool.cognito.id +} + +output "identity_pool_id" { + description = "Cognito Identity Pool ID" + value = aws_cognito_identity_pool.cognito.id +} + +output "web_client_id" { + description = "Cognito Web Client ID" + value = aws_cognito_user_pool_client.cognito.id +} + +output "login_domain" { + description = "Cognito Login Domain" + value = nonsensitive(sensitive("${aws_cognito_user_pool_domain.cognito.domain}.auth.${data.aws_region.current.id}.${data.aws_partition.current.dns_suffix}")) +} \ No newline at end of file diff --git a/terraform/environment/wildsea/main.tf b/terraform/environment/wildsea/main.tf index ee702487..a570694a 100644 --- a/terraform/environment/wildsea/main.tf +++ b/terraform/environment/wildsea/main.tf @@ -1,3 +1,7 @@ +data "aws_region" "current" {} +data "aws_partition" "current" {} +data "aws_caller_identity" "current" {} + variable "aws_account" { description = "ID of the AWS Account" type = string @@ -20,6 +24,13 @@ variable "environment" { type = string } +variable "saml_metadata_url" { + description = "SAML Metadata URL" + type = string + sensitive = true + default = "TODO" +} + locals { app_name = "Wildsea" prefix = "${local.app_name}-${var.environment}"