You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a shared_secret_grants target secret still holds the placeholder password that cpflow generate ships in templates/postgres.yml, every review-app deploy fails deep in the release phase with a bare Postgres authentication error. Nothing in the grant, policy, binding, or template is wrong, so the failure is very hard to attribute.
This is a request for an early, actionable diagnostic — not a bug report. cpflow behaved correctly throughout the investigation described below.
What happened downstream
In shakacode/react-on-rails-starter-tanstack, review apps share one staging Postgres via:
<app>-staging-pg was created by cpflow setup-app from the generated postgres.yml template, whose committed default is:
data:
password: the_password #Replace this with a real passwordusername: <app>
That placeholder was never replaced. The persistent staging app was independently hand-patched to carry the real password as an inline literal, so staging kept working while every review app failed — which made the failure look intermittent or external.
Every deploy failed identically:
PG::ConnectionBad: FATAL: password authentication failed for user "<app>"
ERROR: Failed to run release script. → exit code 64
Why it took so long to attribute
All config inspection passes. Grant, placeholder substitution, policy target, and binding are all correct — only the stored value is wrong, and that is invisible to config review.
The reveal binding is applied and released correctly. Polling every 10s during a real deploy: EMPTY → reveal -> <app>-review-pr-205-identity at 02:36:27Z → EMPTY at 02:44:42Z. The release script failed at 02:40:13Z, inside that window. cpflow does exactly what its docs describe.
Verifying the credential the obvious way gives a false pass. The stock postgres image ships:
host all all 127.0.0.1/32 trust
host all all all scram-sha-256
so psql -h 127.0.0.1 inside the container authenticates with any password. Only a non-loopback test exercises scram-sha-256. This trap is easy to fall into when debugging a shared-database setup.
Several rounds of investigation concluded "external authorization boundary, no repo-owned remediation" before the real cause was found.
Suggested improvement
Warn when a shared_secret_grants target secret still contains the generator's placeholder value — ideally during setup-app / deploy-image, before the release phase runs:
WARNING: shared_secret_grants entry 'database' targets secret '<app>-staging-pg',
whose 'password' field still contains the generated placeholder 'the_password'.
Review apps will fail database authentication until this is replaced.
A literal-value check against the shipped placeholder is cheap and needs no database connectivity. Optional extras:
Mention the loopback-trust pitfall in docs/secrets-and-env-values.md, so operators verifying a shared credential test over the non-loopback path.
Note in the shared-secret docs that reusing an app-scoped <app>-pg secret as a shared grant target inherits the generator placeholder.
Summary
When a
shared_secret_grantstarget secret still holds the placeholder password thatcpflow generateships intemplates/postgres.yml, every review-app deploy fails deep in the release phase with a bare Postgres authentication error. Nothing in the grant, policy, binding, or template is wrong, so the failure is very hard to attribute.This is a request for an early, actionable diagnostic — not a bug report.
cpflowbehaved correctly throughout the investigation described below.What happened downstream
In
shakacode/react-on-rails-starter-tanstack, review apps share one staging Postgres via:<app>-staging-pgwas created bycpflow setup-appfrom the generatedpostgres.ymltemplate, whose committed default is:That placeholder was never replaced. The persistent staging app was independently hand-patched to carry the real password as an inline literal, so staging kept working while every review app failed — which made the failure look intermittent or external.
Every deploy failed identically:
Why it took so long to attribute
All config inspection passes. Grant, placeholder substitution, policy target, and binding are all correct — only the stored value is wrong, and that is invisible to config review.
The reveal binding is applied and released correctly. Polling every 10s during a real deploy:
EMPTY→reveal -> <app>-review-pr-205-identityat02:36:27Z→EMPTYat02:44:42Z. The release script failed at02:40:13Z, inside that window.cpflowdoes exactly what its docs describe.Verifying the credential the obvious way gives a false pass. The stock
postgresimage ships:so
psql -h 127.0.0.1inside the container authenticates with any password. Only a non-loopback test exercisesscram-sha-256. This trap is easy to fall into when debugging a shared-database setup.Several rounds of investigation concluded "external authorization boundary, no repo-owned remediation" before the real cause was found.
Suggested improvement
Warn when a
shared_secret_grantstarget secret still contains the generator's placeholder value — ideally duringsetup-app/deploy-image, before the release phase runs:A literal-value check against the shipped placeholder is cheap and needs no database connectivity. Optional extras:
trustpitfall indocs/secrets-and-env-values.md, so operators verifying a shared credential test over the non-loopback path.<app>-pgsecret as a shared grant target inherits the generator placeholder.Environment
cpflow5.2.0, reusable workflow@v5.2.0shakacode/react-on-rails-starter-tanstack(issue Add timeout for runner jobs #194)inboundAllowType: same-org