Skip to content

aio console workspace api add replaces subscribed APIs instead of appending (v5.3.0) #258

@pru55e11

Description

@pru55e11

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-cli 11.1.0 (macOS arm64, node v24.14.1)
  • @adobe/aio-cli-plugin-console 5.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> --json

Expected

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:

  1. The success message says "added", with no mention that anything was removed.
  2. 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

  1. Make api add truly additive — read the current subscription list and merge with the requested codes before persisting.
  2. 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 / --merge flag with --merge as the default.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions