From a2857d56e027d1d2d1a025af11f4570d595d002a Mon Sep 17 00:00:00 2001 From: James Kolpack Date: Sun, 30 Nov 2025 23:55:34 -0500 Subject: [PATCH] Auth configuration in docker --- .gitignore | 5 + DEPLOYMENT.md | 279 +++++++++++++++++++++++++++++++++++++ WebApp/Program.cs | 14 ++ auth-secrets.example.json | 18 +++ docker-compose.example.yml | 40 ++++++ 5 files changed, 356 insertions(+) create mode 100644 DEPLOYMENT.md create mode 100644 auth-secrets.example.json create mode 100644 docker-compose.example.yml diff --git a/.gitignore b/.gitignore index f5cd2f6..054343b 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,8 @@ _ReSharper*/ DataBackup/ *.db /.claude/* + +# Production secrets and configuration +auth-secrets.json +docker-compose.yml +docker-compose.override.yml diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..0529e04 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,279 @@ +# Docker Deployment Guide + +## Authentication Configuration for Production + +The application supports two methods for configuring authentication credentials in Docker: + +### Option 1: Volume-Mounted JSON File (Recommended) + +This approach allows you to edit credentials without rebuilding the container. + +**Steps:** + +1. **Generate Password Hashes** (on your development machine): + ```bash + # Run the app locally and navigate to: + https://localhost:/dev/hash-password?password=YourPassword + ``` + +2. **Create `auth-secrets.json`** on your Docker host: + ```bash + cp auth-secrets.example.json auth-secrets.json + ``` + +3. **Edit `auth-secrets.json`** and replace the placeholder hashes: + ```json + { + "Authentication": { + "Users": [ + { + "Email": "admin@example.com", + "PasswordHash": "$2a$11$actual.hash.here", + "Role": "Administrator", + "DisplayName": "Administrator" + } + ] + } + } + ``` + +4. **Mount the file in Docker Compose**: + ```yaml + volumes: + - ./auth-secrets.json:/app/secrets/auth-secrets.json:ro + ``` + +5. **Update credentials**: Simply edit `auth-secrets.json` on the host and restart the container: + ```bash + docker-compose restart webapp + ``` + +**Security Note**: Set proper file permissions on the host: +```bash +chmod 600 auth-secrets.json +``` + +--- + +### Option 2: Environment Variables + +This approach is useful for container orchestration platforms (Kubernetes, Docker Swarm, etc.). + +**Docker Compose Example**: +```yaml +environment: + - TSA_Authentication__Users__0__Email=admin@example.com + - TSA_Authentication__Users__0__PasswordHash=$2a$11$hash... + - TSA_Authentication__Users__0__Role=Administrator + - TSA_Authentication__Users__0__DisplayName=Administrator + - TSA_Authentication__Users__1__Email=advisor@example.com + - TSA_Authentication__Users__1__PasswordHash=$2a$11$hash... + - TSA_Authentication__Users__1__Role=Advisor + - TSA_Authentication__Users__1__DisplayName=Chapter Advisor +``` + +**Docker Run Example**: +```bash +docker run -d \ + -p 8080:8080 \ + -e ASPNETCORE_ENVIRONMENT=Production \ + -e TSA_Authentication__Users__0__Email=admin@example.com \ + -e TSA_Authentication__Users__0__PasswordHash='$2a$11$hash...' \ + -e TSA_Authentication__Users__0__Role=Administrator \ + -e TSA_Authentication__Users__0__DisplayName=Administrator \ + tsa-chapter-organizer:latest +``` + +**Kubernetes Secret Example**: +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: tsa-auth-secrets +type: Opaque +stringData: + TSA_Authentication__Users__0__Email: "admin@example.com" + TSA_Authentication__Users__0__PasswordHash: "$2a$11$hash..." + TSA_Authentication__Users__0__Role: "Administrator" + TSA_Authentication__Users__0__DisplayName: "Administrator" +``` + +--- + +## Building and Running + +### Build the Docker Image + +```bash +cd WebApp +docker build -t tsa-chapter-organizer:latest . +``` + +### Run with Docker Compose + +```bash +# Copy and customize the example +cp docker-compose.example.yml docker-compose.yml + +# Edit auth-secrets.json with your credentials +cp auth-secrets.example.json auth-secrets.json +# (Edit the file and replace hashes) + +# Start the container +docker-compose up -d + +# View logs +docker-compose logs -f webapp +``` + +### Access the Application + +- HTTP: `http://localhost:8080` +- HTTPS: `https://localhost:8081` (if configured) + +--- + +## Managing Users + +### Adding a New User + +**With Volume-Mounted File:** +1. Edit `auth-secrets.json` on the host +2. Add new user entry to the `Users` array +3. Restart the container: `docker-compose restart webapp` + +**With Environment Variables:** +1. Add new environment variables (increment the index number) +2. Recreate the container: `docker-compose up -d` + +### Changing a Password + +1. Generate new hash using the dev endpoint (on local dev machine) +2. Update the `PasswordHash` value in your configuration +3. Restart/recreate the container + +### Removing a User + +1. Remove the user entry from your configuration +2. Restart/recreate the container + +--- + +## Security Considerations + +1. **File Permissions**: + ```bash + chmod 600 auth-secrets.json + chown root:root auth-secrets.json + ``` + +2. **Never Commit Secrets**: Add to `.gitignore`: + ``` + auth-secrets.json + docker-compose.yml + ``` + +3. **Use HTTPS in Production**: Configure SSL/TLS certificates + +4. **Backup Credentials**: Store encrypted backups of `auth-secrets.json` + +5. **Password Rotation**: Periodically regenerate password hashes + +6. **Monitor Access**: Review application logs for failed login attempts: + ```bash + docker-compose logs webapp | grep "Failed login" + ``` + +--- + +## Troubleshooting + +### Container Won't Start + +Check logs: +```bash +docker-compose logs webapp +``` + +### Can't Login + +1. Verify `auth-secrets.json` is properly mounted: + ```bash + docker exec tsa-app ls -la /app/secrets/ + ``` + +2. Check if the file is being loaded: + ```bash + docker-compose logs webapp | grep "secrets" + ``` + +3. Verify JSON syntax: + ```bash + cat auth-secrets.json | jq . + ``` + +### Forgot Admin Password + +1. Generate a new password hash locally +2. Update `auth-secrets.json` on the host +3. Restart the container + +--- + +## Example: Complete Setup + +```bash +# 1. Generate password hashes locally +# Navigate to: https://localhost:5001/dev/hash-password?password=MySecurePass123 + +# 2. Create secrets file +cat > auth-secrets.json <