Harden prod Railway runtime secrets#94
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThis PR externalizes hardcoded production secrets to Railway environment variables, documents the required variable names, updates the production config to read them, and adds a validation script ensuring config and docs stay consistent. ChangesProduction Railway Secrets Externalization
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Related Knowledge 1 document with suggested updates is ready for review. BAWES Universe Production Operations & Deployments RunbookView Suggested Changes@@ -39,10 +39,10 @@
### Backend (Railway)
- **Build & Deploy**: Uses Railway CLI. Set `RAILWAY_DOCKERFILE_PATH` to `./Dockerfile-nginx-dev-railway` (dev) or `./Dockerfile-nginx-railway` (prod). Use `railway login`, `railway link`, and `railway up` to deploy. [Reference](https://github.com/BAWES-Universe/studenthub/blob/ca90a5502040ba8191fe9f80d29d0b6a4d2a6152/railway/railway.md#L1-L34)
-- **Required Env Vars**: Set via Railway dashboard or `.env` files (not in repo).
+- **Required Env Vars**: Set via Railway dashboard or `.env` files (not in repo). Production Railway requires `DB_DSN`, `DB_USERNAME`, `DB_PASSWORD`, `WALLET_DB_DSN`, `WALLET_DB_USERNAME`, `WALLET_DB_PASSWORD`, `REDIS_HOSTNAME`, `REDIS_PASSWORD`, `REDIS_USERNAME` (optional), `REDIS_PORT` (optional, defaults 6379), `REDIS_DATABASE` (optional, defaults 0), and `SENTRY_DSN`. See [prod-railway-runtime-secrets.md](https://github.com/BAWES-Universe/studenthub/blob/main/docs/prod-railway-runtime-secrets.md) for the full list.
- **Database Connectivity**:
- Dev: MySQL (host=mysql, db=studenthub, user=studenthubuser, pass=12345)
- - Prod: AWS RDS (host=studenthub-prod.cluster-c8mekjvvbygf.eu-west-2.rds.amazonaws.com, db=studenthub, user=bawes, pass=bawes12student!hub)
+ - Prod Railway: Configured via environment variables (`DB_DSN`, `DB_USERNAME`, `DB_PASSWORD`, `WALLET_DB_DSN`, `WALLET_DB_USERNAME`, `WALLET_DB_PASSWORD`) set in Railway dashboard
- **Logs**: Use `docker logs <container_id>` or Railway dashboard logs. [Reference](https://github.com/BAWES-Universe/studenthub/blob/ca90a5502040ba8191fe9f80d29d0b6a4d2a6152/README.md#L9-L174)
### Admin Frontend (CircleCI → S3/CloudFront)
@@ -115,7 +115,7 @@
## Observability & Incident Response
-- **Sentry Logging**: Configured in backend environment files (`environments/*/common/config/main-local.php`) with DSN `https://6cbd2100e1ff41e7875352655ffbf50d:e18336b09d864b29aa12aca3fbc6706c@sentry.io/168200` for error/warning levels, tagged by environment (`dev`, `dev-server`, `production`). [Reference](https://github.com/BAWES-Universe/studenthub/blob/ca90a5502040ba8191fe9f80d29d0b6a4d2a6152/environments/dev/common/config/main-local.php#L1-L124)
+- **Sentry Logging**: Configured in backend environment files (`environments/*/common/config/main-local.php`) for error/warning levels, tagged by environment (`dev`, `dev-server`, `production`). Production Railway Sentry DSN is configured via the `SENTRY_DSN` environment variable set in the Railway dashboard. [Reference](https://github.com/BAWES-Universe/studenthub/blob/ca90a5502040ba8191fe9f80d29d0b6a4d2a6152/environments/dev/common/config/main-local.php#L1-L124)
- **Slack Logging**: Configured for info/warning levels for admin, candidate, company, staff, remail, common, console categories.
- **What to Check First**: Sentry project for stack traces (environment tags), Slack channels for notifications, `~/logs` for cron and migration logs.
- **Common Incidents**: No documentation found in repos for email not sending, PDF export 500, or transfers stuck. Debugging steps must be sourced from Sentry, Slack, Railway, Netlify, or AWS dashboards.
@@ -130,9 +130,9 @@
## Day-1 Ops Checklist
-- Verify Railway deployments for dev/prod: run `railway link`, confirm `RAILWAY_DOCKERFILE_PATH`, inspect AWS RDS/Redis connections in `environments/prod/common/config/main-local.php`.
+- Verify Railway deployments for dev/prod: run `railway link`, confirm `RAILWAY_DOCKERFILE_PATH`, verify production environment variables (`DB_DSN`, `DB_USERNAME`, `DB_PASSWORD`, `WALLET_DB_DSN`, `WALLET_DB_USERNAME`, `WALLET_DB_PASSWORD`, `REDIS_HOSTNAME`, `REDIS_PASSWORD`, `SENTRY_DSN`) are set in Railway dashboard as documented in [prod-railway-runtime-secrets.md](https://github.com/BAWES-Universe/studenthub/blob/main/docs/prod-railway-runtime-secrets.md).
- Confirm CircleCI contexts: ensure `org-global` context holds AWS credentials for admin/staff S3/CloudFront buckets as listed in `.circleci/config.yml`.
-- Check Sentry project (`dsn ...@sentry.io/168200`) for alerting rules tied to `environment` tags and ensure Slack logger targets the correct workspace.
+- Check Sentry project for alerting rules tied to `environment` tags and ensure Slack logger targets the correct workspace. Production Railway Sentry DSN is configured via environment variable in the Railway dashboard.
- Review cron job logs under `~/logs` and trigger key jobs manually (e.g., `php ~/www/yii cron/daily`) after verifying cache flush steps from README.
- Snapshot MySQL (prod RDS) via `railway connect mysql` and push `.sql` dump to the appropriate S3 bucket (`studenthub-uploads`).
- Confirm candidate & company frontend deployment channels by logging into their hosting dashboards (Netlify/AWS) and documenting build steps. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/check-prod-railway-runtime-secrets.py (1)
15-20: ⚡ Quick winHarden
component_blockagainst formatting drift and missing markers.This parser currently fails with an unhandled exception if a component marker is absent and is tightly coupled to exact indentation, which can cause noisy false failures.
Proposed patch
def component_block(config, component): marker = f"'{component}' => [" - start = config.index(marker) - next_component = re.search(r"\n '[^']+' => \[", config[start + len(marker):]) + start = config.find(marker) + require(start != -1, f"Component '{component}' must exist in config.") + next_component = re.search(r"\n\s{8}'[^']+'\s*=>\s*\[", config[start + len(marker):]) end = start + len(marker) + next_component.start() if next_component else len(config) return config[start:end]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/check-prod-railway-runtime-secrets.py` around lines 15 - 20, component_block currently assumes the exact marker exists and exact indentation, causing crashes; change it to use config.find(marker) and handle a -1 (marker missing) case gracefully (e.g., return empty string or raise a clear ValueError), and loosen the next-component regex to accept arbitrary whitespace (use r"\n\s*'[^']+'\s*=>\s*\[") when searching the remainder; compute end as before (start + len(marker) + match.start()) if a match exists or use len(config) when not, and ensure all indexes are only used after confirming start >= 0.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tests/check-prod-railway-runtime-secrets.py`:
- Around line 15-20: component_block currently assumes the exact marker exists
and exact indentation, causing crashes; change it to use config.find(marker) and
handle a -1 (marker missing) case gracefully (e.g., return empty string or raise
a clear ValueError), and loosen the next-component regex to accept arbitrary
whitespace (use r"\n\s*'[^']+'\s*=>\s*\[") when searching the remainder; compute
end as before (start + len(marker) + match.start()) if a match exists or use
len(config) when not, and ensure all indexes are only used after confirming
start >= 0.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 565e9af6-3b33-4be9-a7d6-b767f7577eb1
📒 Files selected for processing (3)
docs/prod-railway-runtime-secrets.mdenvironments/prod-railway/common/config/main-local.phptests/check-prod-railway-runtime-secrets.py
Related to #55
/claim #55
Scope
This is a narrow production Railway runtime-secret hardening slice. It does not touch S3/AWS keys, SQS/EventManager, MediaConvert, SES/mailers, Xero, Cloudinary, Wallet/Yeaster service tokens, OneSignal, Civil ID upload/remove flows, live production services, database access, candidate data, or real credential values.
Summary
Verification
php -lcould not be run here because PHP is not installed in this environment. The PHP change is limited to replacing literal config values with existinggetenv(...)style config expressions.Safety boundary
No live Railway, AWS/IAM/S3, database, Redis, Sentry, candidate data, private exports, screenshots, or credential values were accessed or included in docs/comments.
Transparency: automation-assisted; I reviewed the diff and verification before submitting.
Summary by CodeRabbit
Documentation
Configuration
Tests