Skip to content

Conversation

@jeffsmale90
Copy link
Contributor

@jeffsmale90 jeffsmale90 commented Sep 16, 2025

Summary

Add execution-permission decoding to SignatureController for eth_signTypedData_v4 delegation requests. If a delegation request is unable to be decoded into a coherent Execution Permission, reject external (not from origin: metamask) attempts to sign delegations for internal accounts. Adds decoded permission in signature request state for rendering downstream.

Why

Readable Permissions requires the ability to sign delegations, only when the delegation can be decoded to a permission that is then shown to the user.

The architecture is described in this document. Decoding has been added to GatorPermissionsController in #6556

Note: the request origin is always @metamask/gator-permission-snap (any other origin is rejected). Because of this, metadata is added to the 712 payload, defining the justification and origin which is the original origin of the request (the dapp).

Base automatically changed from feat/decodePermission to main September 16, 2025 18:44
@jeffsmale90 jeffsmale90 force-pushed the feat/decodePermission_signatureController branch 3 times, most recently from 217553e to 4dee17d Compare September 16, 2025 18:49
@jeffsmale90 jeffsmale90 changed the title Decode permissions in SignatureController feat: decode permissions in SignatureController Sep 17, 2025
@jeffsmale90 jeffsmale90 force-pushed the feat/decodePermission_signatureController branch 4 times, most recently from 8a636fc to 4b72727 Compare September 17, 2025 04:34
@jeffsmale90 jeffsmale90 marked this pull request as ready for review September 17, 2025 04:37
@jeffsmale90 jeffsmale90 force-pushed the feat/decodePermission_signatureController branch from 4b72727 to 21a7c84 Compare September 17, 2025 04:37
@jeffsmale90 jeffsmale90 requested review from a team as code owners September 17, 2025 04:37
cursor[bot]

This comment was marked as outdated.

@jeffsmale90 jeffsmale90 force-pushed the feat/decodePermission_signatureController branch from 21a7c84 to b4006dc Compare September 17, 2025 06:19
cursor[bot]

This comment was marked as outdated.

@jeffsmale90 jeffsmale90 force-pushed the feat/decodePermission_signatureController branch from b4006dc to 47460e5 Compare September 17, 2025 07:13
cursor[bot]

This comment was marked as outdated.

@jeffsmale90 jeffsmale90 force-pushed the feat/decodePermission_signatureController branch from 0ac0fd7 to b5b431f Compare September 17, 2025 07:46
@jeffsmale90 jeffsmale90 requested a review from a team as a code owner September 17, 2025 22:47
cursor[bot]

This comment was marked as outdated.

@jeffsmale90 jeffsmale90 force-pushed the feat/decodePermission_signatureController branch from bf157ae to 48d4d7b Compare September 18, 2025 01:17
cursor[bot]

This comment was marked as outdated.

@socket-security
Copy link

socket-security bot commented Sep 22, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​metamask/​gator-permissions-controller@​0.2.0971008390100

View full report

@jeffsmale90 jeffsmale90 force-pushed the feat/decodePermission_signatureController branch from 31cbe3c to 442a239 Compare September 22, 2025 03:03
cursor[bot]

This comment was marked as outdated.

@jeffsmale90 jeffsmale90 force-pushed the feat/decodePermission_signatureController branch from 442a239 to 8378da7 Compare September 22, 2025 03:09
cursor[bot]

This comment was marked as outdated.

@jeffsmale90 jeffsmale90 force-pushed the feat/decodePermission_signatureController branch from 8378da7 to a3a38b6 Compare September 22, 2025 03:30
cursor[bot]

This comment was marked as outdated.

};

