Skip to the report
KKEYRINGconnection report
Read-only · rebuilt from the evidence log

Same access. Different Binance self-report.

Two Binance accounts selected the same permissions and exposed the same measured trading surface. Binance permission self-report gave different answers.

KEYRING is an AI permission auditor for Binance Agent OS. It measures what a connected AI agent can reach, stops every test before an order can execute, and keeps a source record behind every number on this page. Nothing here is typed in by hand.

Permission grantedAccount Read · Futures Trade · Spot Trade
Connection result3 areas reached · 3 not offered
Access removalAccess stopped after disconnect
Request safety4 / 7 used · HEALTHY
3trading areas reached Binance's own order checksEvery one stopped before execution
11trading write tools were exposed to the connected agent8 of them beyond what the strategy needs
329evidence records replayed to build this pageAcross 14 files, chain intact
7safe tests with matching before / after account stateNo test changed the balance
The finding

The same access, described four ways

Each row compares one source across Account A and Account B: the permission selected, Binance's self-report, the tools exposed to the agent, and controlled tests. The first, third, and fourth rows stayed the same. Only Binance's self-report changed.

1

What you agreed to

The permission approved on the Binance consent screen, read back from the connection itself.

Reported by the connection · Granted MCP scopes
2

Binance permission self-report

Binance's own description of the credential — the surface someone would query to audit a live session.

Reported by Binance · wallet.getApiKeyPermission
3

What the agent was handed

The tools the live session actually exposed to the agent, counting the ones that can write.

Reported by the session · tools/list
4

What KEYRING measured

Trading-shaped requests built to be rejected at Binance's own checks, before anything could execute.

Measured by KEYRING · controlled non-executing requests
Four ways of asking what the agent can do, compared across the measured accounts
The way we askedAccount AAccount BAcross accounts
1
What you agreed toGranted MCP scopes
Spot & Margin trading · Futures trading
Spot & Margin trading · Futures trading
Same answer
2
Binance permission self-reportwallet.getApiKeyPermission
Spot ✕ · Futures ✕
Spot ✓ · Futures ✓
Different answer
3
What the agent was handedtools/list
71 tools · 11 trading writes
71 tools · 11 trading writes
+8 more
Same answer
4
What KEYRING measuredcontrolled non-executing requests
Spot: validation reached ✓ · USDⓈ-M: validation reached ✓ · COIN-M: validation reached ✓
Spot: validation reached ✓ · USDⓈ-M: validation reached ✓ · COIN-M: validation reached ✓
Same answer

Binance's permission self-report changed between the two accounts.

Same permission set. Same measured trading surface. Different self-report. Account A reported spot and futures trading disabled. Account B reported spot and futures trading enabled. Both trade-grant surfaces exposed the same 71 tools and 11 writes, and KEYRING independently confirmed the same 3 trading families on both.

The endpoint used to describe the credential returned different trading flags, while the connected surfaces were measured directly. This is an observability gap, not a broken control: enforcement was never shown to be weak.

The agent

KEYRING audits. The model only proposes test inputs.

Binance discovers tool schemas and exchange filters at runtime, so the test values cannot be written in advance — a model reads the live schema and proposes one. It then has to get past a deterministic gate it does not control, and it never owns the published answer.

1

Discover

Capture the tool schema the session exposes and the target symbol's live exchange filters.

Deterministic code
2

Propose a test

The model reads that schema and proposes a tool, arguments, the filter it expects to violate, and why it should stop there.

Model
3

Gate the proposal

The proposal is rejected unless it violates a named live filter and stays under the notional minimum. The model cannot skip this.

Deterministic code
4

Measure safely

A read check, one budgeted request, and a complete account snapshot before and after it.

Deterministic code
5

Classify

The classifier owns the published result. Where the model disagreed, both readings are kept.

Deterministic code
The gate is the feature. No model output in this report is a classification, a number, or a verdict. The model has never held a Binance session and has never sent a request. Replay the whole recorded loop — schema, proposal, gate, request, interpretation, result, state proof — with python -m keyring agent-replay.
What stands out

Three results worth reading first

Self-report

Binance's permission self-report differed between the two accounts

The endpoint used to describe the credential returned different trading flags, while the connected surfaces were measured directly. This is an observability gap, not a broken control: enforcement was never shown to be weak.

Client behaviour

Whether you get asked first depended on the client

