Repository navigation
Rate-limit df.start - #427
Conversation
f93d73b to
b690d26
Compare
There was a problem hiding this comment.
🟡 Changes recommended
A non-superuser can bypass both quotas through repeated transaction rollbacks because instance accounting is rolled back while enqueue commits separately, allowing unaccounted engine work and retained failure history.
1 open issue
What changed in this PR
Adds per-role instance quotas to df.start() to address denial-of-service risks from excessive workflow submissions, with enforcement in both transaction modes.
Changes:
- Adds configurable active and retained-instance quotas, serialized admission checks, and quota error hints.
- Adds an owner-leading index and prepares version 0.2.10 with upgrade support.
- Adds quota, concurrency, isolation, and security tests, plus configuration and upgrade documentation.
| File | Description |
|---|---|
| USER_GUIDE.md | Documents quota configuration, scope, retention, and transaction interactions. |
| tests/e2e/sql/93_start_limits_serializable.sql | Tests overlapping serializable starts and transaction retries. |
| tests/e2e/sql/92_start_limits_trust.sql | Tests protected accounting and resistance to status and lock manipulation. |
| tests/e2e/sql/91_start_limits_concurrency.sql | Tests admission locking, isolation levels, rollback, and timeouts. |
| tests/e2e/sql/90_start_limits.sql | Tests quota settings, enforcement, identities, and transaction modes. |
| tests/e2e/sql/89_schema_qualification.sql | Adds aggregate-shadowing traps for quota queries. |
| tests/e2e/sql/00_setup_playground.sql | Adds a helper to wait for engine-terminal state. |
| src/lib.rs | Registers quota settings and the fresh-install index. |
| src/dsl.rs | Enforces quotas with per-role locking and current-snapshot counts. |
| src/client.rs | Counts engine-active instances and preserves quota error details. |
| sql/pg_durable--0.2.9--0.2.10.sql | Adds the quota index during extension upgrade. |
| scripts/test-upgrade.sh | Tests quota enforcement against older installed schemas. |
| docs/upgrade-testing.md | Describes quota compatibility, migration, and performance considerations. |
| docs/api-reference.md | Documents quota settings and start rejection behavior. |
| CHANGELOG.md | Records quota security changes and upgrade implications. |
| Cargo.toml | Bumps the package version to 0.2.10. |
| Cargo.lock | Aligns the locked package version with 0.2.10. |
Review effort: Balanced
There was a problem hiding this comment.
🟡 Changes recommended
Submission records can be deleted despite failed local metadata cleanup, falsely blocking submissions through quota accounting, while reused rolled-back IDs can abort starts instead of triggering retries.
2 open issues
1 resolved since last review
Review effort: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
Security-sensitive admission combines PostgreSQL locking and snapshots with independently committed provider state, requiring human review and unavailable runtime validation of concurrency, rollback, cleanup, and binary-only upgrades.
No open issues 🎉
2 resolved since last review
Review effort: Balanced
1ae8bc6 to
30bcbd0
Compare


Fixes #139.
Summary
Adds administrator-controlled admission quotas to
df.start()to limit runaway workflow submission and retained history.df.max_concurrent_per_userdf.max_instances_per_userBoth settings are superuser-settable, apply per submitting role and origin database, and accept
0to disable the individual limit. Superuser submission identities are exempt, subject to the existing superuser-instance policy. Rejected starts raise SQLSTATE53400with an actionable hint.These are concurrency and retention quotas, not calls-per-second or byte limits.
Implementation
'new'uses its separate session’s configuration defaults rather than inheriting caller session overrides.Upgrade & compatibility
Prepares version 0.2.10 and adds an owner-leading index through the extension upgrade script. Quotas also work with supported older schemas without
ALTER EXTENSION UPDATE; the worker provisions protected accounting before publishing readiness. Updating the extension adds the index.No orchestration payloads or replay-visible operations change. However, the new defaults also affect existing workflows whose SQL calls
df.start().Retained capacity is not freed by completion, cancellation, or rollback alone. With default retention, a role holding 10,000 recent submissions may remain blocked until history ages out or an administrator adjusts policy. Existing orphan records created before protected accounting cannot be attributed retroactively.
Validation
Local PG17 validation passed:
Also fixes Docker’s test classification so reconciliation-only regressions run under the primary CI runner’s required configuration rather than the fixed-configuration Docker image.