ESD-1688: Act on behalf of a managed account - #547
Open
Phil-Browne wants to merge 3 commits into
Open
Conversation
Add a global --on-behalf-of flag and MEGAPORT_MANAGED_ACCOUNT_UID env fallback naming a managed account company UID. When set, the authenticated Megaport client is built with megaport.WithCallContext(uid) so every authenticated API call carries the X-Call-Context header; unset sends no header. Wired through both native and WASM auth paths (token and credentials), plus the setAuthCredentials optional 4th arg.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #547 +/- ##
==========================================
- Coverage 79.50% 79.49% -0.01%
==========================================
Files 193 193
Lines 18859 18870 +11
==========================================
+ Hits 14993 15001 +8
- Misses 2818 2820 +2
- Partials 1048 1049 +1
🚀 New features to boost your workflow:
|
Contributor
There was a problem hiding this comment.
Pull request overview
Adds support for acting on behalf of a managed account across the CLI by introducing a global --on-behalf-of flag (with MEGAPORT_MANAGED_ACCOUNT_UID env fallback) and applying megaport.WithCallContext(uid) during client construction so authenticated requests carry X-Call-Context: <uid>.
Changes:
- Added global
--on-behalf-ofpersistent flag (native + WASM) and a shared resolver (flag first, then env var). - Applied
megaport.WithCallContext(uid)to native login and both WASM authenticated login branches (portal token + API key/secret). - Extended WASM
setAuthCredentialsto accept an optional UID and ensured UID is cleared on credential/token/session transitions; updated tests, types, and docs accordingly.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| internal/wasm/wasm.go | Adds managed-account UID handling to WASM credential/token lifecycle (set/clear) via env var. |
| internal/wasm/wasm_test.go | Adds unit tests covering UID set/clear behavior and undefined/null handling. |
| internal/utils/utils.go | Introduces utils.ManagedAccountUID global bound to the new persistent flag. |
| internal/commands/config/login.go | Applies WithCallContext during native authenticated client construction. |
| internal/commands/config/login_wasm.go | Applies WithCallContext in both WASM authenticated client creation paths. |
| internal/commands/config/login_test.go | Adds request-level test asserting presence/absence of X-Call-Context. |
| internal/commands/config/config_shared.go | Adds shared UID resolver (flag first, then env var). |
| frontend-integration/types/megaport-wasm.d.ts | Updates TS types for setAuthCredentials(..., managedAccountUID?). |
| docs/megaport-cli.md | Documents the new global --on-behalf-of flag. |
| cmd/megaport/megaport_common.go | Registers --on-behalf-of on the native root command. |
| cmd/megaport/common_wasm.go | Registers --on-behalf-of on the WASM root command. |
Fixes the threat-model finding that a resolved --on-behalf-of UID was silently invisible: a stale or forgotten flag could leave someone acting on a managed account without realizing it. Native login now prints "Acting on behalf of managed account <uid>" alongside the success message; both WASM login branches log the same to the console. Also drops the now-redundant uid != "" guard on the native path, since WithCallContext already no-ops on an empty string.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a global
--on-behalf-offlag (and aMEGAPORT_MANAGED_ACCOUNT_UIDenv fallback) that names a managed account company UID. When set, the authenticated client is built withmegaport.WithCallContext(uid), so every authenticated API call for that invocation carriesX-Call-Context: <uid>. Unset means no header and unchanged behavior. This is the CLI half of EIP-7108 (ESD-1610 shipped the SDK option; ESD-1611 is the Terraform equivalent).Follows the existing
--base-url/utils.BaseURLpattern: flag first, then env var.Changes:
--on-behalf-ofpersistent flag on both the native and WASM root commands.WithCallContextwhen non-empty, on both native login and both WASM login branches (portal token and API-key).setAuthCredentialsgains an optional 4th arg for the UID;clearAuthCredentialsandsetAuthTokenclear it so it never leaks across auth sessions.Sending the header on every authenticated request is correct: verified in the megalith backend that
X-Call-Contextis consumed by the globalSessionTokenAuthenticationFilter(not per-endpoint), which swaps the session's company to the managed child before any controller runs, so all authenticated endpoints honor it. The backend enforces authorization (canManageChildreturns 403 if the caller can't manage that company) and rejects the header for assumed-role sessions, so forwarding a UID is safe. The OpenAPI spec only declaring the parameter on three pricebook GETs is incomplete documentation, not the real scope.What I could not verify
WithCallContextoption application is proven by the native request-level test (same SDK code path); the WASM flag/env wiring is unit-tested, but the actual browser request is verified manually in-browser.WithCallContextsets the header on the client beforeAuthorize()runs, so the token-exchange request to the auth-m2m host also carriesX-Call-Context, not just resource API calls. This isn't new: the existingWithCustomHeaders(cliHeaders)option already does the same, unchanged by this PR, so no new host is receiving unexpected headers. Standard HTTP servers ignore headers they don't recognize and the token endpoint has no company-context concept to act on, so risk reads as low, but the token-issuing service is a separate microservice consumed only as an external dependency, with no source in this megalith checkout to confirm it's ignored outright.