/** Metadata use in the signTypedData request when handling EIP-7715 execution permission requests */
export type ExecutionPermissionMetadata = {
Copy link
Member

Choose a reason for hiding this comment

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

Minor, this isn't necessarily specific to the permissions but general metadata.

/** Metadata use in the signTypedData request when handling EIP-7715 execution permission requests */
export type ExecutionPermissionMetadata = {
origin: string;
justification: string;
Copy link
Member

Choose a reason for hiding this comment

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

Minor, JSDoc on properties?

@jeffsmale90 jeffsmale90 enabled auto-merge (squash) September 23, 2025 09:13
caveats,
} as unknown as MessageParamsTyped,
],
[
Copy link

Choose a reason for hiding this comment

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

Bug: Test Label Mismatch Causes Confusion

A test case in the decodePermissionFromRequest suite is mislabeled "Missing authority." The test data for this case actually omits the delegator field, not authority. This leads to duplicate test descriptions, making test output unclear.

Fix in Cursor Fix in Web

await this.#approveAndSignRequest(metadata, traceContext);
} catch (error) {
log('Signature request failed', error);
log('Signature request failed', (error as Error).message);
Copy link

Choose a reason for hiding this comment

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

Bug: Error Logging Fails with Non-Error Objects

The updated error logging in SignatureController.ts assumes caught errors are always Error objects. As JavaScript allows throwing any value, accessing .message on non-Error types can lead to undefined being logged or a runtime error, losing valuable debugging context.

Fix in Cursor Fix in Web

@jeffsmale90 jeffsmale90 merged commit 09d848c into main Sep 23, 2025
239 checks passed
@jeffsmale90 jeffsmale90 deleted the feat/decodePermission_signatureController branch September 23, 2025 09:22
This was referenced Sep 23, 2025
jeffsmale90 added a commit that referenced this pull request Sep 24, 2025
## Explanation

Releases @metamask/signature-controller@34.0.0

### Added

- Add two new controller state metadata properties: `includeInStateLogs`
and `usedInUi` ([#6473](#6473))
- **BREAKING:** Decode delegation permissions using
`@metamask/gator-permissions-controller` when calling
`newUnsignedTypedMessage`, adds `@metamask/gator-permissions-controller`
as a peer dependency.
([#6619](#6619))

### Changed

- Bump `@metamask/controller-utils` from `^11.12.0` to `^11.14.0`
([#6620](#6620),
[#6629](#6629))
- Bump `@metamask/base-controller` from `^8.1.0` to `^8.4.0`
([#6355](#6355),
[#6465](#6465),
[#6632](#6632))
- Bump `@metamask/utils` from `^11.4.2` to `^11.8.0`
([#6588](#6588))
- Bump `@metamask/network-controller` from `^24.1.0` to `^24.2.0`
([#6678](#6678))
- Bump `@metamask/keyring-controller` from `^23.0.0` to `^23.1.0`
([#6590](#6590))
- Bump `@metamask/accounts-controller` from `^33.0.0` to `^33.1.0`
([#6572](#6572))
github-merge-queue bot pushed a commit to MetaMask/metamask-extension that referenced this pull request Sep 25, 2025
…ded permission (#36054)

## **Description**


This feature is only enabled in Flask.

When a dapp requests an EIP-7715 Readable Permission, the user must sign
with `eth_signTypedData_v4`, but it's important that the user can
understand what is being signed. This PR surfaced the decoded permission
information in a new Sign Permission view.

When a `eth_signTypedData_v4` request is received by
`@metamask/signature-controller` that appears to be a delegation, it
will pass this request to `@metamask/gator-permissions-controller` to
decode the request into the originating permission. If this is
successful, `@metamask/signature-controller` attaches the decoded
permission to the request `metadata`.

This PR adds a new view showing the details of the permission that the
user is signing. This does not implement the final design, and focusses
only on introducing the functionality to extension. Further iteration
will be made to improve the UX. As such, no internationalization has
been included in this change.

A couple important points to note:
- if `GATOR_PERMISSIONS_ENABLED` is not true, the request will be
rejected here (this should never happen, because the method
`wallet_requestExecutionPermissions` will not allow requests if the
feature is not enabled
- if the origin is not the configured Gator Permissions Snap, the
permission will not be decoded by the `GatorPermissionsController`
- if the request is for a delegation signature, and no permission is
decoded, the SignatureController will reject the request
- This feature is only being released into Flask at this stage - future
PRs will refine the UX before this is released to end-users

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/36054?quickstart=1)

## **Changelog**

CHANGELOG entry: presents a Permission confirmation view when a decoded
permission exists on signTypedData metadata. Flask only.

## **Related issues**

These PRs are related to this feature:
- Introduce GatorPermissionsController to mobile
MetaMask/metamask-mobile#20006
- Decode permissions in SignatureController
MetaMask/core#6619
- Method 'decodePermissionFromPermissionContextForOrigin' is now
synchronous MetaMask/core#6656
- Add `decodePermissionFromPermissionContextForOrigin` to
`GatorPermissionsController` MetaMask/core#6556

## **Manual testing steps**

1. Run the 7715 gator snaps locally
2. Build MetaMask flask with `GATOR_PERMISSIONS_ENABLED=true` and
`GATOR_PERMISSIONS_PROVIDER_SNAP_ID=local:http://localhost:8082`
2. Open the 7715 gator snap page
3. Install snaps if necessary, by clicking "Install kernel snap", then
"Install provider snap"
4. Select the appropriate permission type and parameters
5. Click "Grant Permission"
6. Adjust the requested permission as necessary
7. Click "Grant"

Expect to see the sign permission screen:

## **Screenshots/Recordings**

<img width="396" height="852" alt="image"
src="https://github.com/user-attachments/assets/b45e5a7d-ccaa-4456-be65-4b990bc2ea2d"
/>

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
github-merge-queue bot pushed a commit to MetaMask/metamask-mobile that referenced this pull request Oct 21, 2025
## **Description**

Updates the dependency on @metamask/signature-controller to 34.0.0

This version bump introduces a dependency on
@metamask/gator-permissions-controller via
`GatorPermissionsControllerDecodePermissionFromPermissionContextForOriginAction`
which has been added to signature-controller-messenger.

## **Changelog**

From SignatureController
https://github.com/MetaMask/core/blob/main/packages/signature-controller/CHANGELOG.md:

### @metamask/signature-controller 34.0.0

#### Added

- Add two new controller state metadata properties: includeInStateLogs
and usedInUi (MetaMask/core#6473)
- Decode delegation permissions using
`@metamask/gator-permissions-controller` when calling
`newUnsignedTypedMessage`
([#6619](MetaMask/core#6619))

#### Changed

- Bump @metamask/controller-utils from ^11.12.0 to ^11.14.0
(MetaMask/core#6620,
MetaMask/core#6629)
- Bump @metamask/base-controller from ^8.1.0 to ^8.4.0
(MetaMask/core#6355,
MetaMask/core#6465,
MetaMask/core#6632)
- Bump @metamask/utils from ^11.4.2 to ^11.8.0
(MetaMask/core#6588)

### @metamask/signature-controller 33.0.0

#### Changed

- BREAKING: Bump peer dependency @metamask/accounts-controller from
^32.0.0 to ^33.0.0 (MetaMask/core#6345)
- BREAKING: Bump peer dependency @metamask/keyring-controller from
^22.0.0 to ^23.0.0 (MetaMask/core#6345)
- Bump @metamask/base-controller from ^8.0.1 to ^8.1.0
(MetaMask/core#6284)
- Bump @metamask/controller-utils from ^11.11.0 to ^11.12.0
(MetaMask/core#6303)

CHANGELOG entry: null

## **Screenshots/Recordings**

## **Pre-merge author checklist**

- [ ] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Upgrade @metamask/signature-controller to ^34 and allow
GatorPermissionsController decode action in the signature controller
messenger.
> 
> - **Dependencies**:
>   - Bump `@metamask/signature-controller` to `^34.0.0`.
> - **Engine**:
> -
**`app/core/Engine/messengers/signature-controller-messenger/signature-controller-messenger.ts`**:
> - Add
`GatorPermissionsControllerDecodePermissionFromPermissionContextForOriginAction`
and allow
`GatorPermissionsController:decodePermissionFromPermissionContextForOrigin`
in `allowedActions`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
657705e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants