Skip to content

docs(api-admin): clarify budget enforcement is SaaS-only - #225

Merged
moonming merged 2 commits into
mainfrom
docs/budget-saas-only
May 10, 2026
Merged

docs(api-admin): clarify budget enforcement is SaaS-only#225
moonming merged 2 commits into
mainfrom
docs/budget-saas-only

Conversation

@moonming

@moonming moonming commented May 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

The §4.4 `Budgets` prose previously said "the proxy reads the
budget at request start and adds the cost at end of request" —
true in neither mode:

  • Standalone: the proxy never reads `max_budget_usd` from the
    etcd snapshot at all (`grep -rn 'max_budget' crates/aisix-proxy/`
    → 0 non-test matches).
  • SaaS / Managed: the DP doesn't compute cost or accumulate
    spend; cp-api owns both. The DP only calls cp-api
    (`/dp/budget_check`) and pushes usage to it
    (`/dp/telemetry`) — and only for chat-completion and Anthropic
    messages traffic.

Architectural review confirmed budget is a SaaS-tier feature: cp-api
is the single source of truth, multiple DP instances stay
consistent without DP-side coordination, and the DP avoids
duplicating cp-api's pricing/accumulation logic.

This PR rewrites §4.4 to describe what actually happens in each
mode, with concrete file paths, cache TTLs, batch sizes, and
worst-case propagation latency. No code changes.

Changes

  • §4.4 §"SaaS / Managed mode": describe the pull
    (`/dp/budget_check`, 5 s LRU cache) + push (`/dp/telemetry`,
    5 s / 100-event batches) flows; pin worst-case ≈ 10 s
    propagation; document the cp-api-unreachable fall-back ladder
    (`AISIX_DP_BUDGET_STALE_MAX_SECONDS` → `fail_mode`).
  • §4.4 "Usage push" bullet — pin the two endpoints that emit
    UsageEvents today (`/v1/chat/completions`, `/v1/messages`)
    and explicitly list the five that don't; cross-reference Non-chat endpoints don't emit UsageEvents — cp-api's spend ledger misses spend from /v1/responses, /v1/embeddings, /v1/audio*, /v1/images*, /v1/rerank #226.
  • §4.4 §"Standalone mode": state plainly that enforcement is not
    implemented; explain why the admin schema still accepts the
    field (SaaS CP writes ApiKey rows including this field directly
    into etcd, so the wire shape must stay compatible).
  • §4.2 — one-line caveat under the apikey example so a reader
    landing on §4.2 alone sees max_budget_usd is SaaS-only and is
    pointed at §4.4.

Audit history

PR went through one round of independent audit (general-purpose
agent, no shared context). Findings:

  • MEDIUM — "each completion enqueues a UsageEvent"
    overgeneralized; only chat completions + Anthropic messages
    emit. Fixed in d1b4379 by pinning the two emitting
    endpoints and explicitly listing the five that don't.
  • LOW — §4.2 example sets `max_budget_usd: 500.0` with no
    caveat. Fixed in d1b4379 by adding a cross-reference note.
  • LOW — "stay consistent" → "stay eventually consistent
    within the 5 s cache window". Folded into the prose during the
    fix.

Audit also surfaced a real product gap (not introduced by this
PR): non-chat endpoints don't push usage to cp-api, so SaaS
budgets undercount spend on embeddings/audio/images/responses/
rerank traffic. Filed as #226 (HIGH for SaaS budget
correctness and billing accuracy) and linked from §4.4.

Closes

Test plan

  • No code changes — `cargo test` not affected.
  • CI green (markdown-only change; lint should pass trivially).
  • Reviewer reads the new §4.4 against `crates/aisix-proxy/src/budget.rs`,
    `crates/aisix-server/src/telemetry.rs`, and `crates/aisix-proxy/src/chat.rs:977-980`
    to confirm cache TTL, batch size, fail-mode, and emitting-endpoints
    match the code.

Summary by CodeRabbit

  • Documentation
    • Expanded Admin API docs for budget management, clarifying per-API-key USD budget caps and that enforcement applies only in SaaS/managed mode.
    • Described enforcement workflow in SaaS/managed deployments: pre-checks, batched usage reporting, propagation timing, and stale/ fail-mode behavior during connectivity issues.
    • Noted Standalone mode accepts budget fields for compatibility but does not enforce them.

Review Change Stack

