Conversation
Adds "What if Someone Else Runs My Action?" section to the patterns doc. Covers two answers: (1) for pure actions, it doesn't matter, and (2) for restricted access, use Dashboard API key scoping as the primary control with in-action signature verification as defense-in-depth. Includes a warning against gating on plain js_params values. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds guidance to the Lit Actions “Patterns” documentation to address concerns about unauthorized execution of Action-Identity–signed Lit Actions, and recommends practical access-control layers for actions that require restriction.
Changes:
- Introduces a new “What if Someone Else Runs My Action?” subsection under Action-Identity Signing.
- Documents when “someone else running the same CID” is harmless for pure/side-effect-free actions.
- Recommends API-key scoping as the primary control and in-action cryptographic verification as defense-in-depth, with an explicit warning against trusting plain
js_params.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ```javascript | ||
| async function main({ signature, message }) { | ||
| const ALLOWED_ADDRESS = "0xAbc123..."; // your PKP's wallet address | ||
|
|
||
| const recovered = ethers.utils.verifyMessage(message, signature); | ||
| if (recovered.toLowerCase() !== ALLOWED_ADDRESS.toLowerCase()) { | ||
| throw new Error("Unauthorized: caller signature does not match allowed address"); | ||
| } | ||
|
|
There was a problem hiding this comment.
The in-action signature check verifies address ownership, but the example uses a caller-supplied message without any freshness / anti-replay property. As written, a previously obtained (or leaked) {message, signature} pair can be replayed indefinitely to pass the gate. Consider documenting that the message should include a nonce and/or expiry (ideally server-generated) and that the action should verify freshness (e.g., via an external API, on-chain state, or other replay protection).
There was a problem hiding this comment.
Good catch. Added a note that the message should include a nonce or timestamp for replay protection, plus an inline comment in the code example. Fixed in ff55dd9.
The PKP address check is reliable when the group is configured so only a specific PKP can be used with the action — the ownership model enforces that callers can only use PKPs belonging to their account. Signature verification moves to method #3 as defense-in-depth. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Adds a new "What if Someone Else Runs My Action?" subsection to the Action-Identity Signing section of the patterns doc (
docs/lit-actions/patterns.mdx). Addresses the common concern about unauthorized action execution with two answers:Includes an explicit
<Note>warning against gating on plainjs_paramsvalues, since parameters are caller-supplied and trivially spoofable.Pre-Landing Review
Pre-Landing Review: No code issues found (docs-only change).
Adversarial review (Claude + Codex): Both models independently flagged that the original draft's gating example (checking a plain PKP public key from
js_params) was bypassable. The example was rewritten to use signature verification (ethers.utils.verifyMessage) and the section now recommends Dashboard API key scoping as the primary access control.Test plan
🤖 Generated with Claude Code