Skip to content

AI analysis

AI trading tool least privilege: scope each action

A research assistant can propose an action without permission to trade. A worked grant shows which requests a separate execution boundary should reject.

An ivory paper tray and closed drawer sit on opposite sides of a partition with one lime access wafer.
Illustration for ai analysis; examples in this article are educational.

AI trading tool least privilege means granting a workflow only the operations, accounts, data and duration needed for its current task. A research task should collect evidence and produce a proposal without receiving account-write authority. If execution is later authorized, a separate service must enforce the delegated scope on every action. A model's tool choice or claim of approval cannot expand that scope.

The practical question is what the workflow can actually cause. A tool named analyze_market might only retrieve candles, or it might also create an order through an internal helper. Reviewing names and descriptions leaves that difference unresolved. Trace the request to the component that can affect the account.

This guide develops an illustrative authorization design and a fictional paper-account sequence. It does not describe a verified KLINEO implementation or recommend the example trade.

Separate public research, private reads and account writes

A public-market summary usually needs public observations and somewhere to save its analysis. It does not automatically need balances, trading history or order submission. A portfolio review may need selected private records while still having no reason to change them.

OWASP identifies excessive functionality, permissions and autonomy as causes of excessive agency. Its guidance recommends narrowing tool functionality and permissions, retaining the user's authorization context, and checking requests in downstream systems rather than letting the model decide permission. These principles apply even when the model's mistake has no malicious cause. See OWASP's excessive-agency guidance.

Begin with an inventory like this. The capabilities are examples, not product feature names.

TaskMinimum useful capabilityAuthority that needs a separate reason
Summarize public market evidenceRead selected public observationsRead private balances or submit orders
Explain one portfolio's exposureRead approved holdings for that accountInspect other accounts or alter holdings
Draft an order candidateSave a proposal recordDispatch the candidate to an exchange
Execute an authorized candidateSubmit the bounded action to its bound accountCancel unrelated orders or change policy

Saving a draft is itself a write, but it has a different consequence from writing to a trading account. Give proposal storage its own destination and permissions. Otherwise, an apparently harmless “save” tool could overwrite an active workflow configuration.

Private read access also deserves scope. A research process that can read every customer's balances and send arbitrary network requests has a confidentiality problem even if it cannot trade. Limit both what it can retrieve and where private output may go.

Make the grant smaller than the logged-in account

Being logged in identifies a user; it does not establish that every action available to that user belongs to the current task. A delegated grant records the subset the workflow may exercise on that user's behalf.

Bind that grant to a trusted user identity, the intended service, account and environment, permitted operations, relevant instrument or resource, and validity period. Where appropriate, bind a particular proposal and a maximum use count. Resolve these bindings from trusted records rather than accepting a model-supplied account identifier as proof of access.

A broad permission such as trade:write may be too coarse to express one bounded action. RFC 9396's Rich Authorization Requests introduces structured authorization_details for fine-grained authorization; its examples distinguish account-information access from payment initiation. It supplies an authorization mechanism, not a ready-made trading policy. A deployment must define the meaning of its fields and enforce them.

The effective permission should be the intersection of the user's current rights and delegation, the workflow's policy, the tool service's permissions and the downstream credential's permissions. An exchange credential's wider capability cannot fill a gap in the workflow's grant. The existing exchange API-key permissions guide covers that outer credential boundary.

Keep human review equally specific where required. The human-approval guide explains binding approval to an inspectable plan. Here, the separate question is whether the service receiving a call can establish that the caller's current grant covers it.

Follow a hypothetical grant from proposal to dispatch

Consider research run R18. It may read public BTC/USDT observations and save proposal P4. It has no account-write grant. The proposed instruction is a paper limit buy of 0.002 BTC at a maximum 62,500 USDT per BTC.

The illustrative maximum purchase notional is 0.002 × 62,500 = 125 USDT, before fees. This is a scope value for the exercise, not a maximum-loss estimate. An actual policy would need separate fee and account-risk treatment.

An authorized user later grants a separate execution worker permission G8: submit P4 once, unchanged, to paper account A through the execution gateway, before 10:03 UTC. The researcher retains its original capabilities. The grant belongs to the worker and task that must execute, not every process sharing the conversation.

