infra(cpb): add database, env vars, and setup scripts for Connecting People Bot#120
infra(cpb): add database, env vars, and setup scripts for Connecting People Bot#120SashkoMarchuk merged 7 commits intomainfrom
Conversation
- .env.example: CPB variables for dev and prod sections - .env: CPB dev defaults (using Reporter Bot token for testing) - docker-compose.yml: CPB env vars for postgresql + n8n services - docker-compose.prod.yml: CPB env vars for n8n (prod overrides) - scripts/init-db.sh: append CPB user/database creation block - scripts/cpb-setup-db.sh: new idempotent production DB setup script Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…lures - Add identifier validation for username/database name (regex + 63-char limit) - Add -v ON_ERROR_STOP=1 to psql invocation to catch SQL errors - Add pipefail to catch pipeline failures - Fix misleading comment on password escaping Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
🤖 CodeRabbit AI Review AvailableTo request a code review from CodeRabbit AI, add CodeRabbit will analyze your code and provide feedback on:
Note: Reviews are only performed when |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds CPB (Connecting People Bot) configuration: new environment variables in Changes
Sequence Diagram(s)sequenceDiagram
participant Operator as Operator
participant Provision as cpb-setup-db.sh
participant InitScript as init-db.sh
participant Postgres as PostgreSQL
participant n8n as n8n Service
participant Slack as Slack API
Operator->>Provision: run provisioning (CPB_POSTGRES_HOST, POSTGRES_PASSWORD_CPB, ...)
Provision->>Postgres: CREATE ROLE IF NOT EXISTS (validated idents, escaped pwd)
Provision->>Postgres: CREATE DATABASE IF NOT EXISTS (owner CPB role)
Provision->>Postgres: GRANT ALL PRIVILEGES ON DATABASE TO ROLE
Operator->>InitScript: run init (creates CPB role/db if part of init)
Operator->>n8n: start service with CPB env vars
n8n->>Postgres: connect to CPB DB using CPB_POSTGRES_*
n8n->>Slack: use CPB_SLACK_BOT_TOKEN to post/communicate
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.env.example:
- Around line 117-133: This file contains duplicate CPB environment variables
(e.g., POSTGRES_DB_CPB, POSTGRES_USER_CPB, CPB_POSTGRES_HOST, CPB_POSTGRES_DB,
CPB_POSTGRES_USER, CPB_POSTGRES_PASSWORD, CPB_SLACK_BOT_TOKEN, CPB_CHANNEL_ID,
CPB_REPORT_CHANNEL_ID, CPB_ADMIN_SLACK_ID, CPB_DEV_SLACK_ID, CPB_PAIRING_* )
which will override the earlier development entries; remove the duplicate
production block or split into separate templates (e.g., .env.example.dev and
.env.example.prod) so each variable name appears only once in a given template
and placeholders like CPB_CHANNEL_ID/CPB_REPORT_CHANNEL_ID remain unambiguous
for developers to fill.
In `@docker-compose.prod.yml`:
- Around line 45-48: The compose file currently supplies placeholder defaults
for Slack IDs (CPB_CHANNEL_ID, CPB_REPORT_CHANNEL_ID, CPB_ADMIN_SLACK_ID,
CPB_DEV_SLACK_ID) which permits startup with invalid values; change these to be
required by removing the ":-FILL_BEFORE_LAUNCH" defaults and instead use a
strict expansion form (e.g., ${CPB_CHANNEL_ID:?CPB_CHANNEL_ID is required}) for
each variable so the process fails fast at launch if any Slack ID is missing.
In `@scripts/cpb-setup-db.sh`:
- Line 52: The psql call currently hardcodes the admin user with "-U postgres",
which breaks environments that use a different superuser; update the psql
invocation (the line containing "psql -v ON_ERROR_STOP=1 -h \"$PGHOST\" -p
\"$PGPORT\" -U postgres <<-EOSQL") to honor an environment-configurable
superuser variable (e.g. PGUSER, PGSUPERUSER or a new ADMIN_DB_USER) and default
sensibly if unset, then use that variable in place of the hardcoded "-U
postgres" so external PostgreSQL setups can supply their admin username.
In `@scripts/init-db.sh`:
- Around line 17-19: The CREATE USER SQL inserts the raw $POSTGRES_PASSWORD_CPB
into a single-quoted SQL literal which breaks if the password contains a single
quote and can allow injection; before building the SQL statements (the CREATE
USER "$POSTGRES_USER_CPB" WITH ENCRYPTED PASSWORD ... line), sanitize/escape the
password by doubling any single quotes (e.g.
ESCAPED_PASSWORD=${POSTGRES_PASSWORD_CPB//\'/\'\'}), then use that escaped
variable in the SQL string instead of the raw $POSTGRES_PASSWORD_CPB; ensure the
same escaped value is used wherever the password literal is injected.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: b2dd31be-8d7e-4edc-b645-fd2601c3f0f5
📒 Files selected for processing (5)
.env.exampledocker-compose.prod.ymldocker-compose.ymlscripts/cpb-setup-db.shscripts/init-db.sh
- Remove duplicate CPB env vars from production section in .env.example - Make Slack IDs required (:?) in docker-compose.prod.yml instead of defaulting to placeholders - Make PostgreSQL admin user configurable via CPB_POSTGRES_ADMIN_USER in cpb-setup-db.sh - Fix password escaping in init-db.sh and cpb-setup-db.sh (use '' not \'\') Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
🔍 Vulnerabilities of
|
| digest | sha256:17e54ff5e9a181d1bdbf7334ce9637f9c3934d54a65427ae36a5743f46487f15 |
| vulnerabilities | |
| platform | linux/amd64 |
| size | 218 MB |
| packages | 358 |
📦 Base Image alpine:3
| also known as |
|
| digest | sha256:1c4eef651f65e2f7daee7ee785882ac164b02b78fb74503052a26dc061c90474 |
| vulnerabilities |
Description
Description
Description
Description
Description
Description
Description
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
Description
Description
Description
Description
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
Description
Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
|
There was a problem hiding this comment.
🧹 Nitpick comments (3)
.env.example (1)
31-37: Consider adding a brief comment explaining the two variable sets.There are two similar-looking groups:
POSTGRES_*_CPB(Lines 31-33) used by the PostgreSQL service for provisioning, andCPB_POSTGRES_*(Lines 34-37) used by n8n to connect. A short inline comment would help developers understand why both exist.📝 Suggested clarification
# CPB (Connecting People Bot) — Development +# PostgreSQL provisioning variables (used by postgresql service in docker-compose) POSTGRES_DB_CPB=cpb_bot POSTGRES_USER_CPB=cpb_app POSTGRES_PASSWORD_CPB=cpb_password +# CPB application connection variables (used by n8n service) CPB_POSTGRES_HOST=postgresql CPB_POSTGRES_DB=cpb_bot🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.env.example around lines 31 - 37, Add a short inline comment above the two variable groups clarifying that POSTGRES_DB_CPB, POSTGRES_USER_CPB, POSTGRES_PASSWORD_CPB are used by the PostgreSQL service for provisioning/initialization, while CPB_POSTGRES_HOST, CPB_POSTGRES_DB, CPB_POSTGRES_USER, CPB_POSTGRES_PASSWORD are the connection variables consumed by n8n (or the app); place the comment immediately above the first group so developers see the distinction when scanning the .env example.scripts/init-db.sh (1)
8-8: Consider escaping N8N and Temporal passwords for consistency.The CPB password is now properly escaped, but
POSTGRES_PASSWORD_N8N(Line 8) andPOSTGRES_PASSWORD_TEMPORAL(Line 12) are still injected raw into SQL. A single quote in these passwords would break initialization similarly.For consistency and defense-in-depth, consider applying the same escaping pattern to all passwords in this script.
♻️ Proposed fix
# Escape single quotes in CPB password for SQL safety ESCAPED_POSTGRES_PASSWORD_CPB="${POSTGRES_PASSWORD_CPB//\'/''}" +ESCAPED_POSTGRES_PASSWORD_N8N="${POSTGRES_PASSWORD_N8N//\'/''}" +ESCAPED_POSTGRES_PASSWORD_TEMPORAL="${POSTGRES_PASSWORD_TEMPORAL//\'/''}" psql -v ON_ERROR_STOP=1 --username "postgres" <<-EOSQL - CREATE USER "$POSTGRES_USER_N8N" WITH ENCRYPTED PASSWORD '$POSTGRES_PASSWORD_N8N'; + CREATE USER "$POSTGRES_USER_N8N" WITH ENCRYPTED PASSWORD '$ESCAPED_POSTGRES_PASSWORD_N8N'; CREATE DATABASE "$POSTGRES_DB_N8N" OWNER "$POSTGRES_USER_N8N"; GRANT ALL PRIVILEGES ON DATABASE "$POSTGRES_DB_N8N" TO "$POSTGRES_USER_N8N"; - CREATE USER "$POSTGRES_USER_TEMPORAL" WITH ENCRYPTED PASSWORD '$POSTGRES_PASSWORD_TEMPORAL'; + CREATE USER "$POSTGRES_USER_TEMPORAL" WITH ENCRYPTED PASSWORD '$ESCAPED_POSTGRES_PASSWORD_TEMPORAL';Also applies to: 12-12
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/init-db.sh` at line 8, The CREATE USER statements inject POSTGRES_PASSWORD_N8N and POSTGRES_PASSWORD_TEMPORAL raw into SQL, which will break if the passwords contain single quotes; update the script to mirror the escaping used for CPB by replacing direct variable interpolation with the escaped versions (use the same shell-escaping expression applied there) wherever POSTGRES_PASSWORD_N8N and POSTGRES_PASSWORD_TEMPORAL are used (e.g., in the CREATE USER and ALTER ROLE statements) so all three passwords are consistently escaped before being embedded into the SQL commands.scripts/cpb-setup-db.sh (1)
31-45: Identifier validation provides good SQL injection protection.The
validate_pg_identifierfunction correctly enforces PostgreSQL identifier rules (63-char limit,^[a-zA-Z_][a-zA-Z0-9_]*$pattern). This prevents crafted names from breaking or exploiting the SQL statements.To satisfy the SonarCloud warning, consider adding an explicit
return 0at the function's end, though this is optional since the implicit return behavior is correct.♻️ Optional fix for SonarCloud
if [[ ! "$value" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then echo "ERROR: ${name} contains invalid characters (must match ^[a-zA-Z_][a-zA-Z0-9_]*$)" >&2; exit 1 fi + return 0 }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/cpb-setup-db.sh` around lines 31 - 45, The SonarCloud warning requests an explicit success return from the identifier validator: update the validate_pg_identifier function to include an explicit "return 0" as the last statement before the closing brace so the function always returns success when validations pass; keep the current exit 1 behavior on failures and leave the calls validate_pg_identifier "$CPB_USER" "POSTGRES_USER_CPB" and validate_pg_identifier "$CPB_DB" "POSTGRES_DB_CPB" unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.env.example:
- Around line 31-37: Add a short inline comment above the two variable groups
clarifying that POSTGRES_DB_CPB, POSTGRES_USER_CPB, POSTGRES_PASSWORD_CPB are
used by the PostgreSQL service for provisioning/initialization, while
CPB_POSTGRES_HOST, CPB_POSTGRES_DB, CPB_POSTGRES_USER, CPB_POSTGRES_PASSWORD are
the connection variables consumed by n8n (or the app); place the comment
immediately above the first group so developers see the distinction when
scanning the .env example.
In `@scripts/cpb-setup-db.sh`:
- Around line 31-45: The SonarCloud warning requests an explicit success return
from the identifier validator: update the validate_pg_identifier function to
include an explicit "return 0" as the last statement before the closing brace so
the function always returns success when validations pass; keep the current exit
1 behavior on failures and leave the calls validate_pg_identifier "$CPB_USER"
"POSTGRES_USER_CPB" and validate_pg_identifier "$CPB_DB" "POSTGRES_DB_CPB"
unchanged.
In `@scripts/init-db.sh`:
- Line 8: The CREATE USER statements inject POSTGRES_PASSWORD_N8N and
POSTGRES_PASSWORD_TEMPORAL raw into SQL, which will break if the passwords
contain single quotes; update the script to mirror the escaping used for CPB by
replacing direct variable interpolation with the escaped versions (use the same
shell-escaping expression applied there) wherever POSTGRES_PASSWORD_N8N and
POSTGRES_PASSWORD_TEMPORAL are used (e.g., in the CREATE USER and ALTER ROLE
statements) so all three passwords are consistently escaped before being
embedded into the SQL commands.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 1f342094-f414-4d1b-ac02-ae64b504941d
📒 Files selected for processing (4)
.env.exampledocker-compose.prod.ymlscripts/cpb-setup-db.shscripts/init-db.sh
🚧 Files skipped from review as they are similar to previous changes (1)
- docker-compose.prod.yml
Review Findings — Addressed in e74a8b7Fixed (4 CodeRabbit findings)
CI Failures — Dismissed as False Positives
Validation
|
- Add clarifying comments in .env.example for provisioning vs connection vars - Escape N8N and Temporal passwords in init-db.sh for consistency with CPB fix - Add explicit return 0 to validate_pg_identifier (fixes SonarCloud S7682) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.env.example:
- Around line 118-122: Update the production-note paragraph in .env.example to
accurately reference the Development section range (change "lines 30-46" to
"lines 30-48") and include the runtime DB credential variable in the list: add
CPB_POSTGRES_PASSWORD (in addition to POSTGRES_PASSWORD_CPB/POSTGRES variants
already listed) so the production instructions explicitly tell users to set
CPB_POSTGRES_PASSWORD, CPB_POSTGRES_HOST, CPB_SLACK_BOT_TOKEN, CPB_CHANNEL_ID,
CPB_REPORT_CHANNEL_ID, CPB_ADMIN_SLACK_ID, and CPB_DEV_SLACK_ID when creating a
real .env from .env.example.
In `@scripts/init-db.sh`:
- Around line 9-24: Validate all seven identifier environment variables
(POSTGRES_USER_N8N, POSTGRES_DB_N8N, POSTGRES_USER_TEMPORAL,
POSTGRES_DB_TEMPORAL, POSTGRES_DB_TEMPORAL_VISIBILITY, POSTGRES_USER_CPB,
POSTGRES_DB_CPB) before invoking psql by reusing the identifier validation
function/logic from cpb-setup-db.sh (the implementation at lines 32–47) that
enforces the 63-character PostgreSQL limit, valid character set, and emits clear
errors; perform this validation in scripts/init-db.sh and abort with a
descriptive message if any identifier is invalid so that no unvalidated
identifier values are interpolated into the CREATE USER/CREATE DATABASE/GRANT
SQL block.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 09a8692d-889c-4698-b1fb-dd78e1229184
📒 Files selected for processing (3)
.env.examplescripts/cpb-setup-db.shscripts/init-db.sh
✅ Files skipped from review due to trivial changes (1)
- scripts/cpb-setup-db.sh
…note - Add validate_pg_identifier to init-db.sh matching cpb-setup-db.sh pattern - Validate all 7 database/user identifiers before SQL execution - Fix .env.example production note: correct line range (30-48), add CPB_POSTGRES_PASSWORD Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Final Review Status — All Findings ResolvedCommits
All 7 CodeRabbit Findings — Addressed
Additional Improvement
CI Status
Both Docker Security failures are infrastructure issues unrelated to this PR. |
Switch 9 CPB environment variables from :?required to :-default in docker-compose.prod.yml. Docker Compose evaluates all :?required vars globally during file parsing — missing CPB vars would crash ALL services (n8n, temporal, redis, oauth2-proxy), not just CPB functionality. With :-default, deploys work safely without CPB vars configured. CPB won't function (placeholder token, fake IDs) but nothing crashes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|



Summary
cpb_botdatabase,cpb_appuser, and all required environment variablesscripts/cpb-setup-db.sh— idempotent production database setup script with SQL injection protection and error handlingscripts/init-db.shfor dev environment auto-initializationAll changes are additive — no existing n8n or Temporal functionality is modified.
Files Changed
.env.exampledocker-compose.ymlpostgresqlservice (3 vars) +n8nservice (14 vars)docker-compose.prod.ymln8nservice with:?required/:-defaultsyntaxscripts/init-db.shscripts/cpb-setup-db.shSecurity Hardening
The production setup script (
cpb-setup-db.sh) includes:validate_pg_identifier()function validates username/database name against^[a-zA-Z_][a-zA-Z0-9_]*$with 63-char PostgreSQL limit-v ON_ERROR_STOP=1ensures psql exits on SQL errors (not silently ignored)set -eo pipefailcatches both command and pipeline failuresSetup Guide for DevOps
Development (fresh setup)
Development (existing volume)
If you already have a running PostgreSQL volume,
init-db.shwon't re-run. Create the CPB database manually:Production
Environment Variables Reference
POSTGRES_DB_CPBcpb_botcpb_botPOSTGRES_USER_CPBcpb_appcpb_appPOSTGRES_PASSWORD_CPBcpb_passwordCPB_SLACK_BOT_TOKENxoxb-placeholderCPB_CHANNEL_IDCXXXXXXXXXCPB_REPORT_CHANNEL_IDCXXXXXXXXXCPB_ADMIN_SLACK_IDUXXXXXXXXXCPB_DEV_SLACK_IDUXXXXXXXXXCPB_PAIRING_LAMBDA0.05780.0578CPB_PAIRING_ALPHA0.30.3CPB_PAIRING_TRIALS5050CPB_PAIRING_MIN_WEIGHT0.010.01Rollback
All changes are additive. To rollback:
Test Plan
docker compose config --quietpasses (dev config valid)docker compose -f docker-compose.yml -f docker-compose.prod.yml config --quietvalidates (prod config — will error on missing required vars, expected)bash -n scripts/cpb-setup-db.shpasses (no syntax errors)grep -c "CPB" scripts/init-db.shreturns 3 (user, database, grant)test -x scripts/cpb-setup-db.shconfirms executabledocker compose up -d(afterdown -v) createscpb_botdatabasedocker compose exec postgresql psql -U cpb_app -d cpb_bot -c "SELECT 1"returns 1docker compose exec n8n env | grep CPB_lists all 14 CPB variablesSummary by CodeRabbit
New Features
Chores