feat: Update deployment configuration and production settings for Cloud Run#44
Conversation
WalkthroughDeployment configuration updated to pass port information via ASPNETCORE_URLS environment variable instead of explicit port exposure. Dockerfile modified to remove port exposure declarations and add application entrypoint. Production settings URL endpoint adjusted to point to deployed API. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
.github/workflows/deploy-gcloud.yml(3 hunks)src/Web.Api/Dockerfile(1 hunks)src/Web.Api/appsettings.Production.json(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-and-deploy
🔇 Additional comments (2)
src/Web.Api/Dockerfile (1)
26-27: LGTM. Dockerfile changes align with Cloud Run deployment model.Removing
EXPOSEdeclarations is appropriate for Cloud Run, where the port is controlled via theASPNETCORE_URLSenvironment variable instead of container metadata. Adding the explicitENTRYPOINTensures consistent application startup..github/workflows/deploy-gcloud.yml (1)
98-120: Note: Commented-out deployment block represents more secure pattern.The commented-out "Deploy to Cloud Run (Production)" section (lines 98-120) demonstrates a more secure deployment strategy where sensitive values (
ConnectionStrings__DefaultConnection,Email__SmtpPassword, etc.) are injected via environment variables at deployment time rather than stored in configuration files.The active deployment (lines 122-135) simplifies this to only set
ASPNETCORE_ENVIRONMENTandASPNETCORE_URLS, which means the application now relies on hardcoded values inappsettings.Production.json. This is a design trade-off that impacts security posture (credentials in version control) versus deployment simplicity.Clarify intent: Is this a permanent architectural change, or should the environment variable injection pattern be restored?
| --min-instances 0 \ | ||
| --port ${{ env.PORT }} \ | ||
| --set-env-vars "ASPNETCORE_ENVIRONMENT=Production" \ | ||
| --set-env-vars "ASPNETCORE_ENVIRONMENT=Production,ASPNETCORE_URLS=http://+:10000" \ |
There was a problem hiding this comment.
🧩 Analysis chain
CRITICAL: Deployment no longer injects sensitive values via environment variables.
Line 134 simplifies environment variable setup to only ASPNETCORE_ENVIRONMENT=Production,ASPNETCORE_URLS=http://+:10000. The previous pattern (commented-out lines 110-119) injected sensitive configuration via environment variables, which overrode config file values.
Impact: This change forces the application to use hardcoded values from appsettings.Production.json, including:
- Database credentials (plaintext password in
ConnectionStrings.DefaultConnection) - SMTP credentials (plaintext password in
Email.SmtpPassword) - Email settings
This creates a security and compliance risk: sensitive credentials are now stored in version control instead of being injected at deployment time.
Recommended fix:
- Restore the environment variable injection pattern from lines 110-119, OR
- Migrate secrets to Google Cloud Secret Manager and inject them at Cloud Run runtime
The ASPNETCORE_URLS=http://+:10000 addition is correct and should be retained.
Please confirm:
- Is this intentional or an unintended regression from the previous deployment strategy?
- Are there alternative mechanisms in place to inject secrets (e.g., Cloud Secret Manager)?
- Should the previous environment variable injection pattern be restored?
---
🏁 Script executed:
```shell
#!/bin/bash
# Examine the deploy-gcloud.yml workflow file, focusing on lines 110-140
cat .github/workflows/deploy-gcloud.yml | sed -n '100,145p' | nl -v 100
Length of output: 40
🏁 Script executed:
#!/bin/bash
# Search for appsettings files, especially Production variant
fd -e json -e jsonc | grep -i appsettingsLength of output: 109
🏁 Script executed:
#!/bin/bash
# Check for Cloud Secret Manager references in workflow files and infrastructure code
rg -i "secret.*manager|secret.*version" --type=yaml --type=json -C3Length of output: 0
🏁 Script executed:
#!/bin/bash
# Search for environment variable patterns in Cloud Run deployment configurations
rg -i "aspnetcore|connectionstring|smtp" --type=yaml -C2Length of output: 287
🏁 Script executed:
#!/bin/bash
# View deploy-gcloud.yml workflow file, lines 100-145
sed -n '100,145p' .github/workflows/deploy-gcloud.ymlLength of output: 2126
🏁 Script executed:
#!/bin/bash
# View appsettings.Production.json to check for hardcoded credentials
cat src/Web.Api/appsettings.Production.jsonLength of output: 637
🏁 Script executed:
#!/bin/bash
# Search the entire workflow file for set-env-vars and environment variable patterns
rg "set-env-vars|ASPNETCORE" .github/workflows/deploy-gcloud.yml -C3Length of output: 1432
CRITICAL: Deployment regression exposes plaintext credentials in version control.
Verification confirms the review comment is accurate and the issue is critical:
Confirmed findings:
- Lines 100-119 show commented-out deployment with proper secret injection (
${{ secrets.DB_CONNECTION_STRING }},${{ secrets.SMTP_PASSWORD }}, etc.) - Line 134 active deployment injects only
ASPNETCORE_ENVIRONMENT=Production,ASPNETCORE_URLS=http://+:10000 appsettings.Production.jsoncontains hardcoded plaintext credentials in version control:- Database password:
Admin@123 - SMTP password:
uomycajntiuixmki - Email and database configuration with credentials
- Database password:
- No Cloud Secret Manager integration exists as an alternative
This is an intentional regression from secure secret injection to file-based credential storage. Production deployments now depend on plaintext secrets in Git history.
Required action: Restore the secret injection pattern from lines 100-119 or migrate to Google Cloud Secret Manager for runtime secret injection.
| @@ -9,7 +9,7 @@ | |||
| "DefaultConnection": "Host=69.164.244.36;Database=law_chatbot;Username=postgres;Password=Admin@123;Port=5555" | |||
There was a problem hiding this comment.
🧩 Analysis chain
CRITICAL: Plaintext credentials exposed in production configuration file.
The database connection string (line 9) and SMTP credentials (lines 20-21) are hardcoded in plaintext. This violates security best practices and compliance standards (PII/secrets leakage).
- Line 9: PostgreSQL password in connection string
- Lines 20-21: SMTP password in plaintext
These sensitive values must never be stored in version control. Combined with the deployment workflow changes that no longer inject secrets via environment variables, this creates a significant security and compliance risk.
Please verify:
- Is this file
.gitignored? If not, credentials are exposed in the repository history. - Is there an external secret injection mechanism at Cloud Run runtime (e.g., Secret Manager)?
- Should credentials be injected via environment variables during deployment instead?
Consider reverting the deployment workflow to inject ConnectionStrings__DefaultConnection, Email__SmtpPassword, and Email__SmtpUsername via --set-env-vars as shown in the commented-out block (lines 98-120).
Also applies to: 20-21
I'll verify the security concerns raised in this review comment by examining the codebase for the relevant configuration, deployment, and secret management mechanisms.
🏁 Script executed:
#!/bin/bash
# Check .gitignore for appsettings file patterns
echo "=== Checking .gitignore for appsettings patterns ==="
if [ -f .gitignore ]; then
cat .gitignore | grep -E "(appsettings|\.json)" || echo "No appsettings patterns found in .gitignore"
else
echo ".gitignore not found"
fi
echo -e "\n=== Searching for .gitignore files in subdirectories ==="
find . -name ".gitignore" -type f 2>/dev/null | head -10Length of output: 381
🏁 Script executed:
#!/bin/bash
# Inspect appsettings.Production.json for credential exposure
echo "=== Contents of appsettings.Production.json ==="
if [ -f "src/Web.Api/appsettings.Production.json" ]; then
cat "src/Web.Api/appsettings.Production.json"
else
echo "File not found at expected location"
find . -name "appsettings.Production.json" -type f 2>/dev/null
fiLength of output: 685
🏁 Script executed:
#!/bin/bash
# Look for deployment workflow file mentioned in review
echo "=== Searching for deploy-gcloud.yml ==="
find . -name "deploy-gcloud.yml" -o -name "*deploy*" -type f | grep -E "\.(yml|yaml)$" | head -20Length of output: 77
🏁 Script executed:
#!/bin/bash
# Check for Cloud Run or Secret Manager configuration
echo "=== Searching for Cloud Run or Secret Manager references ==="
rg -i "(secret.?manager|cloud.?run|--set-env|SECRETS)" --type yaml --type json -C 3 | head -50Length of output: 60
I need to examine the deployment workflow to verify the secret handling mechanism and confirm if there's commented-out code for environment variable injection.
🏁 Script executed:
#!/bin/bash
# Examine the deploy-gcloud.yml workflow file
echo "=== Contents of deploy-gcloud.yml ==="
cat "./.github/workflows/deploy-gcloud.yml"Length of output: 7232
🏁 Script executed:
#!/bin/bash
# Search for any commented-out sections with env var patterns
echo "=== Searching for commented patterns with env vars in deploy workflow ==="
grep -n "^\s*#.*--set-env\|^\s*#.*ConnectionStrings\|^\s*#.*SmtpPassword" "./.github/workflows/deploy-gcloud.yml" || echo "No commented env var patterns found"Length of output: 892
🏁 Script executed:
#!/bin/bash
# Check if appsettings files are copied or included in deployment
echo "=== Searching for appsettings file references in deployment context ==="
rg -n "appsettings" "./.github/workflows/deploy-gcloud.yml" -C 2Length of output: 314
CRITICAL: Plaintext database and email credentials exposed in production configuration file and version control.
The credentials are hardcoded in plaintext in appsettings.Production.json and are not excluded from version control:
- Line 9: PostgreSQL password
Admin@123inDefaultConnectionstring - Line 22: SMTP password
uomycajntiuixmkiplaintext - Line 21: SMTP username plaintext
The .gitignore does not exclude appsettings*.json files, meaning credentials are exposed in the repository history.
Additionally, the deployment workflow (.github/workflows/deploy-gcloud.yml) has regressed: lines 100-119 show a commented-out deploy step that properly injected secrets via --set-env-vars with GitHub secrets references (${{ secrets.DB_CONNECTION_STRING }}, ${{ secrets.SMTP_USERNAME }}, ${{ secrets.SMTP_PASSWORD }}). The active production deploy step (lines 121-129) no longer performs this injection, relying entirely on the plaintext credentials in the configuration file.
Required fixes:
- Add
appsettings*.Production.jsonandappsettings*.Staging.jsonto.gitignoreimmediately - Rotate all exposed credentials (database password, SMTP password, email account)
- Restore secret injection in the deployment workflow by uncommenting and using the secure pattern with GitHub secrets/variables
- Review git history and consider credential rotation if the repository is public or widely accessible
🤖 Prompt for AI Agents
In src/Web.Api/appsettings.Production.json (line 9) and related files referenced
in the review, the production DB and SMTP credentials are checked into source
(DB password at line 9, SMTP username/password at lines ~21-22); remove these
plaintext secrets from the file and replace them with configuration references
to environment variables or placeholders (e.g. use connection string from env
var or key vault reference), add appsettings*.Production.json and
appsettings*.Staging.json to .gitignore immediately, rotate the exposed
credentials (DB password, SMTP password, email account) and any credentials in
repo history if public, and restore the secure secret injection in
.github/workflows/deploy-gcloud.yml by re-enabling the deploy step that passes
secrets via --set-env-vars (or the platform’s secret mechanism) using GitHub
secrets/variables (e.g. ${{ secrets.DB_CONNECTION_STRING }}, ${{
secrets.SMTP_USERNAME }}, ${{ secrets.SMTP_PASSWORD }}); finally, review and, if
necessary, scrub repository history or use a secret-removal tool and document
the rotation actions.
Summary by CodeRabbit