Repository navigation
Description
Summary
aio console workspace api add --service-code X against a workspace that already has another API subscribed silently replaces the subscription rather than appending to it. The previously-subscribed APIs (and their credential scopes) are removed.
This is contrary to the command name (add), the help text ("Add API service(s) to a Workspace"), and the v5.3.0 release notes which describe it as subscribing one or more API services.
Environment
@adobe/aio-cli11.1.0 (macOS arm64, node v24.14.1)@adobe/aio-cli-plugin-console5.3.0 (the version that introduced this command)
Repro
Start with a workspace that has exactly one API subscribed — for example App Builder Data Services (AppBuilderDataServicesSDK), which adds the adobeio.abdata.* scopes to the OAuth Server-to-Server credential.
# Verify starting state
aio console workspace api list \
--projectName <project> --workspaceName <workspace> --json
# -> [{ "sdkCode": "AppBuilderDataServicesSDK", ... }]
# "Add" I/O Management API
aio console workspace api add \
--projectName <project> --workspaceName <workspace> \
--service-code AdobeIOManagementAPISDK
# -> Successfully added API(s) AdobeIOManagementAPISDK to Workspace <workspace>.
# Verify
aio console workspace api list \
--projectName <project> --workspaceName <workspace> --jsonExpected
Workspace ends up subscribed to both AppBuilderDataServicesSDK and AdobeIOManagementAPISDK. Credential scopes accumulate (adobeio.abdata.* + I/O Management scopes).
Actual
Workspace is subscribed to only AdobeIOManagementAPISDK. AppBuilderDataServicesSDK is silently removed, along with its adobeio.abdata.read|write|manage scopes on the OAuth Server-to-Server credential. Calling api add again with AppBuilderDataServicesSDK swaps it back the other way.
This is a set/replace semantic, not add/append. It's particularly dangerous because:
- The success message says "added", with no mention that anything was removed.
- Removed scopes mean runtime tokens minted from that credential lose access to whatever APIs depended on them, breaking deployed apps without any deploy-time signal.
Workaround
Pass all desired service codes in a single --service-code argument (comma-separated). This works as expected and ends up with all listed services subscribed:
aio console workspace api add \
--projectName <project> --workspaceName <workspace> \
--service-code "AdobeIOManagementAPISDK,AppBuilderDataServicesSDK"Suggested fixes
- Make
api addtruly additive — read the current subscription list and merge with the requested codes before persisting. - If the API truly is set-based under the hood, rename the command (
api set?) and/or add an explicit warning when removing services, or surface a--replace/--mergeflag with--mergeas the default. - The success message should enumerate the post-state (
Workspace <name> is now subscribed to: A, B, C), not just echo what was passed in.
Impact
We hit this on a production-ish App Builder app while following the official CI/CD using GitHub Actions guide, which directs users to add the I/O Management API to enable CI deploys. The "add" silently removed the App Builder Data Services SDK from the workspace's S2S credential, which in turn removed the adobeio.abdata.* scopes that @adobe/aio-lib-db needs at runtime. The deployed actions would have started 401-ing on database calls on next invocation, with no signal at deploy time.
We caught it before it shipped, but only because we happened to verify the workspace state after running api add. Most users following the doc will not.
Activity
aiojbot commentedon May 14, 2026
JIRA issue created: https://jira.corp.adobe.com/browse/ACNA-4603
fix: GH-258 make api add additive instead of overwriting existing ser…
fix: ACNA-4617 / #258 make api add additive, dedupe duplicate service…