feat: per-key spending-rule enforcement for Lambda parity (PRs 1-3)#477
Open
clawdbot-glitch003 wants to merge 5 commits into
Open
feat: per-key spending-rule enforcement for Lambda parity (PRs 1-3)#477clawdbot-glitch003 wants to merge 5 commits into
clawdbot-glitch003 wants to merge 5 commits into
Conversation
… PR 1) First slice of the Lambda-parity work (plans/chipotle-lambda-parity.md): the durable home for per-key blast-radius controls the gateway will enforce. - Migration: spending_rules (rolling spend cap+window, rate rps+burst, concurrency, origin allowlist, enabled) and spending_usage (rolling spend counter with in-SQL window reset). - New `spending` module: typed rows + validated upsert request, sqlx db layer (upsert/get/list/delete rules, atomic record_charge with window reset), ServiceAuth bearer guard for gateway calls, and routes. - Operator-authed CRUD under /api/spending-rules (admin UI) and ServiceAuth-authed /internal endpoints (gateway: fetch rules for its cache, record spend off the response path). - INTERNAL_SERVICE_TOKEN config; /internal endpoints disabled (503) when unset. No production behavior change — nothing reads these tables yet. 9 unit tests cover request validation, hash canonicalization, and the token comparison. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…parity PR 3) The on-chain zero-latency gate for per-key spending rules. All additive and storage-safe: a new mapping appended to the END of root AccountConfigStorage (not a field on the inline-embedded UsageApiKey struct, which would shift the Account layout). - AppStorage: append `mapping(uint256 => bool) usageKeyHasSpendingRules`. - ViewsFacet: `getSpendingRulesFlag(apiKeyHash)` and `canExecuteActionWithSpendingRules(apiKeyHash, cidHash) -> (canExecute, hasSpendingRules)` so the gateway reads both in one RPC. - WritesFacet: `setSpendingRulesFlag(accountApiKeyHash, usageApiKeyHash, bool)` + event, same account-access control as setUsageApiKey. Source only; `forge build` passes. Regenerate the Rust bindings + diamond ABI with `make generate` on the canonical toolchain, then deploy via Safe diamond-cut on Base (both ops steps). The gateway reads the new view through a scoped sol! interface, so it does not depend on the regenerated giant binding. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…(lambda-parity PR 2) Gateway side of the Lambda-parity work. Reads the on-chain hasSpendingRules gate in the same multicall as the execute-permission check; keys without rules pay zero extra work. - accounts: can_execute_action_with_spending_rules -> (can_execute, has_spending_rules), cached in BlockchainCache (new execute_and_spending entry, same generation invalidation). Reads the new view via a scoped sol! interface (read_only_client_and_address helper) so it tracks the workspace alloy version instead of the regenerated giant binding. - core::spending_rules: flag-gated enforcer. On a flagged key it fetches rules (cached, TTL) from lit-payments /internal, then enforces a rolling spend cap (402), a per-node token-bucket rate limit (429), and a per-node concurrency cap (429). Spend is recorded off the response path (in-memory + fire-and- forget POST). Inert unless LIT_PAYMENTS_INTERNAL_URL + INTERNAL_SERVICE_TOKEN are set AND the key's on-chain flag is on. - Wired into core_features::lit_action + the /lit_action route + main state. - 429 (too_many_requests) ApiStatus helper. Origin allowlist (P2.1) deferred. SWR background refresh for the rules cache is a marked follow-up (currently TTL with inline cold-miss fetch). cargo check clean; 4 unit tests for the token bucket, window reset, and hash format. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ty-payments-storage # Conflicts: # lit-api-server/src/accounts/signable_contract.rs # lit-api-server/src/main.rs # lit-payments/src/config.rs # lit-payments/src/main.rs
Brings the two design plans from PR #446 into this branch so they ship with the lambda-parity implementation they describe, and #446 can be closed. - plans/chipotle-lambda-parity.md — prioritized gateway work (this PR implements P0.0/P0.1/P0.2/P1) for per-key blast-radius parity with a public Lambda URL. - plans/private-apps-backend.md — the backend-as-Lit-Actions framework these gateway controls unlock (relay becomes optional). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the Chipotle gateway controls that make a usage API key safe to embed in a frontend, with blast-radius parity to a public AWS Lambda URL (see
plans/chipotle-lambda-parity.md). One branch, three logical layers as separate commits.PR 1 — lit-payments storage. New
spending_rules+spending_usagetables (migration) and aspendingmodule: Operator-authed CRUD under/api/spending-rulesfor the admin UI, andServiceAuth-authed/internalendpoints for the gateway to fetch rules and record rolling spend. Disabled (503) unlessINTERNAL_SERVICE_TOKENis set.PR 3 — AccountConfig contract (source only). Adds the on-chain
hasSpendingRulesgate: a new mapping appended to the end of root storage (storage-safe), asetSpendingRulesFlagwriter, and acanExecuteActionWithSpendingRulesview returning(canExecute, hasSpendingRules)so the gateway reads both in one RPC.forge buildpasses; regenerate bindings + diamond-cut deploy are ops steps.PR 2 — gateway enforcement. Reads the flag in the same multicall as the execute check (cached in
BlockchainCache), so keys without rules pay zero extra work. For a flagged key it enforces a rolling spend cap (402), a per-node token-bucket rate limit (429), and a per-node concurrency cap (429), recording spend off the response path. Inert unlessLIT_PAYMENTS_INTERNAL_URL+INTERNAL_SERVICE_TOKENare set and the key's flag is on. The new view is called via a scopedsol!interface so it tracks the workspace alloy version rather than the regenerated giant binding.cargo checkis clean for both crates; 13 unit tests pass. Not yet wired: the "set rule in DB → flip the on-chain flag" path, the binding regen + Safe diamond-cut deploy, origin allowlist (P2.1), and SWR background refresh for the rules cache (currently TTL + inline cold-miss fetch).🤖 Generated with Claude Code