fix(operator): avoid encoded postgres secret collision#487
Conversation
|
Warning Review limit reached
Next review available in: 2 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (5)
WalkthroughThis PR changes Postgres encoded-credentials secret naming to avoid collisions with the source secret, updates env var generation and reconcile/delete flows to use collision-safe names and ownership checks, and adds tests for collision handling and uncontrolled-secret preservation. ChangesEncoded secret name collision fix
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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 |
✅ Approve — automated reviewAll significant findings raised during the review cycle have been addressed by the author across multiple follow-up commits. The stale controller ownerReference remediation, the delete/finalizer path remediation, the hashed fallback naming to prevent secondary collisions, the existence-check guard before CreateOrUpdate, the stale hashed fallback cleanup, the operation ordering fix (encoded Secret deleted before ResourceReference), and the annotation-based detection of operator-created Secrets have all been implemented with corresponding regression tests. The single remaining finding from one reviewer (codex-1) describes a migration scenario where a previously-colliding source Secret could be overwritten, but this scenario is directly addressed by the annotation-based operator-created Secret detection (fbf8125) and the ensureEncodedPostgresCredentialsSecretCanBeWritten guard, which rejects writing to any uncontrolled existing Secret. No new unresolved blockers or major issues are identified. No findings. |
NumaryBot
left a comment
There was a problem hiding this comment.
NumaryBot posted 1 new inline finding.
Summary: #487 (comment)
There was a problem hiding this comment.
🧹 Nitpick comments (1)
internal/resources/databases/secret.go (1)
85-95: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider adding a test for stale encoded secret cleanup during reconciliation.
The
deleteStaleEncodedPostgresCredentialsSecretsfunction deletes candidate encoded secrets that are neither the source nor the desired name, but only if controlled by the database. No test currently verifies this cleanup path — e.g., a scenario where a previous deployment used the collision-safe name and the source secret later changes to a non-colliding name, leaving a stale controlled secret to be cleaned up.🤖 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 `@internal/resources/databases/secret.go` around lines 85 - 95, The cleanup path in deleteStaleEncodedPostgresCredentialsSecrets is not covered by tests, so add a reconciliation test that exercises stale encoded secret removal when a previous collision-safe secret becomes obsolete after the source secret changes. Use deleteStaleEncodedPostgresCredentialsSecrets and deleteEncodedPostgresCredentialsSecretIfControlled in the test setup to verify that candidate names other than sourceSecretName and desiredSecretName are deleted only when controlled by the Database, while current source/desired secrets are preserved.
🤖 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 `@internal/resources/databases/secret.go`:
- Around line 85-95: The cleanup path in
deleteStaleEncodedPostgresCredentialsSecrets is not covered by tests, so add a
reconciliation test that exercises stale encoded secret removal when a previous
collision-safe secret becomes obsolete after the source secret changes. Use
deleteStaleEncodedPostgresCredentialsSecrets and
deleteEncodedPostgresCredentialsSecretIfControlled in the test setup to verify
that candidate names other than sourceSecretName and desiredSecretName are
deleted only when controlled by the Database, while current source/desired
secrets are preserved.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d6139b1c-26de-4efd-885d-77b4bd4aa55d
⛔ Files ignored due to path filters (1)
docs/09-Configuration reference/settings.catalog.jsonis excluded by!**/*.json
📒 Files selected for processing (4)
internal/resources/databases/env.gointernal/resources/databases/env_test.gointernal/resources/databases/secret.gointernal/resources/databases/secret_test.go
b98f6d4 to
643a686
Compare
|
Addressed in the latest push (643a686):
Validation run locally:
|
NumaryBot
left a comment
There was a problem hiding this comment.
NumaryBot posted 1 new inline finding.
Summary: #487 (comment)
643a686 to
0ae381c
Compare
|
Follow-up for the latest NumaryBot finding addressed in 0ae381c:
Additional validation run locally:
|
NumaryBot
left a comment
There was a problem hiding this comment.
NumaryBot posted 1 new inline finding.
Summary: #487 (comment)
0ae381c to
7ad375c
Compare
|
Finalizer follow-up addressed in 7ad375c:
Validation run locally after this change:
|
NumaryBot
left a comment
There was a problem hiding this comment.
NumaryBot posted 2 new inline findings.
Summary: #487 (comment)
7ad375c to
01e1fd3
Compare
|
Hashed fallback follow-up addressed in 01e1fd3:
Validation run locally after this change:
|
NumaryBot
left a comment
There was a problem hiding this comment.
NumaryBot posted 2 new inline findings.
Summary: #487 (comment)
01e1fd3 to
e55f810
Compare
|
Hashed fallback stale cleanup addressed in e55f810:
Validation run locally:
|
NumaryBot
left a comment
There was a problem hiding this comment.
NumaryBot posted 2 new inline findings.
Summary: #487 (comment)
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@internal/resources/databases/init.go`:
- Around line 64-72: The cleanup order in the postgres credentials path is
wrong: in the branch that uses getPostgresCredentialsSecretReference,
deleteEncodedPostgresCredentialsSecret should run before
resourcereferences.Delete so a failed reconcile can still recover the stored
reference. Update the deletion flow in init.go so the encoded secret is removed
first, then delete the "postgres" ResourceReference afterward; keep the existing
error handling intact so retries remain safe and do not leak the encoded secret.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ab1b9ec0-c29d-4904-9c81-c5ade76df632
⛔ Files ignored due to path filters (1)
docs/09-Configuration reference/settings.catalog.jsonis excluded by!**/*.json
📒 Files selected for processing (5)
internal/resources/databases/env.gointernal/resources/databases/env_test.gointernal/resources/databases/init.gointernal/resources/databases/secret.gointernal/resources/databases/secret_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
- internal/resources/databases/env.go
- internal/resources/databases/secret_test.go
e55f810 to
f62ad62
Compare
NumaryBot
left a comment
There was a problem hiding this comment.
NumaryBot posted 2 new inline findings.
Summary: #487 (comment)
f62ad62 to
fbf8125
Compare
NumaryBot
left a comment
There was a problem hiding this comment.
NumaryBot posted 2 new inline findings.
Summary: #487 (comment)
fbf8125 to
84af876
Compare
NumaryBot
left a comment
There was a problem hiding this comment.
NumaryBot posted 1 new inline finding.
Summary: #487 (comment)
84af876 to
ef34297
Compare
NumaryBot
left a comment
There was a problem hiding this comment.
NumaryBot review complete: no remaining inline findings.
Resolved 1 stale NumaryBot review thread (0 fixed, 1 outdated).
Summary: #487 (comment)
|
Final follow-up after CI review comments:
Validation:
|
Summary
Root cause
v3.12.0introduced a derived Secret named<database>-postgres-uri-credentialsfor URL-encoded Postgres credentials. A real deployment can already use that exact name as the source Secret referenced by?secret=...(for exampleformance-ledger-postgres-uri-credentials). In that case, the Database reconciler writes encoded credentials back into the source Secret it just read, turning its input into its output and causing repeated reconciliations/rollouts around Ledger deployments.Helm / release context
formance-1.15.0resolvesregionsto3.12.0, which resolves the Operator chart to3.12.0; that is how the Operator change from #484 reached users. No Helm template change is needed for the fix itself, but a follow-up Operator release and Helm dependency refresh will be needed to ship it through the umbrella chart.Validation
CGO_ENABLED=0 go test ./internal/resources/databases -run 'Test(GetPostgresEnvVarsAvoidsEncodedSecretNameCollision|ReconcileEncodedPostgresCredentialsSecretAvoidsSourceSecretNameCollision|DeleteEncodedPostgresCredentialsSecretKeepsUncontrolledSourceSecret)' -count=1 -vKUBEBUILDER_ASSETS="$(pwd)/bin/k8s/1.32.0-darwin-arm64" CGO_ENABLED=0 go test ./...nix develop -c just pre-commitOperational checks
prod-eu-west-1-hosting: Operator is stillv3.11.2; Ledger databases use?secret=..., so it is exposed if upgraded to3.12.0before this fix.staging-eu-west-1-hosting: Operator is on the post-v3.12.0image, but visible Ledger databases use inline credentials, so it does not exercise the affected?secret=...path.object has been modified/POSTGRES_URL_ENCODED/postgres-uri-credentialsloop was found in the last 24h of our prod/staging hosting operator logs.