Skip to content

feat: implement TIP-1011 enhanced access key permissions#3384

Merged
0xKitsune merged 31 commits intomainfrom
tanishk/tip-1011-primitives-exact
Apr 1, 2026
Merged

feat: implement TIP-1011 enhanced access key permissions#3384
0xKitsune merged 31 commits intomainfrom
tanishk/tip-1011-primitives-exact

Conversation

@legion2002
Copy link
Copy Markdown
Contributor

@legion2002 legion2002 commented Mar 30, 2026

Implements TIP-1011 end to end for T3 access keys. Adds periodic TIP-20 spending limits, per-target and per-selector call scopes, and recipient-constrained token calls across the spec, authorization payload, AccountKeychain precompile, runtime enforcement, and txpool admission.

The key-authorization payload now carries exact RLP and JSON semantics for limits and allowed_calls, including the distinction between unrestricted keys and deny-all scoped keys. The precompile persists the new restriction state, validates uniqueness and constrained-selector invariants, exposes the new allowed-call and spending-limit interfaces, hides stale scopes for revoked or expired keys, and keeps the T3 access-key creation restrictions intact.

Handler and txpool validation now reject malformed TIP-1011 authorizations before execution and enforce selector and recipient scoping consistently with onchain storage. The diff also extends coverage for RLP roundtrips, periodic rollover, allowed-call normalization, recipient-constrained TIP-20 selectors, and access-key execution paths.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 30, 2026

✅ Changelog found on PR.

Edit changelog

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d11fad3e41

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
Contributor

@0xKitsune 0xKitsune left a comment

Choose a reason for hiding this comment

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

Overall lgtm but left a few additional comments regarding missing tests.

0xKitsune

This comment was marked as duplicate.

Co-authored-by: 0xrusowsky <90208954+0xrusowsky@users.noreply.github.com>
}

/// Root-only create-or-replace updates for one or more target call scopes.
pub fn set_allowed_calls(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This seems valid, is there a reason we dont emit an event when scope is changed?

Comment on lines +478 to +480
if scopes.is_empty() {
return Ok(());
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Isnt this what the remaining logic is doing? If scopes is empty we are returning early and allowing any calls from the key. If scopes is not empty, we upsert the target scope and flips the is_scoped flag. Lmk if I am missing something though.

Comment on lines +563 to +576
let mut rules = Vec::new();

for selector in selectors {
let recipients: Vec<Address> = self.key_scopes[key_hash].target_scopes[target]
.selector_scopes[selector]
.recipients
.read()?
.into();

rules.push(SelectorRule {
selector,
recipients,
});
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: consider using collect, feel free to ignore though if preferred.

let rules = selectors
    .into_iter()
    .map(|selector| {
        let recipients: Vec<Address> = self.key_scopes[key_hash].target_scopes[target]
            .selector_scopes[selector]
            .recipients
            .read()?
            .into();
        Ok(SelectorRule { selector, recipients })
    })
    .collect::<Result<Vec<_>>>()?;

&& subject.matches_spending_limit_update(&updates.spending_limit_spends)
&& let Some(ref mut provider) = state_provider
&& exceeds_spending_limit(provider, subject, tx.transaction.fee_token_cost())
&& exceeds_spending_limit(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

we will address this in a follow up tx pool PR

"too many call scopes in key authorization",
)));
}

Copy link
Copy Markdown
Contributor Author

@legion2002 legion2002 Apr 1, 2026

Choose a reason for hiding this comment

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

addressing in #3422

Stacks on #3384.

Replaces nested `Option<Vec<_>>` key-scope fields with vec-based
semantics for `selector_rules` and `recipients`, and canonicalizes empty
nested lists to omitted trailing RLP fields while still decoding
omitted/`0x80`/`0xc0` as allow-all.

Updates the TIP, handler, txpool validation, and focused tests so empty
selector lists mean address-only scope and empty recipient lists mean no
recipient restriction.
}
}

if spec.is_t3() {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

addressing in #3422

keychain
.set_transaction_key(access_key_addr)
.map_err(|e| EVMError::Custom(e.to_string()))
.map_err(|e| EVMError::Custom(e.to_string()))?;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

addressed in - 5162f3c

@legion2002 legion2002 added the cyclops Trigger Cyclops PR audit label Apr 1, 2026
@tempoxyz-bot
Copy link
Copy Markdown

tempoxyz-bot commented Apr 1, 2026

👁️ Cyclops Security Review

599511b

🧭 Auditing · mode=normal · workers 0/3 done (3 left) · verify pending 0

Worker Engine Progress Status
pr-3384-w1 gemini-3.1-pro-preview 🔍 thread-1 · · Running
pr-3384-w2 amp/deep 🔍 thread-1 · · Running
pr-3384-w3 gpt-5.4 🔍 thread-1 · · Running
⚙️ Controls
  • 🚀 Keep only 1 remaining iteration per worker after the current work finishes.
  • 👀 Keep only 2 remaining iterations per worker after the current work finishes.
  • ❤️ Let only worker 1 continue; other workers skip queued iterations.
  • 😄 Let only worker 2 continue; other workers skip queued iterations.
  • 🎉 End faster by skipping queued iterations and moving toward consolidation.
  • 😕 Stop active workers/verifiers now and start consolidation immediately.

📜 3 events

🔍 pr-3384-w1 iter 1/3 [audit-ripple.md]
🔍 pr-3384-w3 iter 1/3 [audit-deep-focus.md]
🔍 pr-3384-w2 iter 1/3 [audit-focused.md]

@legion2002 legion2002 added cyclops Trigger Cyclops PR audit and removed cyclops Trigger Cyclops PR audit labels Apr 1, 2026
@tempoxyz-bot
Copy link
Copy Markdown

tempoxyz-bot commented Apr 1, 2026

👁️ Cyclops Security Review

79c51af

🧭 Auditing · mode=normal · workers 0/3 done (3 left) · verify pending 1

Worker Engine Progress Status
pr-3384-w1 gemini-3.1-pro-preview 🚨 thread-1 🔍 thread-2 · Running
pr-3384-w2 amp/deep 🔍 thread-1 · · Running
pr-3384-w3 gpt-5.4 🔍 thread-1 · · Running

Findings

# Finding Severity Verification Threads
1 Missing Intrinsic Gas Validation for Dynamic Scope Validation Causes Undercharge DoS High ⏳ Pending audit
⚙️ Controls
  • 🚀 Keep only 1 remaining iteration per worker after the current work finishes.
  • 👀 Keep only 2 remaining iterations per worker after the current work finishes.
  • ❤️ Let only worker 1 continue; other workers skip queued iterations.
  • 😄 Let only worker 2 continue; other workers skip queued iterations.
  • 🎉 End faster by skipping queued iterations and moving toward consolidation.
  • 😕 Stop active workers/verifiers now and start consolidation immediately.

📜 7 events

🔍 pr-3384-w1 iter 1/3 [audit-ripple.md]
🔍 pr-3384-w2 iter 1/3 [audit-focused.md]
🔍 pr-3384-w3 iter 1/3 [audit-deep-focus.md]
🚨 pr-3384-w1 iter 1 — finding | Thread
🚨 Finding: Missing Intrinsic Gas Validation for Dynamic Scope Validation Causes Undercharge DoS (High) | Thread
🔍 pr-3384-w1 iter 2/3 [audit-historical.md]
🔬 Verifying: Missing Intrinsic Gas Validation for Dynamic Scope Validation Causes Undercharge DoS | Thread

@tempoxyz-bot
Copy link
Copy Markdown

tempoxyz-bot commented Apr 1, 2026

👁️ Cyclops Security Review

79c51af

🧭 Auditing · mode=normal · workers 0/3 done (3 left) · verify pending 0

Worker Engine Progress Status
pr-3384-w1 gemini-3.1-pro-preview 🔍 thread-1 · · Running
pr-3384-w2 amp/deep 🔍 thread-1 · · Running
pr-3384-w3 gpt-5.4 🔍 thread-1 · · Running
⚙️ Controls
  • 🚀 Keep only 1 remaining iteration per worker after the current work finishes.
  • 👀 Keep only 2 remaining iterations per worker after the current work finishes.
  • ❤️ Let only worker 1 continue; other workers skip queued iterations.
  • 😄 Let only worker 2 continue; other workers skip queued iterations.
  • 🎉 End faster by skipping queued iterations and moving toward consolidation.
  • 😕 Stop active workers/verifiers now and start consolidation immediately.

📜 3 events

🔍 pr-3384-w1 iter 1/3 [audit-ripple.md]
🔍 pr-3384-w3 iter 1/3 [audit-deep-focus.md]
🔍 pr-3384-w2 iter 1/3 [audit-focused.md]

decofe and others added 4 commits April 1, 2026 20:24
Co-Authored-By: 0xKitsune <77890308+0xKitsune@users.noreply.github.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019d4ab7-a146-70d4-bcf2-8aa7032a9a54
Updates keychain gas estimation snapshots to match new values from
TIP-1011 permission changes, and adds missing changelog entry to fix the
CI changelog check.

Prompted by: daniel

Co-authored-by: 0xKitsune <77890308+0xKitsune@users.noreply.github.com>
The key_type mismatch check is gated behind spec.is_t3(), so the test
needs a T3 EVM to exercise the rejection path.

Co-Authored-By: 0xKitsune <77890308+0xKitsune@users.noreply.github.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019d4ac0-09dc-7361-9cc6-035d3f173f9c
@0xKitsune 0xKitsune added this pull request to the merge queue Apr 1, 2026
Merged via the queue into main with commit 5df1837 Apr 1, 2026
37 checks passed
@0xKitsune 0xKitsune deleted the tanishk/tip-1011-primitives-exact branch April 1, 2026 23:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cyclops Trigger Cyclops PR audit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants