Skip to content

feat: require db_anon_role for PostgREST, remove pgedge_application_r…#361

Merged
moizpgedge merged 3 commits intomainfrom
Feat/PLAT-568/Remove-pgedge_application_read_only-default-from-PostgREST-anon-role
Apr 22, 2026
Merged

feat: require db_anon_role for PostgREST, remove pgedge_application_r…#361
moizpgedge merged 3 commits intomainfrom
Feat/PLAT-568/Remove-pgedge_application_read_only-default-from-PostgREST-anon-role

Conversation

@moizpgedge
Copy link
Copy Markdown
Contributor

Summary

Removes the pgedge_application_read_only fallback from the PostgREST
authenticator, unblocking PLAT-559 (removal of deprecated built-in roles).

Previously, if a user deployed a PostgREST service without supplying
db_anon_role, the control plane silently defaulted to
pgedge_application_read_only as the anon role and granted it to the
connect_as user. This created a hidden dependency on the deprecated role
that prevented PLAT-559 from cleaning it up.

Changes

  • desiredAnonRole() in postgrest_authenticator_resource.go now returns
    r.DBAnonRole directly — no fallback
  • db_anon_role is now required in ParsePostgRESTServiceConfig
    omitting it returns 400: db_anon_role is required
  • All tests updated to supply an explicit db_anon_role or assert the new
    required-field error

Testing

  • Missing db_anon_role400 db_anon_role is required
  • Empty db_anon_role400 db_anon_role must not be empty
  • Valid deployment with explicit db_anon_role: "web_anon" — only web_anon
    is granted, pgedge_application_read_only is not granted ✓
  • All unit tests pass (go test ./...) ✓

…ead_only default

`desiredAnonRole()` previously fell back to `pgedge_application_read_only`
when no anon role was supplied, blocking removal of the deprecated built-in
roles in PLAT-559.

`db_anon_role` is now required at validation time. Omitting it returns a
400 with `db_anon_role is required`. All tests updated accordingly.

PLAT-568
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Warning

Rate limit exceeded

@moizpgedge has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 10 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 16 minutes and 10 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6c99dfdc-115e-4cb0-a262-8ab9c0e26b3f

📥 Commits

Reviewing files that changed from the base of the PR and between 5d6b26d and a9237af.

📒 Files selected for processing (3)
  • e2e/postgrest_test.go
  • server/internal/api/apiv1/validate_test.go
  • server/internal/database/postgrest_service_config.go
📝 Walkthrough

Walkthrough

This pull request makes db_anon_role a required configuration field for PostgREST services. The default fallback value "pgedge_application_read_only" has been removed from parsing and validation logic, and validation now fails with an error when the field is absent from the configuration.

Changes

Cohort / File(s) Summary
PostgREST Service Config Parsing
server/internal/database/postgrest_service_config.go, server/internal/database/postgrest_service_config_test.go
Modified config parsing to require db_anon_role as a mandatory field. Removed default fallback value and now appends validation error when field is absent. Updated tests to remove default-value assertions and add coverage for the new required-field validation.
Service Validation Tests
server/internal/api/apiv1/validate_test.go
Updated test cases to expect validation failure when db_anon_role is missing or empty in postgrest service specs. Test fixtures now include non-empty Config with db_anon_role: "web_anon" and test names reflect the new validation requirement.
Authenticator Resource
server/internal/orchestrator/swarm/postgrest_authenticator_resource.go, server/internal/orchestrator/swarm/postgrest_authenticator_resource_test.go
Removed default fallback behavior from desiredAnonRole() function; now returns DBAnonRole directly without defaulting to "pgedge_application_read_only" when empty. Updated corresponding test expectations accordingly.
Config Resource Test
server/internal/orchestrator/swarm/postgrest_config_resource_test.go
Updated test fixture to use web_anon instead of pgedge_application_read_only for the db_anon_role value in assertions.

Poem

🐰 A hop, skip, and change in the config today,
Where db_anon_role must have its say,
No defaults allowed, be explicit, my friend!
The fallback's retired—the requirements now blend,
With validation enforced, the PostgREST configs shine. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: requiring db_anon_role for PostgREST and removing the pgedge_application_read_only default fallback.
Description check ✅ Passed The PR description covers the Summary, Changes, and Testing sections well, but is missing the Checklist and Notes for Reviewers sections from the template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch Feat/PLAT-568/Remove-pgedge_application_read_only-default-from-PostgREST-anon-role

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented Apr 22, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 duplication

Metric Results
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes. Give us feedback

@moizpgedge moizpgedge requested a review from rshoemaker April 22, 2026 12:57
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
server/internal/database/postgrest_service_config.go (1)

11-16: ⚠️ Potential issue | 🟡 Minor

Update the optional-fields comments for db_anon_role.

Lines 13 and 37 still describe every field as optional/defaulted, but db_anon_role is now required by Lines 56-69.

📝 Proposed comment update
 // PostgRESTServiceConfig is the typed internal representation of PostgREST service
 // configuration. Parsed from ServiceSpec.Config map[string]any. All fields are
-// optional; defaults are applied when absent.
+// optional unless noted; defaults are applied when absent.
 type PostgRESTServiceConfig struct {
 	DBSchemas    string `json:"db_schemas"`    // default: "public"
-	DBAnonRole   string `json:"db_anon_role"`
+	DBAnonRole   string `json:"db_anon_role"`  // required
 	DBPool       int    `json:"db_pool"`       // default: 10, range: 1-30
 // ParsePostgRESTServiceConfig parses and validates a config map into a typed
-// PostgRESTServiceConfig. All fields are optional with sensible defaults.
+// PostgRESTServiceConfig. `db_anon_role` is required; other fields are optional
+// with sensible defaults.
 func ParsePostgRESTServiceConfig(config map[string]any) (*PostgRESTServiceConfig, []error) {

Also applies to: 36-38

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/internal/database/postgrest_service_config.go` around lines 11 - 16,
The struct comment incorrectly marks DBAnonRole as optional/defaulted — update
the comment for PostgRESTServiceConfig.DBAnonRole to indicate it is required (no
default) instead of optional, and adjust the surrounding struct-level comment to
only list defaults for truly optional fields (e.g., leave DBSchemas as default
"public" but remove or change the "All fields are optional; defaults are
applied" phrasing); locate the DBAnonRole field in PostgRESTServiceConfig and
change its inline comment to reflect "required: no default" (or similar clear
wording) so readers and maintainers know this field must be provided.
server/internal/api/apiv1/validate_test.go (1)

1475-1477: ⚠️ Potential issue | 🟡 Minor

Keep unrelated PostgREST validation tests isolated with a valid db_anon_role.

These cases assert db_pool, unknown-key, jwt_secret, connect_as, or port-conflict behavior, but they still produce an additional missing-db_anon_role error. Since the tests only use ErrorContains, that extra error is masked.

🧪 Proposed fixture updates
 		{
 			name: "postgrest invalid db_pool range",
 			svc: &api.ServiceSpec{
 				ServiceID:   "my-postgrest",
 				ServiceType: "postgrest",
 				Version:     "latest",
 				HostIds:     []api.Identifier{"host-1"},
 				Config: map[string]any{
-					"db_pool": float64(99),
+					"db_anon_role": "web_anon",
+					"db_pool":      float64(99),
 				},
 			},
 		{
 			name: "postgrest unknown config key",
 			svc: &api.ServiceSpec{
 				ServiceID:   "my-postgrest",
 				ServiceType: "postgrest",
 				Version:     "latest",
 				HostIds:     []api.Identifier{"host-1"},
 				Config: map[string]any{
-					"invalid_key": "value",
+					"db_anon_role": "web_anon",
+					"invalid_key":  "value",
 				},
 			},
 		{
 			name: "postgrest jwt_secret too short",
 			svc: &api.ServiceSpec{
 				ServiceID:   "my-postgrest",
 				ServiceType: "postgrest",
 				Version:     "latest",
 				HostIds:     []api.Identifier{"host-1"},
 				Config: map[string]any{
-					"jwt_secret": "tooshort",
+					"db_anon_role": "web_anon",
+					"jwt_secret":   "tooshort",
 				},
 			},
 		{
 			name: "postgrest missing connect_as",
 			svc: &api.ServiceSpec{
 				ServiceID:   "my-postgrest",
 				ServiceType: "postgrest",
 				Version:     "latest",
 				HostIds:     []api.Identifier{"host-1"},
+				Config:      map[string]any{"db_anon_role": "web_anon"},
 				// ConnectAs intentionally left empty
 			},
 		{
 			name: "postgrest connect_as references unknown user",
 			svc: &api.ServiceSpec{
 				ServiceID:   "my-postgrest",
 				ServiceType: "postgrest",
 				Version:     "latest",
 				HostIds:     []api.Identifier{"host-1"},
 				ConnectAs:   "nonexistent",
+				Config:      map[string]any{"db_anon_role": "web_anon"},
 			},
 					{
 						ServiceID:   "postgrest-server",
 						ServiceType: "postgrest",
 						Version:     "latest",
 						HostIds:     []api.Identifier{"host-1"},
 						ConnectAs:   "app",
 						Port:        utils.PointerTo(8080),
-						Config:      map[string]any{},
+						Config:      map[string]any{"db_anon_role": "web_anon"},
 					},

Also applies to: 1490-1492, 1505-1507, 1514-1535, 2271-2278

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/internal/api/apiv1/validate_test.go` around lines 1475 - 1477, The
tests that validate specific PostgREST config errors are failing to isolate the
intended error because the test fixtures' Config maps lack a valid db_anon_role,
producing an extra missing-role error; update each problematic test's Config
(e.g., the Config map used in the table-driven cases around the shown snippet)
to include a valid db_anon_role entry (for example "db_anon_role": "anon") so
the tests only surface the targeted validation error (apply the same change to
the other similar cases referenced in this file).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@server/internal/api/apiv1/validate_test.go`:
- Around line 1475-1477: The tests that validate specific PostgREST config
errors are failing to isolate the intended error because the test fixtures'
Config maps lack a valid db_anon_role, producing an extra missing-role error;
update each problematic test's Config (e.g., the Config map used in the
table-driven cases around the shown snippet) to include a valid db_anon_role
entry (for example "db_anon_role": "anon") so the tests only surface the
targeted validation error (apply the same change to the other similar cases
referenced in this file).

In `@server/internal/database/postgrest_service_config.go`:
- Around line 11-16: The struct comment incorrectly marks DBAnonRole as
optional/defaulted — update the comment for PostgRESTServiceConfig.DBAnonRole to
indicate it is required (no default) instead of optional, and adjust the
surrounding struct-level comment to only list defaults for truly optional fields
(e.g., leave DBSchemas as default "public" but remove or change the "All fields
are optional; defaults are applied" phrasing); locate the DBAnonRole field in
PostgRESTServiceConfig and change its inline comment to reflect "required: no
default" (or similar clear wording) so readers and maintainers know this field
must be provided.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2f7ff90e-6a4c-47ac-aa1b-58cbd1a4ca64

📥 Commits

Reviewing files that changed from the base of the PR and between a682f3e and 5d6b26d.

📒 Files selected for processing (6)
  • server/internal/api/apiv1/validate_test.go
  • server/internal/database/postgrest_service_config.go
  • server/internal/database/postgrest_service_config_test.go
  • server/internal/orchestrator/swarm/postgrest_authenticator_resource.go
  • server/internal/orchestrator/swarm/postgrest_authenticator_resource_test.go
  • server/internal/orchestrator/swarm/postgrest_config_resource_test.go

Struct comment on PostgRESTServiceConfig incorrectly stated all fields
are optional with defaults. Updated to note DBAnonRole is required with
no default, and added an inline field comment to match.

Three validate_test.go cases (db_pool range, unknown config key,
jwt_secret too short) were missing db_anon_role in their Config maps,
causing an extra validation error that obscured the intended assertion.
Added db_anon_role to each fixture.

PLAT-568
All PostgREST E2E tests were failing because db_anon_role is now
required and the test fixtures did not supply it.

- postgrestSpec() injects db_anon_role: "anon" when not provided
- postgrestBaseSpec() adds an "anon" (NOLOGIN) user to DatabaseUsers
- TestPostgRESTMultiHostDBURI and TestPostgRESTFailover get the same
  anon user added to their inline DatabaseSpec
- TestPostgRESTAuthenticatorRole assertion updated from
  pgedge_application_read_only to anon

PLAT-568
@moizpgedge moizpgedge merged commit a6ba020 into main Apr 22, 2026
3 checks passed
@jason-lynch jason-lynch deleted the Feat/PLAT-568/Remove-pgedge_application_read_only-default-from-PostgREST-anon-role branch April 27, 2026 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants