fix: migrate Adobe Post Office auth to Bearer + x-api-key (LLMO-7021) - #3066
fix: migrate Adobe Post Office auth to Bearer + x-api-key (LLMO-7021)#3066JayKid wants to merge 3 commits into
Conversation
APO is moving domains; the new contract requires an OAuth Bearer token and an x-api-key header instead of the legacy IMS auth scheme. Endpoint URL change is handled separately via Vault (ADOBE_POSTOFFICE_ENDPOINT). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Hey @JayKid,
⚠ Degraded review - no spec document was found for this change (searched the PR links, the touched repos' docs, the architecture/guidelines docs, and linked Jira). This review covers code-level quality but could not validate the change against an agreed design, so confidence is reduced. Add a spec link (PR template section 4) and re-request review for a full-confidence pass.
Verdict: Request changes - one operational concern with the new env vars.
Complexity: MEDIUM - small diff; API surface signal.
Changes: Migrates Adobe Post Office auth from IMS scheme to Bearer and adds x-api-key header at both email call sites (3 files).
Must fix before merge
- [Important] Missing env var guard for new
x-api-keyvariables -src/support/email-service.js:103/src/controllers/trial-users.js:164(details inline)
Non-blocking (1): minor issues and suggestions
- question: Two different env var names (
LLMO_EMAIL_IMS_CLIENT_IDvsEMAIL_IMS_CLIENT_ID) - are these intentionally distinct IMS client registrations? See inline comment onsrc/controllers/trial-users.js:164.
Skill: pr-review | Model: us.anthropic.claude-opus-4-6-v1[1m] | Duration: 2m 58s | Cost: $2.76 | Commit: 9e707d8921b51d90fe0f8b4f1c5669b02dc69c5f
If this code review was useful, please react with 👍. Otherwise, react with 👎.
| Accept: 'application/json', | ||
| Authorization: `IMS ${accessToken}`, | ||
| Authorization: `Bearer ${accessToken}`, | ||
| 'x-api-key': env.LLMO_EMAIL_IMS_CLIENT_ID, |
There was a problem hiding this comment.
issue (blocking): The new x-api-key env var (LLMO_EMAIL_IMS_CLIENT_ID) is used without a presence check. This file already validates ADOBE_POSTOFFICE_ENDPOINT and throws when it is missing. If this var is unset, the header is sent as x-api-key: undefined, producing an opaque 401/403 from APO rather than a clear configuration error.
Add a guard alongside the existing endpoint check:
if (!env.LLMO_EMAIL_IMS_CLIENT_ID) {
return { status: 500, body: { error: 'LLMO_EMAIL_IMS_CLIENT_ID is not configured' } };
}Same pattern applies to EMAIL_IMS_CLIENT_ID in src/controllers/trial-users.js:164.
| Accept: 'application/xml', | ||
| Authorization: `IMS ${imsTokenPayload.access_token}`, | ||
| Authorization: `Bearer ${imsTokenPayload.access_token}`, | ||
| 'x-api-key': env.EMAIL_IMS_CLIENT_ID, |
There was a problem hiding this comment.
question: This uses env.EMAIL_IMS_CLIENT_ID while email-service.js uses env.LLMO_EMAIL_IMS_CLIENT_ID. Are these intentionally different IMS client registrations (one for the LLMO email flow, one for trial/welcome emails)? If so, makes sense - just confirming since both target the same APO endpoint.
Addresses MysticatBot review: a missing LLMO_EMAIL_IMS_CLIENT_ID / EMAIL_IMS_CLIENT_ID would send 'x-api-key: undefined' and produce an opaque APO 401/403. Fail early with a clear config error, matching the existing ADOBE_POSTOFFICE_ENDPOINT guard. Adds coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
This PR will trigger a patch release when merged. |
|
@MysticatBot thanks — addressed in be4ef1b. Blocking (guard): Added a presence check for the
Added unit tests for both guards (and updated two pre-existing trial-user tests whose Non-blocking (env var names): Yes, intentional and pre-existing — this PR didn't introduce the divergence. Re-requesting review — thanks! |
There was a problem hiding this comment.
Hey @JayKid,
⚠ Degraded review - no spec document was found for this change (searched the PR links, the touched repos' docs, the architecture/guidelines docs, and linked Jira). This review covers code-level quality but could not validate the change against an agreed design, so confidence is reduced. Add a spec link (PR template section 4) and re-request review for a full-confidence pass.
Verdict: Approve - prior blocking finding addressed, no new issues.
Complexity: MEDIUM - small diff; API surface signal.
Changes: Migrates Adobe Post Office auth from IMS to Bearer scheme and adds x-api-key header, with env var guards at both call sites (4 files).
Note: CI checks are still pending - confirm they pass before merge.
Previously flagged, now resolved
- Env var guard for
x-api-keysource variables now present at both call sites, matching the existing endpoint guard pattern.
Skill: pr-review | Model: us.anthropic.claude-opus-4-6-v1[1m] | Duration: 1m 42s | Cost: $4.63 | Commit: be4ef1b9cbede9abb331f57a55b1503fa911e739
If this code review was useful, please react with 👍. Otherwise, react with 👎.
|
Second opinion on PR #3066 (MysticatBot already reviewed → Approved) Verdict: Changes recommended — go further than MysticatBot. The code is fine; two things should be nailed down before merge, and neither is catchable by the unit tests (they only assert the header string the code sends). What MysticatBot missed
On MysticatBot's blocking findings
Discarded in verification
Bottom line: MysticatBot's approve is defensible for code quality. The one risk it can't see from the diff is that the Bearer + x-api-key contract is an unverified external assumption — if it is wrong, the tests will not tell you. Worth confirming before merge. Second opinion via char-multi-persona-review — complements, does not override, MysticatBot's review. |
Addresses calvarezg review on #3066: - trial-users.js: build a local env copy for the email IMS client instead of writing IMS_CLIENT_ID/SECRET/CODE/SCOPE onto the shared context.env, which is reused across warm Lambda invocations (credential-bleed risk). Mirrors the pattern already used in email-service.js. - email-service.js: throw a clear error when IMS returns no access_token so a malformed 200 fails legibly instead of sending 'Bearer undefined'. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@calvarezg thanks for the second opinion — addressed in 16648dc: #2 (shared Bonus (from your #684 review): empty-token guard. #1 (Bearer + x-api-key contract) — confirmed as the real risk, verifying out-of-band. Can't be proven in the diff, agreed. Early dev signal: a live weekly-digest run in DEV hit the new endpoint and returned #3 (shared Re-requesting review. |
calvarezg
left a comment
There was a problem hiding this comment.
Re-review (updated to 16648dc4)
Verdict: Approve — my earlier "changes recommended" items are resolved. One merge-gate remains, and it is not a code issue.
On my second-opinion findings:
-
[Important]
context.envmutation — fixed correctly.trial-users.jsnow buildsemailEnv = { ...env, IMS_CLIENT_ID: env.EMAIL_IMS_CLIENT_ID, ... }and passesImsClient.createFrom({ ...context, env: emailEnv }). The direct writes onto sharedcontext.envare gone — mirrors theemail-service.jspattern, with a comment explaining the warm-Lambda reason. Thex-api-keyheader readsenv.EMAIL_IMS_CLIENT_IDfrom the un-mutatedenv, consistent with the token minted under that client. Traced the send path — nothing downstream depends on the oldenv.IMS_CLIENT_IDwrite. Clean. -
[Important] Bearer + x-api-key contract — the real risk, verifying out-of-band. Correct call. The DEV signal (old code hitting the new APO returned
403 ErrMissingAPIKey) confirms the new endpoint enforcesx-api-key, but does not yet proveBearer+ this key are accepted (a 200). That confirmation (branch deploy + one real send, tracked with the APO owner on LLMO-7021) is what should gate merge. Not a code blocker. -
[Minor] Shared header helper — deferred to LLMO-7021. Fine; it spans two repos.
New in this update:
- Empty-token guard in
getEmailServiceToken— throws if IMS returns 200 withoutaccess_token, avoidingBearer undefined. Good, tested. - [Minor, new] The empty-token guard is only on the email-service path, not trial-users.
trial-users.jscallsimsClient.getServiceAccessToken()directly and usesimsTokenPayload.access_tokenwithout the same null check, so a misbehaving IMS could still sendBearer undefined+x-api-keythere. Low probability. Worth one line if you touch it again; not blocking.
Bottom line: code is good to go. The only thing between here and merge is the out-of-band 200 confirmation on the Post Office contract, which you own and are tracking.
Second opinion via char-multi-persona-review — complements, does not override, MysticatBot's review.
What
Migrates the Adobe Post Office (APO) email integration to the new API contract ahead of APO's domain move.
Per the APO team, the contract change is auth header + endpoint:
Authorization: IMS <token>→Authorization: Bearer <token>x-api-key: <ims-client-id>The endpoint URL itself (
ADOBE_POSTOFFICE_ENDPOINT→https://apo-prod.adobe.io/https://apo-stage.adobe.io) is a Vault change, not code — it is not modified here.Changes
src/support/email-service.js—Bearerauth +x-api-key: env.LLMO_EMAIL_IMS_CLIENT_IDsrc/controllers/trial-users.js(trial/welcome email) —Bearerauth +x-api-key: env.EMAIL_IMS_CLIENT_IDtest/support/email-service.test.js— updated header assertions +x-api-keycoverageTesting
npx mocha test/support/email-service.test.js test/controllers/trial-users.test.js— 59 passing.Notes
OneAdobe/aem-xwalk-trial#107); migration guide: PostOffice Migration wiki (FDT space).spacecat-reporting-worker(weekly digest) is a separate PR.Ref: LLMO-7021