Skip to content

CEXT-6151: Add ACL admin UI schema and helper to check permissions#522

Open
oshmyheliuk wants to merge 10 commits into
mainfrom
CEXT-6151-v2
Open

CEXT-6151: Add ACL admin UI schema and helper to check permissions#522
oshmyheliuk wants to merge 10 commits into
mainfrom
CEXT-6151-v2

Conversation

@oshmyheliuk

Copy link
Copy Markdown
Collaborator

Description

https://jira.corp.adobe.com/browse/CEXT-6151

  1. Update adminUISdk schema to support ACL fields for menu items
  2. Add a public helper that extensions can call from the SPA and from runtime actions to check whether the current user is allowed to use a given ACL resource.

Related Issue

https://github.com/magento-commerce/adobe-commerce-backend-uix/pull/352

Motivation and Context

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have signed the Adobe Open Source CLA.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have read the DEVELOPMENT document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@changeset-bot

changeset-bot Bot commented Jun 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9ec1234

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@adobe/aio-commerce-lib-app Minor
@adobe/aio-commerce-lib-admin-ui Minor
@adobe/aio-commerce-lib-core Minor
@adobe/aio-commerce-sdk Patch
@adobe/aio-commerce-lib-api Patch
@adobe/aio-commerce-lib-auth Patch
@adobe/aio-commerce-lib-config Patch
@adobe/aio-commerce-lib-events Patch
@adobe/aio-commerce-lib-webhooks Patch
@aio-commerce-sdk/common-utils Patch
@aio-commerce-sdk/scripting-utils Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added with-changeset The PR contains a Changeset file. pkg: aio-commerce-lib-app Includes changes in `packages/aio-commerce-lib-app` pkg: aio-commerce-lib-admin-ui labels Jun 16, 2026
// → "Magento_CommerceBackendUix::adminuisdk_app_acme_promotions"

// Check access in a runtime action:
const client = getAdminUiPermissionClient({

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

would it be possible to create a function in aio-commerce-lib-app that returns a permission client which auto resolves the app id from the one set in the commerce config so we don't need to pass this value on each function call.
Something like

const app = getAppPermissionClient({httpClient}); // resolves appId from app.commerce.config

@iivvaannxx iivvaannxx Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

resolves appId From app.commerce.config

That's something we may need to be cautious with. Runtime code (that runs in a runtime action) that depends on that file can not easily read the configuration unless it's bundled with the action, which requires extra setup in ext.config.yaml via include or via some import trick (messy bundle/build stuff).

It's the same problem we have (for now) with lib-config: we need to receive the schema in initialize. There are ways to make this work, but they are not trivial.

@github-actions github-actions Bot added the spec Includes changes in `specs/features` label Jun 17, 2026
* @returns The full Commerce ACL resource id for the menu leaf node (e.g.
* `"Magento_CommerceBackendUix::adminuisdk_app_approval_dashboard_app_menu_approval_dashboard"`).
*/
export function getMenuAclResourceId(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should be documented in usage.md?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added examples here e726578

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This documentation should be completely agnostic of app.commerce.config, it doesn't know about it.


const permissionClient = getAdminUiPermissionClient({
httpClient, // AdobeCommerceHttpClient — reuse the one from createAdminUiApiClient
appId: "acme-promotions", // metadata.id from your app config; enables no-argument calls

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What's the appId used for? What happens if I am not an App Management user? If this is intended to be used with App Management shouldn't it be in lib-app?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

appId is used to generate the ACL resource ID for future permission checks in the permission client.
I think it should be a part of the admin-ui library. The comment in usage.md was confusing, so I updated it.

Comment on lines +31 to +33
* This is a cross-repo contract shared with the Commerce module. Both sides must produce
* the exact same output for the same input. Any change here must be coordinated with the
* Commerce module's ACL id generator.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This will end up in public docs. Isn't this kind of an internal comment?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, it's more like an internal comment. We need to maintain consistent logic between Commerce and aio-commerce-sdk to generate the same ACL resources.
I updated comments https://github.com/adobe/aio-commerce-sdk/pull/522/commits

/** Options used to create an Admin UI SDK permission client. */
export interface AdminUiPermissionClientOptions {
/** The application's `metadata.id` value. When provided, `check()` and `require()` can be called with no resource argument. */
appId?: string;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Now that I see how appId works, I would challenge the fact that it is tightly coupled to a concept outside this library (app IDs). It's a useful convenience, but I am not sure it's the right layer to implement it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The appID is optional; the client can check permissions directly by providing the full ACL Resource ID.
But this client can check only resources created by the Admin UI commerce module. All ACL resources are created based on the installed apps, so the client is tightly coupled to the Admin UI and the installed applications' logic.

It's not like you can use this client to check any ACL Resource in Commerce; for resources not created by the Admin UI module, the API endpoint would always return false.

Comment on lines +59 to +62
* Throws `AdminUiPermissionDeniedError` if denied.
* Throws `AdminUiPermissionError` on 401, network, and parse errors.
* When called with no argument, defaults to the ACL resource id derived from `appId`.
* Throws `AdminUiPermissionError` immediately when neither `resource` nor a valid `appId` is available.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These lines should use proper JSDoc so that the autogenerated documentation picks those correctly. @throws with proper @link

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Updated in 5f29d20

});
}

/** Creates a client for checking Admin UI SDK ACL resources. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

options is not documented as @param.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Updated in 5f29d20

.post("adminuisdk/permission/check", {
json: { resource: params.resource },
})
.json<unknown>();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I believe unknown is the default so .json() should be equivalent.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Updated in e958f27

* @param httpClient - The {@link AdobeCommerceHttpClient} to use to make the request.
* @param params - The resource to check.
*
* @throws An `HTTPError` if the status code is not 2XX.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe @link is better for this throws?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added in e958f27


public constructor(
resource: string,
options?: ErrorOptions & { traceId?: string },

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

From where is this ErrorOptions sourced? In any case, I would create a custom Options for each error even if equivalent to the default, this way we decouple both and we avoid type contract changes in the future if we need to add some options.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I added an export for error options from the core package
9ec1234. It sounds logical to re-use them.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This wasn't merged separately? In any case Implemented should be marked.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Marked

@github-actions github-actions Bot added the pkg: aio-commerce-lib-core Includes changes in `packages/aio-commerce-lib-core` label Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg: aio-commerce-lib-admin-ui pkg: aio-commerce-lib-app Includes changes in `packages/aio-commerce-lib-app` pkg: aio-commerce-lib-core Includes changes in `packages/aio-commerce-lib-core` spec Includes changes in `specs/features` with-changeset The PR contains a Changeset file.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants