Learn / Lesson 4

Keys that cannot raise their own limit

Separate spending authority from limit management. This local model keeps a fixed total and does not let the spending key raise it. [2]

quotum x402 per-request intake remains closed. Do not sign a per-request payment. [2]

Who can move the ceiling?

A per-payment cap and a session budget answer different questions. The x402 v2 specification leaves client-side budget management outside its scope. If you are building a spending tool, decide both how much it may authorize and who may change that rule. Treat the management credential as a separate part of your design. [1]

For this lesson, imagine a fictional provider with a spending key and a separate operator. The spending key can use an allowance; it cannot edit it or create keys. This is a teaching model, not a description of a named provider API. We will test its permission boundary instead of assuming a cap enforces itself. [1]

Draw the authority boundary

Start by listing everything the spending process can reach. Include credentials in environment variables, configuration files, mounted secrets and tools. Look for a management key or a funded wallet that could obtain another credential. Remove those routes from the spending process before treating its visible cap as a meaningful boundary. [1]

In our fictional example, a spending key is labeled with a sample limit of 20 units. If the same process also holds an operator credential with access to a sample account of 100 units, assess the whole account balance as reachable. The smaller label alone does not describe the authority you handed over. [1]

Keep limit changes in a separate operator action. This toy refuses every raise. A spending role cannot manage limits. A holder role cannot either: limit changes would be a separate operator action, and this toy does not implement that action. It does not parse free text. [1]

What the quotum docs actually say

The seat docs describe one provider key per seat, limited to the session cap. The keeper sets that limit at the provider. When a seat is freed, its key is deleted. The docs do not identify the key type, so this lesson does not label it an admin or inference key. [2]

Holder day keys are off since 30 October 2026. The docs describe a separately budgeted day key for the house, allocated from the operator’s seat. That use is separate from holder issuance. This page cannot create one; its allocation control is a fictional exercise. [2]

Pay as you go is another system beside seats: revocable project keys spend prepaid balance through its endpoint. Its project balance and key budget are separate from the seat session cap. Keep those scopes separate when reading a meter or checking a refusal. Do not treat the example allocation here as a live product allowance. [2]

Share an allowance without growing it

The local example starts with a parent limit of 50 sample units. Only the holder role may allocate a child. Allocating 5 lowers the parent limit to 45 and gives the child 5. The combined limit remains 50. These numbers define the exercise; they are not a quote, a funded balance or a measured spend. [1]

The model checks available parent allowance before cutting a child. It refuses a non-integer, zero, a negative amount, an allocation above 5, an allocation above unspent parent allowance, an eleventh child, and any non-holder caller. Spending reduces what remains available without raising any limit. Reset starts a new local example. [1]

Try the refusal first

Ask the spending key to raise its own limit. Then ask it to allocate a child. Both actions should be refused in this toy. Choose the holder role to allocate 5 sample units and inspect both sides of the split. Repeat the test after spending, when less unspent parent allowance remains. [1]

For your own implementation, write tests for limit changes, credential creation and spending beyond the allowance. Check that failed actions leave the accounting unchanged. Use disposable test credentials in a sandbox and inspect the actual provider response. The plain REFUSED labels below are model outcomes, not promises about a provider HTTP status code. [1]

Try to raise the cap. Fictional provider, sample units.
505000

Combined limit: 50 sample units

Parent limit 50, spent 0, child limits 0.

Choose an action. Holder day keys on quotum are off.

Run it

Self-contained JavaScript sample. Run here or save the module and run it with Node. No network or credentials.

// Fictional provider, sample units, no credentials or network.
export function createFamily() {
  let parent = 50, spent = 0;
  const children = [];
  const valid = n => Number.isSafeInteger(n) && n >= 0;
  return {
    raise(role, limit) {
      if (role !== 'operator') return 'REFUSED: only an operator action may change limits';
      return 'REFUSED: raising the original allowance is outside this toy';
    },
    cut(role, amount) {
      if (role !== 'holder') return 'REFUSED: holder authority required';
      if (!valid(amount) || amount === 0 || amount > 5 || children.length >= 10 || amount > parent - spent) return 'REFUSED: invalid allocation';
      parent -= amount;
      children.push({ limit: amount, spent: 0 });
      return 'ALLOCATED: parent ' + parent + ', children ' + children.reduce((s, k) => s + k.limit, 0);
    },
    spend(amount) {
      if (!valid(amount) || amount > parent - spent) return 'REFUSED: allowance exceeded';
      spent += amount;
      return 'SPENT: ' + spent + ', parent remaining ' + (parent - spent);
    },
    state() { return { parent, spent, children: children.map(k => ({ ...k })), total: parent + children.reduce((s, k) => s + k.limit, 0) }; }
  };
}
export function run() {
  const f = createFamily();
  return [f.spend(10), f.raise('spending', 500), f.cut('spending', 5), f.cut('holder', 5), f.spend(35), f.spend(1), 'TOTAL LIMIT: ' + f.state().total];
}
if (typeof process !== 'undefined' && process.argv[1]?.endsWith('/keys-that-cannot-raise-their-own-limit.mjs')) console.log(run().join('\n'));
Save sample module
The sample has not run yet.

Check yourself

In the fictional 100-unit account, the process has a 20-unit spending key and the operator credential. What authority must you assess? [1]

Read the explanation

Assess every credential the process can use. [1]

The toy allocates 5 from a parent limit of 50. What is the combined limit? [1]

Read the explanation

The parent becomes 45 and the child receives 5. [1]

Does this page offer holder day-key creation on quotum? [2]

Read the explanation

The docs date that restriction to 30 October 2026. [2]

Sources

  1. x402 evidence baseline, 3 November 2026. Version 2 specification at the pinned commit, EVM exact, ERC-3009.
  2. quotum receipts, seat keys and Pay as you go. Site copy captured 5 November 2026.

Written by the team that sells capped inference keys. Check the cited docs yourself.