The §4.4 prose previously said "the proxy reads the budget at
request start and adds the cost at end of request" — true neither
in standalone mode (proxy doesn't read the field at all) nor in
SaaS mode (proxy doesn't compute cost; cp-api accumulates from
telemetry). Architectural review confirmed budget is a SaaS-tier
feature: cp-api is the single source of truth, the DP delegates
per-request decisions via `/dp/budget_check` and pushes usage via
`/dp/telemetry`.

Rewrite §4.4 to:
- State explicitly that DP never reads `max_budget_usd` from the
  etcd snapshot; the field is informational on the DP side.
- Explain the SaaS pull (pre-check) + push (telemetry) flows with
  exact cache TTL, batch size, and worst-case ≈ 10 s propagation.
- Document the cp-api unreachable fall-back (sticky cache up to
  `AISIX_DP_BUDGET_STALE_MAX_SECONDS`, then `fail_mode`).
- State plainly that standalone mode does not enforce — admin POST
  accepts the field for SaaS wire compatibility (CP writes ApiKey
  rows including this field directly into etcd) but it's a no-op
  on the DP side.

Closes #189 (wontfix — by design, not a gap).
Closes #190 (depends on #189; field is unenforced DP-side, so
admin lower-bound tightening has no practical effect).
Copilot AI review requested due to automatic review settings May 10, 2026 13:41
@coderabbitai

coderabbitai Bot commented May 10, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: b99b5a3d-726a-4be1-80c3-94893fa55f4a

📥 Commits

Reviewing files that changed from the base of the PR and between 0819e9c and d1b4379.

📒 Files selected for processing (1)
  • docs/api-admin.md
✅ Files skipped from review due to trivial changes (1)
  • docs/api-admin.md

📝 Walkthrough

Walkthrough

Admin API docs expand Budgets: max_budget_usd lives on the ApiKey resource (no budgets collection), SaaS enforcement uses per-request cp-api checks with a 5s LRU cache plus batched telemetry, standalone mode accepts the field but does not enforce it, and stale/propagation behavior is documented.

Changes

Budget Enforcement Documentation

Layer / File(s) Summary
Budget API Specification
docs/api-admin.md
Budgets section expanded to specify max_budget_usd on ApiKey resource only, SaaS enforcement via cp-api budget checks with 5s LRU cache and batched telemetry updates, stale decision behavior when cp-api is unreachable, and ~10s worst-case propagation timing.
ApiKey Note
docs/api-admin.md
Explicit note added that max_budget_usd enforcement applies only in managed/SaaS mode and references the standalone behavior caveat.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Updates the admin API documentation (§4.4 “Budgets”) to reflect that budget enforcement in the data-plane proxy is managed via cp-api in SaaS/Managed deployments and is not implemented in standalone deployments.

Changes:

  • Rewrites §4.4 to describe the managed-mode budget pre-check (/dp/budget_check) and usage push (/dp/telemetry) flows, including timing expectations and fallback behavior.
  • Clarifies that standalone mode does not enforce max_budget_usd, and that the field remains for wire compatibility with managed mode.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/api-admin.md
Comment on lines +192 to +193
with a 5 s LRU cache per api_key. `allow=false` becomes a 429
`BudgetExceeded` before upstream dispatch.
Comment thread docs/api-admin.md
decision sticks for up to `AISIX_DP_BUDGET_STALE_MAX_SECONDS`
(default 600 s); past that the proxy applies the `fail_mode`
(`open` / `closed` / `sticky`) the most recent successful response
carried.
PR #225 audit (general-purpose agent) flagged that the "Usage push"
bullet overgeneralized — only /v1/chat/completions and /v1/messages
emit UsageEvents today; embeddings, audio, images, responses, and
rerank don't (per the comment at chat.rs:977-980). The previous
prose implied complete coverage, which would mislead anyone reading
§4.4 to plan SaaS budgets.

Fixes:
- §4.4 "Usage push" — pin the two emitting endpoints; explicitly
  list the five that don't and reference the chat.rs comment;
  link the carve-out to the new tracking issue #226.
- §4.2 — add a one-line caveat under the apikey example so a
  reader landing on §4.2 alone sees that max_budget_usd is
  SaaS-only and points at §4.4 for the propagation model.
@moonming
moonming merged commit fef4af4 into main May 10, 2026
5 of 6 checks passed
@jarvis9443
jarvis9443 deleted the docs/budget-saas-only branch June 25, 2026 06:25
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