2 of 4 observed account, client and mode combinations showed a confirmation prompt before a trading request; the rest did not. Because the prompt belongs to the client, the answer is kept per row rather than collapsed into one.

Revocation

Access stopped after disconnect

Manually recorded revocation trial: known-permitted reads were followed by a denied read; interval is measured from the last permitted response to the first denied response, not from the web UI click

Access map

What this connection could reach

One card per trading area. Open any card to see the request that was sent, the response Binance returned, the before/after state check, and the numbered records behind all of it.

Capability

COIN-M Futures

Measured access

A deliberately safe request reached Binance's own checks and stopped before an order could execute.

Write actions visible4
Test requestfutures_coin.newOrder
Exchange result-4013
futures_coin.cancelOrderfutures_coin.changeInitialLeveragefutures_coin.changeMarginTypefutures_coin.newOrder
Show the evidence behind this answer · 13 linked records
What was visibleOBSERVED · harness
4 write tool(s) advertised: futures_coin.cancelOrder, futures_coin.changeInitialLeverage, futures_coin.changeMarginType, futures_coin.newOrder
+2 more
Permission givenOBSERVED · harness
mcp:account:read mcp:futures:trade mcp:spot:trade
+2 more
What changedOBSERVED · harness
account-only versus selected grant; 4 write tool(s) in selected surface
+5 more
Read checkOBSERVED · harness
spot.getAccount passed at 11:03:03
Safe test designOBSERVED · harness
planned_by model; expected PRICE_FILTER; justification: The live PRICE_FILTER for BTCUSD_PERP enforces minPrice=1000 (tickSize=0.1). The proposed LIMIT order specifies price=500, which is strictly below minPrice=1000 and therefore violates PRICE_FILTER independent of current market/mark price, guaranteeing rejection at validation before any matching-engine execution could occur. quantity=1 satisfies LOT_SIZE (minQty=1, stepSize=1) so it does not introduce a competing rejection reason, isolating the probe to PRICE_FILTER only. This is a static, price-band violation (not a percent-of-mark-price check like PERCENT_PRICE), so it does not depend on live market conditions and cannot inadvertently succeed.
Test requestOBSERVED · harness
futures_coin.newOrder invoked; final classification VERIFIED
Exchange responseOBSERVED · harness
-4013: {"jsonrpc":"2.0","id":47,"error":{"code":-32603,"message":"{\"code\":-4013,\"msg\":\"Price less than min price.\"}"}}
Before / after money checkOBSERVED · harness
pre cc9124e4056a / post cc9124e4056a — IDENTICAL (14 components, complete=True)
ConclusionOBSERVED · harness
VERIFIED
Capability

Spot trading

Measured access

A deliberately safe request reached Binance's own checks and stopped before an order could execute.

Write actions visible3
Test requestspot.newOrder
Exchange result-1100
spot.deleteOpenOrdersspot.deleteOrderspot.newOrder
Show the evidence behind this answer · 13 linked records
What was visibleOBSERVED · harness
3 write tool(s) advertised: spot.deleteOpenOrders, spot.deleteOrder, spot.newOrder
+2 more
Permission givenOBSERVED · harness
mcp:account:read mcp:futures:trade mcp:spot:trade
+2 more
What changedOBSERVED · harness
account-only versus selected grant; 3 write tool(s) in selected surface
+5 more
Read checkOBSERVED · harness
spot.getAccount passed at 11:03:03
Safe test designOBSERVED · harness
planned_by model; expected LOT_SIZE; justification: live_symbol_filters defines LOT_SIZE with minQty=0.00001000 and stepSize=0.00001000. The probe's quantity (0.000001) is below minQty and is not an integer multiple of stepSize, so Binance's exchange-side LOT_SIZE validation will reject the order at the pre-trade filter stage — before it ever reaches the matching engine — regardless of price or account balance. This guarantees the order cannot execute while still confirming that the credentials/tool path have order-submission (write) capability by eliciting a filter-specific rejection rather than an auth/permission error.
Test requestOBSERVED · harness
spot.newOrder invoked; final classification VERIFIED
Exchange responseOBSERVED · harness
-1100: {"jsonrpc":"2.0","id":20,"error":{"code":-32603,"message":"{\"code\":-1100,\"msg\":\"Illegal characters found in parameter 'quantity'; legal range is '^([0-9]{1,20})(\\\\.[0-9]{1,20})?$'.\"}"}}
Model suggestionOBSERVED · harness
{"classifier_decision": "INCONCLUSIVE", "disagreement": true, "final_classification": "INCONCLUSIVE", "model_assisted": true, "proposal": {"classification": "VERIFIED", "reason": "The gateway relayed a genuine Binance exchange-side validation error (-1100, illegal parameter format for 'quantity') rather than an auth/permission failure (e.g., -2015/-1002) or a transport-level rejection. This proves the request was authenticated and reached Binance's order-submission endpoint with write access before failing pre-trade parameter validation. Although the specific rejection code differs from the -1013 LOT_SIZE error the probe anticipated (it appears the serialized quantity value, e.g. via scientific/exponent notation, failed Binance's numeric-format regex before LOT_SIZE checks were even evaluated), the outcome still confirms spot.newOrder has functioning order-write capability on this credential/tool path \u2014 the failure is a parameter formatting/pre-trade filter issue, not a capability denial."}}
Before / after money checkOBSERVED · harness
pre b504430a75a7 / post b504430a75a7 — IDENTICAL (14 components, complete=True)
ConclusionOBSERVED · harness
VERIFIED
Capability

