Skip to content

feat: add hidden-key request allowances for new accounts - #1416

Open
pjb157 wants to merge 1 commit into
mainfrom
peter/ui-only-request-allowances
Open

feat: add hidden-key request allowances for new accounts#1416
pjb157 wants to merge 1 commit into
mainfrom
peter/ui-only-request-allowances

Conversation

@pjb157

@pjb157 pjb157 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add separately configurable lifetime playground and batch request allowances for newly created standard users
  • attach allowances only to internal hidden execution keys and atomically reserve one request per playground/Flex submission or the contained request count for file batches
  • prevent visible API keys from spending allowances, while retaining normal paid-credit behavior
  • permanently revoke both allowances on the first positive credit transaction from any source and refresh inference routing
  • keep exhausted allowance rows routable for already accepted queued work, without backfilling existing accounts

Validation

  • just test rust
  • just lint rust
  • focused allowance, API-key provenance, batch, file-content, and dedicated-database regression tests
  • independent code review with all important findings addressed

Provision separate lifetime playground and batch request budgets only for newly created standard users. Reserve them atomically through UI-owned hidden keys, revoke them on the first positive credit transaction, and keep queued work routable through allowance-aware sync.
Copilot AI review requested due to automatic review settings July 31, 2026 15:36
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying control-layer with  Cloudflare Pages  Cloudflare Pages

Latest commit: a5d67f5
Status: ✅  Deploy successful!
Preview URL: https://4a8e7f29.control-layer.pages.dev
Branch Preview URL: https://peter-ui-only-request-allowa.control-layer.pages.dev

View logs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a “trial” mechanism for newly created standard-user accounts by provisioning lifetime request allowances on hidden UI execution keys (playground + batch), consuming them atomically at request acceptance time, and revoking them permanently on the first positive credit gain while keeping routing stable for already-queued work.

Changes:

  • Introduces api_key_request_allowances (migration + Rust repo) and wires provisioning into standard-user creation flows.
  • Gates playground, flex, and batch admission paths to reserve allowances only for eligible hidden keys, while preventing visible API keys from spending allowances.
  • Extends onwards routing eligibility to keep hidden keys routable while an allowance row exists (even when remaining reaches 0), and revokes allowances on positive credit gains with routing refresh.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
dwctl/src/test/mod.rs Updates a dedicated-database regression test to provision a batch allowance for the test user.
dwctl/src/sync/onwards_config/tests.rs Adds coverage ensuring hidden-key allowances keep metered routing until the allowance row is deleted.
dwctl/src/sync/onwards_config/mod.rs Extends key-eligibility SQL to include hidden playground/batch keys when an allowance row exists.
dwctl/src/inference/middleware.rs Adds flex allowance reservation on queued acceptance; enriches flex key resolution with balance + provenance fields.
dwctl/src/db/handlers/request_allowances.rs New repository implementing provision, preflight, and atomic reservation of request allowances (with tests).
dwctl/src/db/handlers/mod.rs Exposes RequestAllowances / AllowanceReservation through the handlers module.
dwctl/src/db/handlers/credits.rs Revokes allowances on any positive signed credit delta (and relies on DB trigger to refresh onwards routing).
dwctl/src/config.rs Adds config knobs for initial playground/batch request allowances and validates they are non-negative.
dwctl/src/auth/middleware.rs Enforces that API-key-authenticated playground submissions require positive credits; reserves playground allowance for session UI submissions.
dwctl/src/auth/current_user.rs Provisions allowances for newly auto-created proxy-header standard users.
dwctl/src/api/handlers/users.rs Provisions allowances when admins create standard users via the management API (config-driven).
dwctl/src/api/handlers/files.rs Adjusts tests to provision large batch allowances for test users to avoid unrelated 402s.
dwctl/src/api/handlers/batches.rs Adds allowance-aware batch admission/reservation, including file-batch request-count reservation logic.
dwctl/src/api/handlers/auth.rs Provisions allowances during native registration; tests cover provisioning and revocation-by-initial-credits.
dwctl/migrations/128_api_key_request_allowances.sql Adds api_key_request_allowances table and a DELETE trigger to notify onwards config reloads.
config.yaml Documents the new request-allowance config settings.
.sqlx/query-ce08e5f67c48bb3cff76492de9ae3a9d4f86bd06b8911d6a13b2b83a201c14ec.json Updates SQLx metadata for onwards target loading query (allowance eligibility clause).
.sqlx/query-4ca7905e785b5dc48a67724ba219670afcf9ef6854d277ebc877c0dfb9624ed8.json Updates SQLx metadata for credit transaction fold query (allowance revocation CTE).
.sqlx/query-08a38081643cc475233b8d7643c0e7d3041934b99604017c10954fb9b2ced4cc.json Updates SQLx metadata for composite-model cache query (allowance eligibility clause).

Comment on lines +2173 to +2181
async fn create_test_user_with_roles(pool: &PgPool, roles: Vec<Role>) -> crate::api::models::users::UserResponse {
let user = crate::test::utils::create_test_user_with_roles(pool, roles).await;
let mut conn = pool.acquire().await.unwrap();
super::RequestAllowances::new(&mut conn)
.provision(user.id, 0, 1_000_000)
.await
.unwrap();
user
}
Comment on lines +2153 to +2158
async fn create_test_user_with_roles(pool: &PgPool, roles: Vec<Role>) -> crate::api::models::users::UserResponse {
let user = crate::test::utils::create_test_user_with_roles(pool, roles).await;
let mut conn = pool.acquire().await.unwrap();
RequestAllowances::new(&mut conn).provision(user.id, 0, 1_000_000).await.unwrap();
user
}
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