code-server/terraform/SAML-SETUP-GUIDE.md
Claude b8094ac6a0
Add comprehensive Terraform infrastructure for code-server deployment on AWS
This commit adds complete Terraform infrastructure as code for deploying
code-server on both EC2 and EKS platforms with enterprise-grade security
and SAML/OIDC authentication.

Features:
- EC2 deployment with Auto Scaling Groups and Application Load Balancer
- EKS deployment with managed node groups and AWS Load Balancer Controller
- Private network setup with VPC, private subnets, and NAT gateways
- SAML/OIDC authentication using OAuth2 Proxy
- Security hardening:
  - KMS encryption for data at rest
  - TLS encryption in transit
  - IAM roles with least privilege
  - Security groups with minimal access
  - VPC Flow Logs
  - IMDSv2 enforcement
- Auto-scaling capabilities for both EC2 and EKS
- CloudWatch logging and monitoring
- Automated deployment scripts

Terraform Modules:
- modules/vpc: VPC with public/private subnets, NAT, and VPC endpoints
- modules/security: Security groups, IAM roles, and KMS keys
- modules/ec2: EC2 Auto Scaling deployment with ALB
- modules/eks: EKS cluster with managed node groups and addons

Deployments:
- deployments/ec2: EC2 deployment configuration
- deployments/eks: EKS deployment configuration with Kubernetes manifests

Documentation:
- README.md: Comprehensive deployment and operations guide
- QUICK-START.md: Quick reference for fast deployment
- SAML-SETUP-GUIDE.md: Step-by-step IdP configuration guide

Scripts:
- scripts/deploy-ec2.sh: Automated EC2 deployment
- scripts/deploy-eks.sh: Automated EKS deployment
- scripts/destroy-ec2.sh: EC2 cleanup
- scripts/destroy-eks.sh: EKS cleanup
2025-11-15 17:29:42 +00:00

12 KiB

SAML/OIDC Authentication Setup Guide

This guide provides step-by-step instructions for configuring various identity providers with code-server deployment.

Table of Contents

Overview

The code-server deployment uses OAuth2 Proxy to provide authentication via SAML/OIDC. This acts as a reverse proxy that handles authentication before requests reach code-server.

Key Concepts

  • OIDC Discovery URL: Endpoint that provides IdP configuration
  • Client ID: Unique identifier for your application
  • Client Secret: Secret key for authentication
  • Redirect URI: URL where users return after authentication
  • Cookie Secret: Secret for encrypting session cookies

Okta Setup

1. Create Application in Okta

  1. Log in to your Okta admin console
  2. Navigate to ApplicationsApplications
  3. Click Create App Integration
  4. Select:
    • Sign-in method: OIDC - OpenID Connect
    • Application type: Web Application
  5. Click Next

2. Configure Application

General Settings:

  • App integration name: Code-Server
  • Logo: (optional) Upload code-server logo

Sign-in redirect URIs:

https://code-server.example.com/oauth2/callback

Sign-out redirect URIs:

https://code-server.example.com

Assignments:

  • Controlled access: Choose who can access (Everyone, specific groups, etc.)

Click Save

3. Get Configuration Values

After creating the application:

  1. Copy Client ID
  2. Copy Client Secret (click "Show" if hidden)
  3. Note your Okta domain (e.g., dev-12345.okta.com)

4. Configure Terraform Variables

# terraform.tfvars

oauth2_issuer_url    = "https://dev-12345.okta.com/.well-known/openid-configuration"
oauth2_client_id     = "<YOUR_CLIENT_ID>"
oauth2_client_secret = "<YOUR_CLIENT_SECRET>"
oauth2_redirect_url  = "https://code-server.example.com/oauth2/callback"

# Generate cookie secret
# python -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())'
oauth2_cookie_secret = "<GENERATED_SECRET>"

# Optional: Restrict to specific users
oauth2_allowed_emails = [
  "user1@company.com",
  "user2@company.com"
]

5. Assign Users

In Okta admin console:

  1. Go to ApplicationsCode-Server
  2. Click Assignments tab
  3. Click AssignAssign to People or Assign to Groups
  4. Add users/groups who should have access

Azure Active Directory Setup

1. Register Application

  1. Log in to Azure Portal
  2. Navigate to Azure Active DirectoryApp registrations
  3. Click New registration

2. Configure Application

Name: Code-Server Supported account types:

  • Single tenant (most common)
  • Or Multi-tenant if needed

Redirect URI:

  • Platform: Web
  • URL: https://code-server.example.com/oauth2/callback

Click Register