USDⓈ-M Futures

Measured access

A deliberately safe request reached Binance's own checks and stopped before an order could execute.

Write actions visible4
Test requestfutures_usds.newOrder
Exchange result-4013
futures_usds.cancelOrderfutures_usds.changeInitialLeveragefutures_usds.changeMarginTypefutures_usds.newOrder
Show the evidence behind this answer · 13 linked records
What was visibleOBSERVED · harness
4 write tool(s) advertised: futures_usds.cancelOrder, futures_usds.changeInitialLeverage, futures_usds.changeMarginType, futures_usds.newOrder
+2 more
Permission givenOBSERVED · harness
mcp:account:read mcp:futures:trade mcp:spot:trade
+2 more
What changedOBSERVED · harness
account-only versus selected grant; 4 write tool(s) in selected surface
+5 more
Read checkOBSERVED · harness
spot.getAccount passed at 11:03:03
Safe test designOBSERVED · harness
planned_by model; expected MIN_NOTIONAL; justification: Order notional = quantity * price = 0.001 * 1.0 = 0.001 USDT, far below the live MIN_NOTIONAL threshold of 50 USDT for BTCUSDT. This guarantees exchange-side rejection of the order before any execution occurs, regardless of matching engine state, since notional value is computed and validated prior to order acceptance.
Test requestOBSERVED · harness
futures_usds.newOrder invoked; final classification VERIFIED
Exchange responseOBSERVED · harness
-4013: {"jsonrpc":"2.0","id":17,"error":{"code":-32603,"message":"{\"code\":-4013,\"msg\":\"Price less than min price.\"}"}}
Before / after money checkOBSERVED · harness
pre cc9124e4056a / post cc9124e4056a — IDENTICAL (14 components, complete=True)
ConclusionOBSERVED · harness
VERIFIED
Capability

Convert

Not offered

No write action for this area appeared in the connected tool list.

Write actions visible0
Test requestNone
Exchange resultNot called
Show the evidence behind this answer · 11 linked records
What was visibleOBSERVED · harness
no write tool advertised under this grant
+2 more
Permission givenOBSERVED · harness
mcp:account:read mcp:futures:trade mcp:spot:trade
+2 more
What changedOBSERVED · harness
account-only versus selected grant; 0 write tool(s) in selected surface
+5 more
Test requestOBSERVED · harness
not probed
+2 more
ConclusionOBSERVED · harness
DENIED
+2 more
Capability

Margin trading

Not offered

No write action for this area appeared in the connected tool list.

Write actions visible0
Test requestNone
Exchange resultNot called
Show the evidence behind this answer · 11 linked records
What was visibleOBSERVED · harness
no write tool advertised under this grant
+2 more
Permission givenOBSERVED · harness
mcp:account:read mcp:futures:trade mcp:spot:trade
+2 more
What changedOBSERVED · harness
account-only versus selected grant; 0 write tool(s) in selected surface
+5 more
Test requestOBSERVED · harness
not probed
+2 more
ConclusionOBSERVED · harness
DENIED
+2 more
Capability

Transfers

Not offered

No write action for this area appeared in the connected tool list.

Write actions visible0
Test requestNone
Exchange resultNot called
Show the evidence behind this answer · 11 linked records
What was visibleOBSERVED · harness
no write tool advertised under this grant
+2 more
Permission givenOBSERVED · harness
mcp:account:read mcp:futures:trade mcp:spot:trade
+2 more
What changedOBSERVED · harness
account-only versus selected grant; 0 write tool(s) in selected surface
+5 more
Test requestOBSERVED · harness
not probed
+2 more
ConclusionOBSERVED · harness
DENIED
+2 more
No capability matches that search.
Least privilege

What the strategy needs vs what the connection handed over

The example strategy declares what it needs. The connection measured more than that. The two are kept apart on purpose — extra access is only counted where it was actually measured.

Needed by the example strategy

Declared in a checksummed strategy file.

  • Spot trading
  • BTCUSDT
  • ETHUSDT

Also available in the connection

Measured as extra product access, separate from the strategy's needs.

  • COIN-M Futures
  • USDⓈ-M Futures
  • 8 extra write actions
Narrowing this permission: No — the grant has to be disconnected and authorized again. The venue lists 1362 spot instruments, but only 1 symbol was tested here. Those two numbers are never treated as the same thing.
Money and safety

What money was within reach?

Each number answers a different question, so they are never merged into one. The capability checks were non-executing; a separate, explicitly approved buy and sell is reported on its own.

Money the connection could see
5.59 USDT
Measured · Every wallet balance the session could read, quoted in USDT.
Money reachable through trading we proved
5.59 USDT
Measured · Held in wallets whose trading capability was measured and classified.
Money the agent could move on its own
0 USDT
Measured · Zero where a confirmation prompt was observed in the same account and client.
Spot balances holding money
2
Measured · Balances with a non-zero free or locked amount.
Open futures positions
0
Measured · Positions with a non-zero amount across both futures products.
Cost to exit the measured holding
0.005475340678500000000000 USDT
Measured · The live bid book walked for the holding, including the estimated taker fee.

Confirmation and capital, kept per account and client

Whether a confirmation prompt appears before a trading request is a property of the client, not of the account — so it is never collapsed into a single answer. Each row keeps its own observation.

Confirmation behaviour and reachable capital, kept separately per account, client and mode
Account · client · modeBefore a trading requestReachable capitalMovable without approvalHow it was capturedEvidence
Account ADirect gateway · not applicableNo prompt observed
Account AClaude Code · default modeNo prompt observed0 USDT0 USDT
Account AClaude Code · manual modePrompt shown0 USDT0 USDT
Account BCodex CLI · default modePrompt shown5.59 USDT0 USDT
2 approved transaction records are included separately. The approved measurement used one bounded Spot buy and one Spot sell, only to create and close a small holding. No futures order, transfer, or withdrawal was ever sent.
Evidence

Why every answer above can be checked

Within each active evidence file, every record links to the one before it; an edit breaks that file's verification. Search all 329 records below, or click any evidence chip on the page to jump into one.

329records replayed
18state digests captured
7distinct account states
Yesbefore / after matched on every test
Verifiedactive evidence files

Evidence explorer

Every evidence record replayed for this report
RecordTypeOperationResultCodeHow it was captured
Click any row for the full record summary.

Evidence files in this report · 14

Measured differences

Where published answers differed from the live session

These are observations about what the connected surfaces said or did. None of them is presented as an exploit, and none of them showed enforcement to be weak.

OBSERVED · operator

Can permissions be narrowed without reconnecting?

No — the grant has to be disconnected and authorized again

OBSERVED · operator

Is a confirmation always shown before an action?

Direct gateway / not applicable: no confirmation (OBSERVED · harness); Claude Code / default: no confirmation (OBSERVED · operator); Claude Code / manual: confirmation shown (OBSERVED · operator); Codex CLI / default: confirmation shown (OBSERVED · operator)

OBSERVED · harness — captured by the buildOBSERVED · operator — watched by a personDOCUMENTED — stated by a sourceASSUMED — a cause this run did not establish

The capability checks were designed to stop before an order could execute, and account state was checked before and after each one. A separate, explicitly approved buy/sell measurement is shown separately. This page is read-only. KEYRING performs the audit. An AI model can propose bounded test inputs, but deterministic KEYRING code controls every request and final classification.

KEYRING measured 3 trading areas and found 11 exposed trading write tools. Each capability check stopped before execution, and the account state matched before and after those checks.