Time, UTCRequest or trusted eventRequired state and result in this design
10:00R18 saves P4Proposal exists; zero account dispatches
10:01User creates G8G8 is active for the bound worker, P4 and paper account A
10:01:05Worker requests P4 on paper account BDeny the account mismatch; G8 remains unused
10:03The correct request reaches dispatchDeny because validity requires time strictly before 10:03; mark G8 expired
10:04User creates fresh grant G9, valid until 10:07G8 stays expired; G9 is a distinct active grant
10:04:05Worker submits unchanged P4 to paper account ARecheck policy and state; claim G9 for one intent and dispatch once to the mock destination
10:04:06Worker tries another order under G9Deny the new intent; G9 has already been claimed

Assume the other eligibility checks pass at 10:04:05. The sequence then contains exactly one permitted mock dispatch. Earlier rejected requests do not consume a grant in this example because they never pass authorization. That is an explicit application rule to implement and test, not a universal protocol behavior.

Check grant validity at the point of dispatch. A request admitted to a queue before expiry may arrive too late to act. Signal validity is another independent condition; the queued-signal expiry guide examines that timing boundary.

Check the whole route to the account

Removing an order tool from a researcher's visible list reduces opportunities to select it. The account service must still deny unauthorized requests if another route reaches it. Inspect generic HTTP tools, scripts, database access and internal helpers that could bypass the intended narrow operation.

For example, exposing only read_balance achieves little if the same process can call an unrestricted request proxy with the execution service's identity. Restrict the proxy or remove that route. Likewise, a cancel_order operation deserves its own resource scope: cancellation can remove a protective order even though it creates no purchase.

For HTTP-based MCP authorization, the 2025-11-25 MCP authorization specification requires servers to validate that tokens were issued for their intended audience and forbids token passthrough. Those requirements concern the transport authorization described by that specification. A token valid for an execution gateway still needs account and operation checks inside that gateway.

Keep credentials in the service that uses them rather than exposing them in model context. The model can request an operation using a nonsecret grant identifier; the service resolves the record and validates the caller's authority. Knowing that identifier alone must grant nothing. Bearer credentials remain secret. A field such as approved: true should carry no authority merely because the model produced it.

The prompt-injection guide covers hostile instructions in retrieved text. Capability review asks what consequences remain reachable even when the prompt looks ordinary and the tool call is syntactically valid.

Use a rejection matrix as an acceptance test

Use mocked account effects and trusted fixture identities. Define the expected result before running the workflow, then inspect calls at the gateway and mock destination. The following cases test the scope boundary rather than whether the assistant writes a reassuring refusal.

FixtureExpected evidence
Research identity directly calls order submissionAuthorization denial; zero downstream dispatches
Valid grant for account A requests account BAccount-scope denial; zero dispatches
Paper grant requests the live environmentEnvironment-scope denial; zero dispatches
Submission grant requests cancellation or a policy changeOperation-scope denial; zero effects of either type
Grant expires while request waitsDenial at dispatch, despite earlier queue admission
Exact authorized fixture passes all current checksOne mock dispatch attached to the original intent

Include the allowed fixture. A service that rejects everything has not demonstrated usable scoped authorization. Also test simultaneous attempts to claim a single-use grant. The claim and intent record need a concurrency-safe boundary so two workers cannot each observe “unused” and dispatch separate actions.

Record the caller identity, grant identifier, resource, operation, policy version, decision and intent identifier. Retain rejection reasons without copying secrets into logs. A positive model explanation, a passed schema and a successful login are separate observations from permission to dispatch.

Preserve the boundary through revocation and recovery

A workflow restart must not turn an expired or already claimed grant into unused authority. Preserve the authorization state alongside the external-effect record. The checkpoint-recovery guide explains why restoring local progress alone cannot establish what happened outside the process.

For a retry of an uncertain original submission, reconcile that intent instead of creating another action from a reused grant. If grant decisions are cached, define and test the delay before revocation takes effect; a short expiry is not immediate revocation. Removing authority does not reverse orders already accepted downstream. Keep account inspection and any corrective action as separately authorized work.

Start your next review with one research task. List every reachable tool and its eventual destination, identify the smallest useful grant, and try one forbidden account action against a mock. Verify the denial at the execution boundary and zero downstream dispatches. Then verify that the intended scoped action can pass. That pair of observations makes least privilege inspectable.

Keep the context with the example.

Each worked example is illustrative, with its sources and assumptions in the article. Read our editorial standards for authorship, verification and corrections.