3. Configure Authentication

  1. Go to Authentication in left menu
  2. Under Implicit grant and hybrid flows, check:
    • ID tokens (used for implicit and hybrid flows)
  3. Under Advanced settings:
    • Allow public client flows: No
  4. Click Save

4. Create Client Secret

  1. Go to Certificates & secrets in left menu
  2. Click New client secret
  3. Description: Code-Server
  4. Expires: Choose duration (24 months recommended)
  5. Click Add
  6. Copy the secret value immediately (it won't be shown again)

5. API Permissions

  1. Go to API permissions in left menu
  2. Verify these permissions exist:
    • Microsoft Graph → openid
    • Microsoft Graph → profile
    • Microsoft Graph → email
  3. Click Grant admin consent (if you have admin rights)

6. Get Configuration Values

From Overview page:

  • Application (client) ID: Copy this
  • Directory (tenant) ID: Copy this

7. Configure Terraform Variables

# terraform.tfvars

oauth2_issuer_url    = "https://login.microsoftonline.com/<TENANT_ID>/v2.0/.well-known/openid-configuration"
oauth2_client_id     = "<APPLICATION_CLIENT_ID>"
oauth2_client_secret = "<CLIENT_SECRET>"
oauth2_redirect_url  = "https://code-server.example.com/oauth2/callback"
oauth2_cookie_secret = "<GENERATED_SECRET>"

# Optional: Restrict by email
oauth2_allowed_emails = [
  "user1@company.com",
  "user2@company.com"
]

8. Restrict Access (Optional)

To limit access to specific users/groups:

  1. Go to Enterprise applications
  2. Find your Code-Server application
  3. Go to Properties
  4. Set User assignment required? to Yes
  5. Go to Users and groups
  6. Click Add user/group
  7. Select users or groups

Google Workspace Setup

1. Create OAuth Client

  1. Go to Google Cloud Console
  2. Select or create a project
  3. Navigate to APIs & ServicesCredentials
  4. Click Create CredentialsOAuth client ID

If prompted:

  1. Click Configure Consent Screen
  2. User Type: Internal (for Google Workspace) or External
  3. Fill in application information:
    • App name: Code-Server
    • User support email: Your email
    • Developer contact: Your email
  4. Scopes: Add openid, email, profile
  5. Click Save and Continue

3. Create OAuth Client ID

Application type: Web application

Name: Code-Server

Authorized redirect URIs:

https://code-server.example.com/oauth2/callback

Click Create

4. Get Configuration Values

After creation:

  • Copy Client ID
  • Copy Client Secret

5. Configure Terraform Variables

# terraform.tfvars

oauth2_issuer_url    = "https://accounts.google.com/.well-known/openid-configuration"
oauth2_client_id     = "<YOUR_CLIENT_ID>.apps.googleusercontent.com"
oauth2_client_secret = "<YOUR_CLIENT_SECRET>"
oauth2_redirect_url  = "https://code-server.example.com/oauth2/callback"
oauth2_cookie_secret = "<GENERATED_SECRET>"

# Restrict to your domain
oauth2_allowed_emails = [
  "user1@company.com",
  "user2@company.com"
]

6. Domain Restriction (Google Workspace)

To restrict to your entire domain:

# For EKS: k8s/oauth2-proxy.yaml
# Add to ConfigMap:
email_domains = ["company.com"]

AWS IAM Identity Center (SSO) Setup

1. Enable IAM Identity Center

  1. Go to IAM Identity Center
  2. Enable IAM Identity Center if not already enabled
  3. Note your AWS access portal URL

2. Register Application

  1. In IAM Identity Center, go to Applications
  2. Click Add application
  3. Select I have an application I want to set up
  4. Click Next

3. Configure Application

Display name: Code-Server

Description: Code-Server IDE

Application start URL: https://code-server.example.com

Application metadata:

  • Choose Manual entry
  • Application ACS URL: https://code-server.example.com/oauth2/callback
  • Application SAML audience: https://code-server.example.com

Click Submit

4. Get Configuration Values

  1. Download the IAM Identity Center SAML metadata file
  2. Note the Client ID (from application details)
  3. Create a Client Secret (in application settings)

5. Configure Terraform Variables

# terraform.tfvars

# Use OIDC endpoint for your region
oauth2_issuer_url    = "https://portal.sso.<region>.amazonaws.com/.well-known/openid-configuration"
oauth2_client_id     = "<YOUR_CLIENT_ID>"
oauth2_client_secret = "<YOUR_CLIENT_SECRET>"
oauth2_redirect_url  = "https://code-server.example.com/oauth2/callback"
oauth2_cookie_secret = "<GENERATED_SECRET>"

6. Assign Users

  1. Go to Assigned users tab
  2. Click Assign users
  3. Select users or groups
  4. Click Assign users

Generic OIDC Provider

For any OIDC-compliant provider:

1. Required Information

Obtain from your IdP:

  • OIDC Discovery URL (usually https://idp.example.com/.well-known/openid-configuration)
  • Client ID
  • Client Secret
  • Supported scopes (typically openid, profile, email)

2. Register Redirect URI

In your IdP, register:

https://code-server.example.com/oauth2/callback

3. Configure Terraform Variables

# terraform.tfvars

oauth2_issuer_url    = "<OIDC_DISCOVERY_URL>"
oauth2_client_id     = "<CLIENT_ID>"
oauth2_client_secret = "<CLIENT_SECRET>"
oauth2_redirect_url  = "https://code-server.example.com/oauth2/callback"
oauth2_cookie_secret = "<GENERATED_SECRET>"

Testing Authentication

1. Deploy Application

# EC2
cd deployments/ec2
terraform apply

# EKS
cd deployments/eks
terraform apply
kubectl apply -f k8s/oauth2-proxy.yaml

2. Access Application

Navigate to your code-server URL (e.g., https://code-server.example.com)

3. Expected Flow

  1. Browser redirects to IdP login page
  2. Enter credentials and authenticate
  3. IdP redirects back to code-server with authorization code
  4. OAuth2 Proxy exchanges code for tokens
  5. Session cookie is set
  6. Request is proxied to code-server
  7. Code-server interface loads

4. Verify Session

After successful login:

  • Check browser cookies for _oauth2_proxy cookie
  • Cookie should be HttpOnly, Secure, and SameSite

5. Test Logout

Navigate to: https://code-server.example.com/oauth2/sign_out

You should be logged out and redirected to IdP

Troubleshooting

Common Issues

Redirect URI Mismatch

Error: redirect_uri_mismatch or similar

Solution:

  1. Verify redirect URI in IdP exactly matches Terraform configuration
  2. Check for trailing slashes (should not have them)
  3. Ensure HTTPS (not HTTP)

Invalid Client

Error: invalid_client

Solution:

  1. Verify Client ID is correct
  2. Verify Client Secret is correct and not expired
  3. Check that client is enabled in IdP

Error: Authentication succeeds but session is not maintained

Solution:

  1. Ensure oauth2_cookie_secret is set and is 32 bytes (base64 encoded)
  2. Verify domain in cookie matches your URL
  3. Check browser is accepting cookies
  4. Ensure HTTPS is configured (cookies may not work over HTTP)

Access Denied

Error: User authenticates but gets "Access Denied"

Solution:

  1. Check oauth2_allowed_emails list
  2. Verify user is assigned to application in IdP
  3. Check OAuth2 Proxy logs:
    # EC2
    aws logs tail /aws/ec2/<prefix>-code-server --filter-pattern oauth2-proxy
    
    # EKS
    kubectl logs -n code-server -l app=oauth2-proxy
    

Issuer URL Not Accessible

Error: error fetching OIDC discovery

Solution:

  1. Verify issuer URL is accessible from your network
  2. Check security groups allow outbound HTTPS
  3. Verify URL is correct (test in browser)
  4. Check for typos in URL

Debug Mode

Enable debug logging:

EC2:

Edit modules/ec2/user-data.sh and add to oauth2-proxy args:

- --log-level=debug

EKS:

Edit deployments/eks/k8s/oauth2-proxy.yaml:

args:
  - --log-level=debug

Testing Connectivity

Test OIDC Discovery:

curl -s https://your-idp.com/.well-known/openid-configuration | jq .

Test Redirect:

# Should show OAuth2 login page
curl -I https://code-server.example.com

Check OAuth2 Proxy Health:

# EC2
curl http://<instance-ip>:4180/ping

# EKS
kubectl port-forward -n code-server svc/oauth2-proxy 4180:4180
curl http://localhost:4180/ping

Security Best Practices

  1. Use HTTPS: Always use HTTPS for production
  2. Rotate Secrets: Regularly rotate client secrets and cookie secrets
  3. Limit Scope: Request only necessary OIDC scopes
  4. Session Timeout: Configure appropriate session expiry
  5. Restrict Emails: Use oauth2_allowed_emails to limit access
  6. Monitor Logs: Regularly review authentication logs
  7. Use Groups: Manage access via IdP groups rather than individual users

Additional Resources