{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::Serverless-2016-10-31",
  "Outputs": {
    "RestAPIId": {
      "Value": {
        "Ref": "RestAPI"
      }
    },
    "APIHandlerName": {
      "Value": {
        "Ref": "APIHandler"
      }
    },
    "APIHandlerArn": {
      "Value": {
        "Fn::GetAtt": [
          "APIHandler",
          "Arn"
        ]
      }
    },
    "EndpointURL": {
      "Value": {
        "Fn::Sub": "https://${RestAPI}.execute-api.${AWS::Region}.${AWS::URLSuffix}/oidc/"
      }
    },
    "IssuerURL": {
      "Value": {
        "Fn::Sub": "https://${RestAPI}.execute-api.${AWS::Region}.${AWS::URLSuffix}/oidc"
      }
    },
    "AuthorizationURL": {
      "Value": {
        "Fn::Sub": "https://${RestAPI}.execute-api.${AWS::Region}.${AWS::URLSuffix}/oidc/authorize"
      }
    },
    "TokenURL": {
      "Value": {
        "Fn::Sub": "https://${RestAPI}.execute-api.${AWS::Region}.${AWS::URLSuffix}/oidc/token"
      }
    },
    "UserInfoURL": {
      "Value": {
        "Fn::Sub": "https://${RestAPI}.execute-api.${AWS::Region}.${AWS::URLSuffix}/oidc/userInfo"
      }
    },
    "PublicKeysURL": {
      "Value": {
        "Fn::Sub": "https://${RestAPI}.execute-api.${AWS::Region}.${AWS::URLSuffix}/oidc/.well-known/jwks.json"
      }
    },
    "ConfigurationURL": {
      "Value": {
        "Fn::Sub": "https://${RestAPI}.execute-api.${AWS::Region}.${AWS::URLSuffix}/oidc/.well-known/openid-configuration"
      }
    },
    "ClientID": {
      "Value": {
        "Fn::Sub": "${EventID}"
      }
    },
    "ClientSecretID": {
      "Value": {
        "Fn::Sub": "${AWS::StackName}/client_secret"
      }
    },
    "WaitingRoomWebContentBucket": {
      "Value": {
        "Fn::Sub": "${OpenIDWebContentBucket}"
      }
    }
  },
  "Resources": {
    "DefaultRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "",
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        },
        "Policies": [
          {
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Sid": "e74c1fd6fae1d4af2dc0c7b3f7d87f5d051e8fe5",
                  "Action": "s3:*",
                  "Effect": "Deny",
                  "Resource": "arn:aws:s3:::*",
                  "Condition": {
                    "StringNotEquals": {
                      "s3:ResourceAccount": {
                        "Fn::Sub": "${AWS::AccountId}"
                      }
                    }
                  }
                },
                {
                  "Effect": "Allow",
                  "Action": [
                    "secretsmanager:GetRandomPassword"
                  ],
                  "Resource": "*",
                  "Sid": "7f4d0d18346e0a497d35bb42c95877d2f7f2708e"
                },
                {
                  "Effect": "Allow",
                  "Action": [
                    "secretsmanager:GetSecretValue",
                    "secretsmanager:CreateSecret",
                    "secretsmanager:DeleteSecret"
                  ],
                  "Resource": [
                    {
                      "Fn::Sub": "arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:${AWS::StackName}/*"
                    }
                  ],
                  "Sid": "f2c267d1780ff10a49a7578694f091cdeb88c73a"
                },
                {
                  "Effect": "Allow",
                  "Action": [
                    "s3:PutObject",
                    "s3:ListBucket",
                    "s3:DeleteObject"
                  ],
                  "Resource": [
                    {
                      "Fn::GetAtt": [
                        "OpenIDWebContentBucket",
                        "Arn"
                      ]
                    },
                    {
                      "Fn::Join": [
                        "/",
                        [
                          {
                            "Fn::GetAtt": [
                              "OpenIDWebContentBucket",
                              "Arn"
                            ]
                          },
                          "*"
                        ]
                      ]
                    }
                  ],
                  "Sid": "1a85431c16a6568990f6dceb8c964199d651fa8c"
                },
                {
                  "Effect": "Allow",
                  "Action": [
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream",
                    "logs:DescribeLogGroups",
                    "logs:DescribeLogStreams",
                    "logs:PutLogEvents",
                    "logs:GetLogEvents",
                    "logs:FilterLogEvents"
                  ],
                  "Resource": {
                    "Fn::Sub": "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:*:*"
                  }
                },
                {
                  "Effect": "Allow",
                  "Action": [
                    "execute-api:Invoke"
                  ],
                  "Resource": "arn:aws:execute-api:*:*:*/*/POST/generate_token"
                }
              ]
            },
            "PolicyName": "DefaultRolePolicy"
          }
        ]
      },
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W11",
              "reason": "Resource * is required for the GetRandomPassword action."
            }
          ]
        },
        "guard": {
          "SuppressedRules": [
            "IAM_NO_INLINE_POLICY_CHECK"
          ]
        }
      }
    },
    "RestAPI": {
      "Type": "AWS::Serverless::Api",
      "Properties": {
        "EndpointConfiguration": "EDGE",
        "StageName": "oidc",
        "DefinitionBody": {
          "swagger": "2.0",
          "info": {
            "version": "1.0",
            "title": {
              "Fn::Sub": "${AWS::StackName}-openid-waiting-room-api"
            },
            "description": "Waiting Room Open ID Adapter API"
          },
          "schemes": [
            "https"
          ],
          "paths": {
            "/authorize": {
              "get": {
                "consumes": [
                  "application/json"
                ],
                "produces": [
                  "application/json"
                ],
                "responses": {
                  "200": {
                    "description": "200 response",
                    "schema": {
                      "$ref": "#/definitions/Empty"
                    }
                  }
                },
                "x-amazon-apigateway-integration": {
                  "responses": {
                    "default": {
                      "statusCode": "200"
                    }
                  },
                  "uri": {
                    "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${APIHandler.Arn}/invocations"
                  },
                  "passthroughBehavior": "when_no_match",
                  "httpMethod": "POST",
                  "contentHandling": "CONVERT_TO_TEXT",
                  "type": "aws_proxy"
                },
                "summary": "This is the authorize endpoint"
              }
            },
            "/token": {
              "post": {
                "consumes": [
                  "application/x-www-form-urlencoded"
                ],
                "produces": [
                  "application/json"
                ],
                "responses": {
                  "200": {
                    "description": "200 response",
                    "schema": {
                      "$ref": "#/definitions/Empty"
                    }
                  }
                },
                "x-amazon-apigateway-integration": {
                  "responses": {
                    "default": {
                      "statusCode": "200"
                    }
                  },
                  "uri": {
                    "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${APIHandler.Arn}/invocations"
                  },
                  "passthroughBehavior": "when_no_match",
                  "httpMethod": "POST",
                  "contentHandling": "CONVERT_TO_TEXT",
                  "type": "aws_proxy"
                },
                "summary": "This is the token endpoint"
              }
            },
            "/userInfo": {
              "get": {
                "consumes": [
                  "application/json"
                ],
                "produces": [
                  "application/json"
                ],
                "responses": {
                  "200": {
                    "description": "200 response",
                    "schema": {
                      "$ref": "#/definitions/Empty"
                    }
                  }
                },
                "x-amazon-apigateway-integration": {
                  "responses": {
                    "default": {
                      "statusCode": "200"
                    }
                  },
                  "uri": {
                    "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${APIHandler.Arn}/invocations"
                  },
                  "passthroughBehavior": "when_no_match",
                  "httpMethod": "POST",
                  "contentHandling": "CONVERT_TO_TEXT",
                  "type": "aws_proxy"
                },
                "summary": "This is the userInfo endpoint"
              }
            },
            "/.well-known/openid-configuration": {
              "get": {
                "consumes": [
                  "application/json"
                ],
                "produces": [
                  "application/json"
                ],
                "responses": {
                  "200": {
                    "description": "200 response",
                    "schema": {
                      "$ref": "#/definitions/Empty"
                    }
                  }
                },
                "x-amazon-apigateway-integration": {
                  "responses": {
                    "default": {
                      "statusCode": "200"
                    }
                  },
                  "uri": {
                    "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${APIHandler.Arn}/invocations"
                  },
                  "passthroughBehavior": "when_no_match",
                  "httpMethod": "POST",
                  "contentHandling": "CONVERT_TO_TEXT",
                  "type": "aws_proxy"
                },
                "summary": "This endpoint is used for auto-configuration of sites"
              }
            },
            "/.well-known/jwks.json": {
              "get": {
                "consumes": [
                  "application/json"
                ],
                "produces": [
                  "application/json"
                ],
                "responses": {
                  "200": {
                    "description": "200 response",
                    "schema": {
                      "$ref": "#/definitions/Empty"
                    }
                  }
                },
                "x-amazon-apigateway-integration": {
                  "responses": {
                    "default": {
                      "statusCode": "200"
                    }
                  },
                  "uri": {
                    "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${APIHandler.Arn}/invocations"
                  },
                  "passthroughBehavior": "when_no_match",
                  "httpMethod": "POST",
                  "contentHandling": "CONVERT_TO_TEXT",
                  "type": "aws_proxy"
                },
                "summary": "This endpoint is used for retrieval of public keys to verify tokens"
              }
            }
          },
          "definitions": {
            "Empty": {
              "type": "object",
              "title": "Empty Schema"
            }
          },
          "x-amazon-apigateway-binary-media-types": [
            "application/octet-stream",
            "application/x-tar",
            "application/zip",
            "audio/basic",
            "audio/ogg",
            "audio/mp4",
            "audio/mpeg",
            "audio/wav",
            "audio/webm",
            "image/png",
            "image/jpg",
            "image/jpeg",
            "image/gif",
            "video/ogg",
            "video/mpeg",
            "video/webm"
          ]
        },
        "AccessLogSetting": {
          "DestinationArn": {
            "Fn::GetAtt": [
              "ApiAccessLogGroup",
              "Arn"
            ]
          },
          "Format": "{ \"requestId\":\"$context.requestId\", \"ip\": \"$context.identity.sourceIp\", \"caller\":\"$context.identity.caller\", \"user\":\"$context.identity.user\",\"requestTime\":\"$context.requestTime\", \"httpMethod\":\"$context.httpMethod\",\"resourcePath\":\"$context.resourcePath\", \"status\":\"$context.status\",\"protocol\":\"$context.protocol\", \"responseLength\":\"$context.responseLength\" }"
        },
        "MethodSettings": [
          {
            "HttpMethod": "*",
            "LoggingLevel": "ERROR",
            "ResourcePath": "/*"
          }
        ]
      }
    },
    "APIHandler": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Runtime": "python3.12",
        "Handler": "app.app",
        "CodeUri": {
          "Bucket": {
            "Fn::Join": [
              "-",
              [
                {
                  "Fn::FindInMap": [
                    "SourceCode",
                    "General",
                    "S3Bucket"
                  ]
                },
                {
                  "Ref": "AWS::Region"
                }
              ]
            ]
          },
          "Key": {
            "Fn::Join": [
              "/",
              [
                {
                  "Fn::FindInMap": [
                    "SourceCode",
                    "General",
                    "KeyPrefix"
                  ]
                },
                "virtual-waiting-room-on-aws-openid-1758042144.zip"
              ]
            ]
          }
        },
        "Tags": {
          "aws-chalice": "version=1.31.2:stage=dev:app=openid-waitingroom"
        },
        "Tracing": "PassThrough",
        "Timeout": 60,
        "MemorySize": 1024,
        "Role": {
          "Fn::GetAtt": [
            "DefaultRole",
            "Arn"
          ]
        },
        "Environment": {
          "Variables": {
            "REDIRECT_URIS_SECRET_ID": {
              "Fn::Sub": "${AWS::StackName}/redirect_uris"
            },
            "WWW_RESOURCES_URL": {
              "Fn::Join": [
                "",
                [
                  "https://",
                  {
                    "Fn::GetAtt": [
                      "OpenIDWebContentCloudFront",
                      "DomainName"
                    ]
                  }
                ]
              ]
            },
            "WAITING_ROOM_EVENT_ID": {
              "Fn::Sub": "${EventID}"
            },
            "PUBLIC_API_ENDPOINT": {
              "Fn::Sub": "${PublicAPIEndpoint}"
            },
            "PRIVATE_API_ENDPOINT": {
              "Fn::Sub": "${PrivateAPIEndpoint}"
            },
            "CLIENT_SECRET_ID": {
              "Fn::Sub": "${AWS::StackName}/client_secret"
            },
            "API_REGION": {
              "Fn::Sub": "${APIRegion}"
            },
            "SOLUTION_ID": {
              "Fn::FindInMap": [
                "SolutionId",
                "UserAgent",
                "Extra"
              ]
            }
          }
        }
      },
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W89",
              "reason": "Lambda does not need to be in the Waiting Room VPC."
            },
            {
              "id": "W92",
              "reason": "Lambda does not require ReservedConcurrentExecutions."
            }
          ]
        }
      }
    },
    "APIHandlerInvokePermission": {
      "Type": "AWS::Lambda::Permission",
      "Properties": {
        "FunctionName": {
          "Ref": "APIHandler"
        },
        "Action": "lambda:InvokeFunction",
        "Principal": "apigateway.amazonaws.com",
        "SourceArn": {
          "Fn::Sub": [
            "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${RestAPIId}/*",
            {
              "RestAPIId": {
                "Ref": "RestAPI"
              }
            }
          ]
        }
      }
    },
    "ApiAccessLogGroup": {
      "Type": "AWS::Logs::LogGroup",
      "Properties": {
        "RetentionInDays": 30
      },
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W84",
              "reason": "Log group data is always encrypted in CloudWatch Logs. Using KMS to encrypt is optional."
            }
          ]
        }
      }
    },
    "4XXErrorOpenIDApiAlarm": {
      "Type": "AWS::CloudWatch::Alarm",
      "Properties": {
        "AlarmDescription": "4xx errors > 0",
        "ComparisonOperator": "GreaterThanThreshold",
        "EvaluationPeriods": 1,
        "DatapointsToAlarm": 1,
        "MetricName": "4XXError",
        "Namespace": "AWS/ApiGateway",
        "Dimensions": [
          {
            "Name": "ApiName",
            "Value": {
              "Fn::Sub": "${AWS::StackName}-openid-waiting-room-api"
            }
          }
        ],
        "Period": 60,
        "Statistic": "Maximum",
        "Threshold": 0,
        "TreatMissingData": "notBreaching"
      }
    },
    "5XXErrorOpenIDApiAlarm": {
      "Type": "AWS::CloudWatch::Alarm",
      "Properties": {
        "AlarmDescription": "5xx errors > 0",
        "ComparisonOperator": "GreaterThanThreshold",
        "EvaluationPeriods": 1,
        "DatapointsToAlarm": 1,
        "MetricName": "5XXError",
        "Namespace": "AWS/ApiGateway",
        "Dimensions": [
          {
            "Name": "ApiName",
            "Value": {
              "Fn::Sub": "${AWS::StackName}-openid-waiting-room-api"
            }
          }
        ],
        "Period": 60,
        "Statistic": "Maximum",
        "Threshold": 0,
        "TreatMissingData": "notBreaching"
      }
    },
    "APIHandlerErrorsAlarm": {
      "Type": "AWS::CloudWatch::Alarm",
      "Properties": {
        "AlarmDescription": "Errors > 0",
        "ComparisonOperator": "GreaterThanThreshold",
        "EvaluationPeriods": 1,
        "DatapointsToAlarm": 1,
        "MetricName": "Errors",
        "Namespace": "AWS/Lambda",
        "Dimensions": [
          {
            "Name": "FunctionName",
            "Value": {
              "Ref": "APIHandler"
            }
          }
        ],
        "Period": 60,
        "Statistic": "Maximum",
        "Threshold": 0,
        "TreatMissingData": "notBreaching"
      }
    },
    "APIHandlerThrottlesAlarm": {
      "Type": "AWS::CloudWatch::Alarm",
      "Properties": {
        "AlarmDescription": "Throttles > 0",
        "ComparisonOperator": "GreaterThanThreshold",
        "EvaluationPeriods": 1,
        "DatapointsToAlarm": 1,
        "MetricName": "Throttles",
        "Namespace": "AWS/Lambda",
        "Dimensions": [
          {
            "Name": "FunctionName",
            "Value": {
              "Ref": "APIHandler"
            }
          }
        ],
        "Period": 60,
        "Statistic": "Maximum",
        "Threshold": 0,
        "TreatMissingData": "notBreaching"
      }
    },
    "GenerateClientSecretFunction": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Runtime": "python3.12",
        "Handler": "generate_client_secret.handler",
        "CodeUri": {
          "Bucket": {
            "Fn::Join": [
              "-",
              [
                {
                  "Fn::FindInMap": [
                    "SourceCode",
                    "General",
                    "S3Bucket"
                  ]
                },
                {
                  "Ref": "AWS::Region"
                }
              ]
            ]
          },
          "Key": {
            "Fn::Join": [
              "/",
              [
                {
                  "Fn::FindInMap": [
                    "SourceCode",
                    "General",
                    "KeyPrefix"
                  ]
                },
                "virtual-waiting-room-on-aws-openid-custom-resources-1758042144.zip"
              ]
            ]
          }
        },
        "Tracing": "PassThrough",
        "Timeout": 60,
        "MemorySize": 1024,
        "Role": {
          "Fn::GetAtt": [
            "DefaultRole",
            "Arn"
          ]
        },
        "Environment": {
          "Variables": {
            "SOLUTION_ID": {
              "Fn::FindInMap": [
                "SolutionId",
                "UserAgent",
                "Extra"
              ]
            }
          }
        }
      },
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W89",
              "reason": "Lambda does not need to be in the Waiting Room VPC."
            },
            {
              "id": "W92",
              "reason": "Lambda does not require ReservedConcurrentExecutions."
            }
          ]
        }
      }
    },
    "GenerateClientSecretResource": {
      "Type": "AWS::CloudFormation::CustomResource",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": [
            "GenerateClientSecretFunction",
            "Arn"
          ]
        },
        "SecretPrefix": {
          "Ref": "AWS::StackName"
        },
        "Timestamp": "1758042144"
      }
    },
    "GenerateRedirectURIsSecretFunction": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Runtime": "python3.12",
        "Handler": "generate_redirect_uris_secret.handler",
        "CodeUri": {
          "Bucket": {
            "Fn::Join": [
              "-",
              [
                {
                  "Fn::FindInMap": [
                    "SourceCode",
                    "General",
                    "S3Bucket"
                  ]
                },
                {
                  "Ref": "AWS::Region"
                }
              ]
            ]
          },
          "Key": {
            "Fn::Join": [
              "/",
              [
                {
                  "Fn::FindInMap": [
                    "SourceCode",
                    "General",
                    "KeyPrefix"
                  ]
                },
                "virtual-waiting-room-on-aws-openid-custom-resources-1758042144.zip"
              ]
            ]
          }
        },
        "Tracing": "PassThrough",
        "Timeout": 60,
        "MemorySize": 1024,
        "Role": {
          "Fn::GetAtt": [
            "DefaultRole",
            "Arn"
          ]
        },
        "Environment": {
          "Variables": {
            "SOLUTION_ID": {
              "Fn::FindInMap": [
                "SolutionId",
                "UserAgent",
                "Extra"
              ]
            }
          }
        }
      },
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W89",
              "reason": "Lambda does not need to be in the Waiting Room VPC."
            },
            {
              "id": "W92",
              "reason": "Lambda does not require ReservedConcurrentExecutions."
            }
          ]
        }
      }
    },
    "GenerateRedirectURIsSecretResource": {
      "Type": "AWS::CloudFormation::CustomResource",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": [
            "GenerateRedirectURIsSecretFunction",
            "Arn"
          ]
        },
        "SecretPrefix": {
          "Ref": "AWS::StackName"
        },
        "Timestamp": "1758042144"
      }
    },
    "BucketLoaderFunction": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Runtime": "python3.12",
        "Handler": "cfn_bucket_loader.handler",
        "CodeUri": {
          "Bucket": {
            "Fn::Join": [
              "-",
              [
                {
                  "Fn::FindInMap": [
                    "SourceCode",
                    "General",
                    "S3Bucket"
                  ]
                },
                {
                  "Ref": "AWS::Region"
                }
              ]
            ]
          },
          "Key": {
            "Fn::Join": [
              "/",
              [
                {
                  "Fn::FindInMap": [
                    "SourceCode",
                    "General",
                    "KeyPrefix"
                  ]
                },
                "virtual-waiting-room-on-aws-openid-custom-resources-1758042144.zip"
              ]
            ]
          }
        },
        "Tracing": "PassThrough",
        "Timeout": 60,
        "MemorySize": 1024,
        "Role": {
          "Fn::GetAtt": [
            "DefaultRole",
            "Arn"
          ]
        },
        "Environment": {
          "Variables": {
            "SOLUTION_ID": {
              "Fn::FindInMap": [
                "SolutionId",
                "UserAgent",
                "Extra"
              ]
            }
          }
        }
      },
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W89",
              "reason": "Lambda does not need to be in the Waiting Room VPC."
            },
            {
              "id": "W92",
              "reason": "Lambda does not require ReservedConcurrentExecutions."
            }
          ]
        }
      }
    },
    "BucketLoaderResource": {
      "Type": "AWS::CloudFormation::CustomResource",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": [
            "BucketLoaderFunction",
            "Arn"
          ]
        },
        "BucketName": {
          "Ref": "OpenIDWebContentBucket"
        },
        "APIs": {
          "public_api": {
            "Fn::Sub": "${PublicAPIEndpoint}"
          },
          "private_api": {
            "Fn::Sub": "${PrivateAPIEndpoint}"
          }
        },
        "Timestamp": "1758042144"
      }
    },
    "OpenIDWebContentBucketOAI": {
      "Type": "AWS::CloudFront::CloudFrontOriginAccessIdentity",
      "Properties": {
        "CloudFrontOriginAccessIdentityConfig": {
          "Comment": "OAI for Open ID web content"
        }
      }
    },
    "OpenIDWebContentCloudFront": {
      "Type": "AWS::CloudFront::Distribution",
      "Properties": {
        "DistributionConfig": {
          "Comment": "CDN for Open ID web content",
          "DefaultRootObject": "index.html",
          "DefaultCacheBehavior": {
            "TargetOriginId": "origin-www-bucket",
            "ForwardedValues": {
              "QueryString": false,
              "Cookies": {
                "Forward": "none"
              },
              "Headers": [
                "Origin",
                "Access-Control-Request-Method",
                "Access-Control-Request-Headers"
              ]
            },
            "ViewerProtocolPolicy": "redirect-to-https",
            "AllowedMethods": [
              "HEAD",
              "GET",
              "OPTIONS"
            ],
            "CachedMethods": [
              "HEAD",
              "GET",
              "OPTIONS"
            ],
            "Compress": true,
            "MinTTL": 0,
            "DefaultTTL": 30,
            "MaxTTL": 60
          },
          "Enabled": true,
          "Origins": [
            {
              "DomainName": {
                "Fn::Join": [
                  "",
                  [
                    {
                      "Ref": "OpenIDWebContentBucket"
                    },
                    {
                      "Fn::Sub": ".s3.${AWS::Region}.amazonaws.com"
                    }
                  ]
                ]
              },
              "Id": "origin-www-bucket",
              "S3OriginConfig": {
                "OriginAccessIdentity": {
                  "Fn::Join": [
                    "",
                    [
                      "origin-access-identity/cloudfront/",
                      {
                        "Ref": "OpenIDWebContentBucketOAI"
                      }
                    ]
                  ]
                }
              }
            }
          ],
          "ViewerCertificate": {
            "CloudFrontDefaultCertificate": true,
            "MinimumProtocolVersion": "TLSv1.2_2019"
          },
          "Logging": {
            "Bucket": {
              "Fn::Join": [
                "",
                [
                  {
                    "Ref": "OpenIDWebLoggingBucket"
                  },
                  ".s3.amazonaws.com"
                ]
              ]
            },
            "IncludeCookies": true,
            "Prefix": "cf/"
          }
        }
      },
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W70",
              "reason": "If the distribution uses the CloudFront domain name such as d111111abcdef8.cloudfront.net (you set CloudFrontDefaultCertificate to true), CloudFront automatically sets the security policy to TLSv1 regardless of the value that you set here."
            }
          ]
        }
      }
    },
    "OpenIDWebLoggingBucketPolicy": {
      "Type": "AWS::S3::BucketPolicy",
      "Properties": {
        "Bucket": {
          "Ref": "OpenIDWebLoggingBucket"
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Id": "PolicyForLoggingPrivateContent",
          "Statement": [
            {
              "Effect": "Deny",
              "Principal": "*",
              "Action": "s3:*",
              "Resource": [
                {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "OpenIDWebLoggingBucket",
                          "Arn"
                        ]
                      },
                      "/*"
                    ]
                  ]
                },
                {
                  "Fn::GetAtt": [
                    "OpenIDWebLoggingBucket",
                    "Arn"
                  ]
                }
              ],
              "Condition": {
                "Bool": {
                  "aws:SecureTransport": "false"
                }
              }
            }
          ]
        }
      }
    },
    "OpenIDWebContentBucketPolicy": {
      "Type": "AWS::S3::BucketPolicy",
      "Properties": {
        "Bucket": {
          "Ref": "OpenIDWebContentBucket"
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Id": "PolicyForCloudFrontPrivateContent",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "CanonicalUser": {
                  "Fn::GetAtt": [
                    "OpenIDWebContentBucketOAI",
                    "S3CanonicalUserId"
                  ]
                }
              },
              "Action": "s3:GetObject",
              "Resource": [
                {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "OpenIDWebContentBucket",
                          "Arn"
                        ]
                      },
                      "/*"
                    ]
                  ]
                }
              ]
            },
            {
              "Effect": "Deny",
              "Principal": "*",
              "Action": "s3:*",
              "Resource": [
                {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "OpenIDWebContentBucket",
                          "Arn"
                        ]
                      },
                      "/*"
                    ]
                  ]
                },
                {
                  "Fn::GetAtt": [
                    "OpenIDWebContentBucket",
                    "Arn"
                  ]
                }
              ],
              "Condition": {
                "Bool": {
                  "aws:SecureTransport": "false"
                }
              }
            }
          ]
        }
      }
    },
    "OpenIDWebContentBucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "CorsConfiguration": {
          "CorsRules": [
            {
              "AllowedHeaders": [
                "*"
              ],
              "AllowedMethods": [
                "GET"
              ],
              "AllowedOrigins": [
                "*"
              ]
            }
          ]
        },
        "BucketEncryption": {
          "ServerSideEncryptionConfiguration": [
            {
              "ServerSideEncryptionByDefault": {
                "SSEAlgorithm": "AES256"
              }
            }
          ]
        },
        "LoggingConfiguration": {
          "DestinationBucketName": {
            "Ref": "OpenIDWebLoggingBucket"
          },
          "LogFilePrefix": "www/"
        }
      }
    },
    "OpenIDWebLoggingBucket": {
      "Type": "AWS::S3::Bucket",
      "DeletionPolicy": "Retain",
      "UpdateReplacePolicy": "Retain",
      "Properties": {
        "AccessControl": "LogDeliveryWrite",
        "OwnershipControls": {
          "Rules": [
            {
              "ObjectOwnership": "ObjectWriter"
            }
          ]
        },
        "BucketEncryption": {
          "ServerSideEncryptionConfiguration": [
            {
              "ServerSideEncryptionByDefault": {
                "SSEAlgorithm": "AES256"
              }
            }
          ]
        },
        "LifecycleConfiguration": {
          "Rules": [
            {
              "AbortIncompleteMultipartUpload": {
                "DaysAfterInitiation": 5
              },
              "ExpirationInDays": 3650,
              "Id": "Expire Objects After 10 Years",
              "NoncurrentVersionExpirationInDays": 3650,
              "Status": "Enabled"
            }
          ]
        }
      },
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W35",
              "reason": "This is the logging bucket. No access logging needed."
            },
            {
              "id": "W51",
              "reason": "This is the logging bucket.  No bucket policy needed."
            }
          ]
        }
      }
    }
  },
  "Description": "(SO0166) Virtual Waiting Room on AWS OpenID Adapter v1.1.15",
  "Parameters": {
    "PublicAPIEndpoint": {
      "Description": "Public endpoint URL for the virtual waiting room APIs",
      "Type": "String"
    },
    "PrivateAPIEndpoint": {
      "Description": "Private endpoint URL for the virtual waiting room APIs",
      "Type": "String"
    },
    "APIRegion": {
      "Description": "AWS region name for the public and private waiting room APIs",
      "Type": "String"
    },
    "EventID": {
      "Description": "Event ID of waiting room",
      "Type": "String"
    }
  },
  "Mappings": {
    "SourceCode": {
      "General": {
        "S3Bucket": "solutions",
        "KeyPrefix": "virtual-waiting-room-on-aws/v1.1.15"
      }
    },
    "SolutionId": {
      "UserAgent": {
        "Extra": "AwsSolution/SO0166/v1.1.15"
      }
    }
  }
}
