1

I have created an admin user to manage my orders and granted the access for order view action only. (as below)

But the user can generate token via API and access all order i.e view, delete, etc resources.

How to restrict the access to orders view only?

ACL Permission assigned to user

2

I resolved the issue, it was core Magento bug.

Admin user with restricted "order create" access can "view", "cancel", etc via API

To fix I need to update the webapi.xml in Sales module.

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
    <route url="/V1/orders/:id" method="GET">
        <service class="Magento\Sales\Api\OrderRepositoryInterface" method="get"/>
        <resources>
            <resource ref="Magento_Sales::actions_view" />
        </resources>
    </route>
    <route url="/V1/orders" method="GET">
        <service class="Magento\Sales\Api\OrderRepositoryInterface" method="getList"/>
        <resources>
            <resource ref="Magento_Sales::actions_view" />
        </resources>
    </route>
    <route url="/V1/orders/:id/statuses" method="GET">
        <service class="Magento\Sales\Api\OrderManagementInterface" method="getStatus"/>
        <resources>
            <resource ref="Magento_Sales::actions_view" />
        </resources>
    </route>
    <route url="/V1/orders/:id/cancel" method="POST">
        <service class="Magento\Sales\Api\OrderManagementInterface" method="cancel"/>
        <resources>
            <resource ref="Magento_Sales::cancel" />
        </resources>
    </route>
    <route url="/V1/orders/:id/emails" method="POST">
        <service class="Magento\Sales\Api\OrderManagementInterface" method="notify"/>
        <resources>
            <resource ref="Magento_Sales::emails" />
        </resources>
    </route>
    <route url="/V1/orders/:id/hold" method="POST">
        <service class="Magento\Sales\Api\OrderManagementInterface" method="hold"/>
        <resources>
            <resource ref="Magento_Sales::hold" />
        </resources>
    </route>
    <route url="/V1/orders/:id/unhold" method="POST">
        <service class="Magento\Sales\Api\OrderManagementInterface" method="unHold"/>
        <resources>
            <resource ref="Magento_Sales::unhold" />
        </resources>
    </route>
    <route url="/V1/orders/:id/comments" method="POST">
        <service class="Magento\Sales\Api\OrderManagementInterface" method="addComment"/>
        <resources>
            <resource ref="Magento_Sales::comment" />
        </resources>
    </route>
    <route url="/V1/orders/:id/comments" method="GET">
        <service class="Magento\Sales\Api\OrderManagementInterface" method="getCommentsList"/>
        <resources>
            <resource ref="Magento_Sales::actions_view" />
        </resources>
    </route>
    <route url="/V1/orders/create" method="PUT">
        <service class="Magento\Sales\Api\OrderRepositoryInterface" method="save"/>
        <resources>
            <resource ref="Magento_Sales::create" />
        </resources>
    </route>
    <route url="/V1/orders/:parent_id" method="PUT">
        <service class="Magento\Sales\Api\OrderAddressRepositoryInterface" method="save"/>
        <resources>
            <resource ref="Magento_Sales::create" />
        </resources>
    </route>
    <route url="/V1/orders/items/:id" method="GET">
        <service class="Magento\Sales\Api\OrderItemRepositoryInterface" method="get"/>
        <resources>
            <resource ref="Magento_Sales::actions_view" />
        </resources>
    </route>
    <route url="/V1/orders/items" method="GET">
        <service class="Magento\Sales\Api\OrderItemRepositoryInterface" method="getList"/>
        <resources>
            <resource ref="Magento_Sales::actions_view" />
        </resources>
    </route>
    <route url="/V1/invoices/:id" method="GET">
        <service class="Magento\Sales\Api\InvoiceRepositoryInterface" method="get"/>
        <resources>
            <resource ref="Magento_Sales::sales_invoice" />
        </resources>
    </route>
    <route url="/V1/invoices" method="GET">
        <service class="Magento\Sales\Api\InvoiceRepositoryInterface" method="getList"/>
        <resources>
            <resource ref="Magento_Sales::sales_invoice" />
        </resources>
    </route>
    <route url="/V1/invoices/:id/comments" method="GET">
        <service class="Magento\Sales\Api\InvoiceManagementInterface" method="getCommentsList"/>
        <resources>
            <resource ref="Magento_Sales::sales_invoice" />
        </resources>
    </route>
    <route url="/V1/invoices/:id/emails" method="POST">
        <service class="Magento\Sales\Api\InvoiceManagementInterface" method="notify"/>
        <resources>
            <resource ref="Magento_Sales::sales_invoice" />
        </resources>
    </route>
    <route url="/V1/invoices/:id/void" method="POST">
        <service class="Magento\Sales\Api\InvoiceManagementInterface" method="setVoid"/>
        <resources>
            <resource ref="Magento_Sales::sales_invoice" />
        </resources>
    </route>
    <route url="/V1/invoices/:id/capture" method="POST">
        <service class="Magento\Sales\Api\InvoiceManagementInterface" method="setCapture"/>
        <resources>
            <resource ref="Magento_Sales::sales_invoice" />
        </resources>
    </route>
    <route url="/V1/invoices/comments" method="POST">
        <service class="Magento\Sales\Api\InvoiceCommentRepositoryInterface" method="save"/>
        <resources>
            <resource ref="Magento_Sales::sales_invoice" />
        </resources>
    </route>
    <route url="/V1/invoices/" method="POST">
        <service class="Magento\Sales\Api\InvoiceRepositoryInterface" method="save"/>
        <resources>
            <resource ref="Magento_Sales::sales_invoice" />
        </resources>
    </route>
    <route url="/V1/invoice/:invoiceId/refund" method="POST">
        <service class="Magento\Sales\Api\RefundInvoiceInterface" method="execute"/>
        <resources>
            <resource ref="Magento_Sales::sales_invoice" />
        </resources>
    </route>
    <route url="/V1/creditmemo/:id/comments" method="GET">
        <service class="Magento\Sales\Api\CreditmemoManagementInterface" method="getCommentsList"/>
        <resources>
            <resource ref="Magento_Sales::sales_creditmemo" />
        </resources>
    </route>
    <route url="/V1/creditmemos" method="GET">
        <service class="Magento\Sales\Api\CreditmemoRepositoryInterface" method="getList"/>
        <resources>
            <resource ref="Magento_Sales::sales_creditmemo" />
        </resources>
    </route>
    <route url="/V1/creditmemo/:id" method="GET">
        <service class="Magento\Sales\Api\CreditmemoRepositoryInterface" method="get"/>
        <resources>
            <resource ref="Magento_Sales::sales_creditmemo" />
        </resources>
    </route>
    <route url="/V1/creditmemo/:id" method="PUT">
        <service class="Magento\Sales\Api\CreditmemoManagementInterface" method="cancel"/>
        <resources>
            <resource ref="Magento_Sales::sales_creditmemo" />
        </resources>
    </route>
    <route url="/V1/creditmemo/:id/emails" method="POST">
        <service class="Magento\Sales\Api\CreditmemoManagementInterface" method="notify"/>
        <resources>
            <resource ref="Magento_Sales::sales_creditmemo" />
        </resources>
    </route>
    <route url="/V1/creditmemo/refund" method="POST">
        <service class="Magento\Sales\Api\CreditmemoManagementInterface" method="refund"/>
        <resources>
            <resource ref="Magento_Sales::sales_creditmemo" />
        </resources>
    </route>
    <route url="/V1/creditmemo/:id/comments" method="POST">
        <service class="Magento\Sales\Api\CreditmemoCommentRepositoryInterface" method="save"/>
        <resources>
            <resource ref="Magento_Sales::sales_creditmemo" />
        </resources>
    </route>
    <route url="/V1/creditmemo" method="POST">
        <service class="Magento\Sales\Api\CreditmemoRepositoryInterface" method="save"/>
        <resources>
            <resource ref="Magento_Sales::sales_creditmemo" />
        </resources>
    </route>
    <route url="/V1/order/:orderId/refund" method="POST">
        <service class="Magento\Sales\Api\RefundOrderInterface" method="execute"/>
        <resources>
            <resource ref="Magento_Sales::creditmemo" />
        </resources>
    </route>
    <route url="/V1/shipment/:id" method="GET">
        <service class="Magento\Sales\Api\ShipmentRepositoryInterface" method="get"/>
        <resources>
            <resource ref="Magento_Sales::shipment" />
        </resources>
    </route>
    <route url="/V1/shipments" method="GET">
        <service class="Magento\Sales\Api\ShipmentRepositoryInterface" method="getList"/>
        <resources>
            <resource ref="Magento_Sales::shipment" />
        </resources>
    </route>
    <route url="/V1/shipment/:id/comments" method="GET">
        <service class="Magento\Sales\Api\ShipmentManagementInterface" method="getCommentsList"/>
        <resources>
            <resource ref="Magento_Sales::shipment" />
        </resources>
    </route>
    <route url="/V1/shipment/:id/comments" method="POST">
        <service class="Magento\Sales\Api\ShipmentCommentRepositoryInterface" method="save"/>
        <resources>
            <resource ref="Magento_Sales::shipment" />
        </resources>
    </route>
    <route url="/V1/shipment/:id/emails" method="POST">
        <service class="Magento\Sales\Api\ShipmentManagementInterface" method="notify"/>
        <resources>
            <resource ref="Magento_Sales::shipment" />
        </resources>
    </route>
    <route url="/V1/shipment/track" method="POST">
        <service class="Magento\Sales\Api\ShipmentTrackRepositoryInterface" method="save"/>
        <resources>
            <resource ref="Magento_Sales::shipment" />
        </resources>
    </route>
    <route url="/V1/shipment/track/:id" method="DELETE">
        <service class="Magento\Sales\Api\ShipmentTrackRepositoryInterface" method="deleteById"/>
        <resources>
            <resource ref="Magento_Sales::shipment" />
        </resources>
    </route>
    <route url="/V1/shipment/" method="POST">
        <service class="Magento\Sales\Api\ShipmentRepositoryInterface" method="save"/>
        <resources>
            <resource ref="Magento_Sales::shipment" />
        </resources>
    </route>
    <route url="/V1/shipment/:id/label" method="GET">
        <service class="Magento\Sales\Api\ShipmentManagementInterface" method="getLabel"/>
        <resources>
            <resource ref="Magento_Sales::shipment" />
        </resources>
    </route>
    <route url="/V1/order/:orderId/ship" method="POST">
        <service class="Magento\Sales\Api\ShipOrderInterface" method="execute"/>
        <resources>
            <resource ref="Magento_Sales::ship" />
        </resources>
    </route>
    <route url="/V1/orders/" method="POST">
        <service class="Magento\Sales\Api\OrderRepositoryInterface" method="save"/>
        <resources>
            <resource ref="Magento_Sales::create" />
        </resources>
    </route>
    <route url="/V1/transactions/:id" method="GET">
        <service class="Magento\Sales\Api\TransactionRepositoryInterface" method="get"/>
        <resources>
            <resource ref="Magento_Sales::transactions_fetch" />
        </resources>
    </route>
    <route url="/V1/transactions" method="GET">
        <service class="Magento\Sales\Api\TransactionRepositoryInterface" method="getList"/>
        <resources>
            <resource ref="Magento_Sales::transactions_fetch" />
        </resources>
    </route>
    <route url="/V1/order/:orderId/invoice" method="POST">
        <service class="Magento\Sales\Api\InvoiceOrderInterface" method="execute"/>
        <resources>
            <resource ref="Magento_Sales::invoice" />
        </resources>
    </route>
</routes>

The PR is #20170 and will be merged in 2.3.1 release.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.