Installing Code-server with EC2 and Podman (integrate with Cognito) (PART 2)
Integrating Amazon Cognito User Pool with Code-Server on EC2 and Podman (PART 2)
Table of Contents
1. Background
In a previous article, I walked through the installation of code-server on an EC2 instance using Podman. While this setup is functional, it has some significant drawbacks when it comes to security:
- Single Password Authentication: The code-server relies on a single password stored in a configuration file. This is not a secure or scalable method to manage authentication.
- Lack of Multi-Factor Authentication (MFA): The setup does not support MFA, increasing the risk of unauthorized access.
- Limited Security Controls: Advanced security features such as user management, password policies, and integration with identity providers are missing.
These limitations make the setup unsuitable for production-grade environments, especially for teams or organizations highly concerned about security.
2. Proposed Solution: Integrating Amazon Cognito
To address these issues, we can integrate Amazon Cognito User Pools with the code-server setup. Amazon Cognito provides a robust and scalable authentication solution with the following features:
- Secure Authentication: Amazon Cognito handles authentication and authorization for users.
- Multi-Factor Authentication (MFA): Adds an extra layer of security by requiring users to authenticate with a second factor (e.g., SMS, TOTP).
- Social Login and Identity Provider Integration: Cognito supports social logins (e.g., Google, Facebook) and third-party identity providers using SAML or OpenID Connect (OIDC).
- Secure Password Policies: Enforces password complexity and expiration policies for enhanced security.
By integrating Cognito, we can offload the authentication responsibility from our application and benefit from its secure, managed authentication flow. In this article, I’ll explore how Cognito fits into the architecture and enhances the security of our code-server setup.
3. Architecture Diagram
The architecture remains similar to the previous setup, with the addition of Amazon Cognito for user authentication. Here’s a high-level overview:
- EC2 Instance: Hosts the code-server running in a Podman container.
- Application Load Balancer (ALB): Routes traffic to the EC2 instance and integrates with Cognito for authentication.
- Amazon Cognito User Pool: Manages user authentication and provides secure sign-in options.

At this point, I assume that you have following the previous article to setup the ALB and ACM. This means that you have already setup the a domain name and a HTTPS certificate for the ALB.
4. Create Cognito User Pool
Step 1: Create a User Pool
1. Navigate to the Amazon Cognito console.
2. Click on Create a user pool.
3. Configure the user pool settings, such as password policies and MFA options.

Step 2: Define a Client App and Configure Sign-In Options
1. After creating the user pool, define an App Client.
2. Choose Traditional Web Application in application type.
3. Configure the sign-in options, such as email or phone number.

Step 3: Maintain Login Callback URL in Cognito
1. Add the callback URL for your code-server application client. This URL is where Cognito will redirect users after successful authentication.
2. For Allowed callback URLs add: https://your-code-server-domain/oauth2/idpresponse
3. Under "Allowed OAuth Flows" select: Authorization code grant
4. Under "Allowed OAuth Scopes" select: openid, email ,profile

5. Setup ALB
Step 1: Add a Rule in ALB
1. Navigate to the AWS Management Console and open the EC2 Dashboard.
2. Select your Application Load Balancer (ALB).
3. Add a new listener rule to forward traffic to your EC2 instance.

Step 2: Add ALB Action for Cognito Authentication
1. In the ALB listener rule, add an action to authenticate users via Cognito.
2. Select the Cognito user pool and the code-server app client you created earlier.

6. Testing of Setup
Step 1: Create user and Test Sign-In on Cognito Page
1. Go to AWS Cognito console, creat a user in the Cognito user pool.
2. Open your browser and navigate to the code-server URL.
3. You should be redirected to the Cognito sign-in page.
4. Enter your credentials and complete the authentication process.

Step 2: Test Sign-In on Code-Server Page
1. After successful authentication, you should be redirected to the code-server interface.
2. Verify that you can access the code-server without any issues.

7. Other Useful AWS Services
To further enhance your development environment, consider integrating the following AWS services:
Amazon EFS (Elastic File System)
- Use EFS to share common resources (e.g., libraries, configuration files) across multiple developers or containers.
- Example: Mount an EFS volume to the Podman container running code-server to persist data across restarts.
Amazon ECR (Elastic Container Registry)
- Store standardized Podman images in ECR to ensure developers are using verified and secure container images.
- This reduces the risk of using untrusted public images and provides a centralized location for managing container versions.
Amazon CloudWatch
- Monitor the code-server container's performance using CloudWatch, including metrics like memory and CPU usage.
- Set up CloudWatch Alarms to notify you if resource usage exceeds predefined thresholds, helping optimize costs and detect potential issues early.
8. Conclusion and Summary
Integrating Amazon Cognito User Pool with code-server on EC2 and Podman significantly enhance the security and usability of your development environment. This setup is particularly beneficial for small teams or startups looking for a cost-effective and secure cloud-based development solution.
By leveraging Cognito, you can add multi-factor authentication (MFA), user management, and social login capabilities to your code-server setup. Additionally, integrating other AWS services like EFS, ECR, and CloudWatch can further streamline your development workflow.
By adopting this architecture, you can focus on writing code while AWS handles the tasks of authentication, resource sharing, and monitoring.