Skip to content

feat: call member-tiers via m2m - #2311

Open
epipav wants to merge 4 commits into
feat/api-gateway-workerfrom
feat/api-gateway-member-tiers
Open

epipav wants to merge 4 commits into
feat/api-gateway-workerfrom
feat/api-gateway-member-tiers

Conversation

@epipav

@epipav epipav commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Replaces the member-tiers stub with the real call: GET <LFX_API_URL>b2b_orgs/member-tiers/{username}?v=1 through Heimdall, authorized with a client-credentials token that is reused until shortly before it expires.

  • New env: LFX_API_URL, M2M_ISSUER_URL, M2M_AUDIENCE, M2M_CLIENT_ID, M2M_CLIENT_SECRET.
  • The M2M client needs member on team:member_tiers_caller in OpenFGA.

Stacked on #2310; retargets to main once it merges.

Copilot AI balanced review requested due to automatic review settings September 25, 2026 15:31
@cursor

cursor Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
Introduces live entitlement lookups and M2M secret handling in the request path; failures or misconfiguration can block tier/org resolution for API traffic.

Overview
Replaces the member-tiers stub in the Insights API gateway with a live GET b2b_orgs/member-tiers/{username}?v=1 call against LFX_API_URL, using a client-credentials M2M token for authorization.

A new m2mToken helper obtains tokens from M2M_ISSUER_URL, caches them in memory until about a minute before expiry, and fetchMemberTiers attaches Bearer on each LFX request. Configuration is extended via LFX_API_URL and M2M_* env vars (documented in .dev.vars.example); gateway tests still mock tiers, and tiers.test.ts covers token reuse, refresh near expiry, and error handling.

Reviewed by Cursor Bugbot for commit a0bd478. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Concurrent cache misses duplicate token exchanges, and the failure test does not reliably exercise the member-tiers error path.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
What changed in this PR

Replaces the member-tier stub with an authenticated Heimdall API call using cached M2M credentials.

Changes:

  • Adds client-credentials token acquisition and caching.
  • Calls the live member-tiers endpoint.
  • Adds environment configuration and tests.
File Description
workers/​api-gateway/​src/​m2m.ts Implements M2M token retrieval and caching.
workers/​api-gateway/​src/​tiers.ts Calls member-tiers with the M2M token.
workers/​api-gateway/​src/​env.ts Defines required M2M environment variables.
workers/​api-gateway/​tests/​tiers.test.ts Tests token reuse and API failures.
workers/​api-gateway/​tests/​gateway.test.ts Updates the gateway test environment.
workers/​api-gateway/​README.md Documents removal of the member-tier stub.
workers/​api-gateway/​.dev.vars.example Adds local M2M configuration placeholders.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread workers/api-gateway/src/m2m.ts
Comment thread workers/api-gateway/tests/tiers.test.ts
Copilot AI review requested due to automatic review settings September 25, 2026 16:37
@epipav
epipav force-pushed the feat/api-gateway-member-tiers branch from 6bd79b1 to 76ab0a0 Compare September 25, 2026 16:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Tier selection mishandles the upstream taxonomy, and concurrent cache misses can trigger redundant token requests.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 High severity

Open (1)
Resolved since last review (2)

Comment thread workers/api-gateway/src/tiers.ts
Copilot AI review requested due to automatic review settings September 25, 2026 16:46
@epipav
epipav force-pushed the feat/api-gateway-member-tiers branch from 76ab0a0 to 62475ec Compare September 25, 2026 16:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The token refresh boundary needs automated coverage before the authentication cache can be safely approved.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Low severity

Open (1)
Resolved since last review (1)

Comment thread workers/api-gateway/tests/tiers.test.ts Outdated
@epipav epipav self-assigned this Sep 25, 2026
@epipav
epipav added this pull request to stack #2313 September 25, 2026 18:56

@themarolt themarolt left a comment

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.

looks good - one question on how member-tiers answers for users without a membership

const response = await fetch(url, {
headers: { authorization: `Bearer ${await m2mToken(env)}` },
});
if (!response.ok) throw new Error(`member-tiers request failed: ${response.status}`);

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 does member-tiers return for a user with no membership - 200 [] or a 404? if it's a 404, this throws and the worker answers 500 instead of the forbidden() 403 in handle, or am I missing something?

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.

member-tiers answers 200 [] for users without a membership (unknown users too), so this lands on forbidden()

@gaspergrom gaspergrom left a comment

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.

Traced the token cache and the outbound URL. Reuse works and the username gets encoded correctly. Two things worth resolving before this merges, both about what happens when the upstream call isn't a clean success.

const response = await fetch(url, {
headers: { authorization: `Bearer ${await m2mToken(env)}` },
});
if (!response.ok) throw new Error(`member-tiers request failed: ${response.status}`);

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 does member-tiers return for a user with no membership, a 200 with an empty array or a 404? If it can 404, this throw has nothing catching it in handle(), so the worker would answer with a raw 500 instead of the 403 that forbidden() already builds for exactly that case.

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.

member-tiers answers 200 [] for users without a membership (unknown users too), so this lands on forbidden()

Comment thread workers/api-gateway/tests/tiers.test.ts
Signed-off-by: anilb <epipav@gmail.com>
Signed-off-by: anilb <epipav@gmail.com>
Signed-off-by: anilb <epipav@gmail.com>
Copilot AI review requested due to automatic review settings September 25, 2026 19:43
@epipav
epipav force-pushed the feat/api-gateway-member-tiers branch from 62475ec to 9fa13d4 Compare September 25, 2026 19:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The tests do not verify the client-credentials request payload that authorizes the new integration.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
Resolved since last review (1)

Comment thread workers/api-gateway/tests/tiers.test.ts
Signed-off-by: anilb <epipav@gmail.com>
Copilot AI review requested due to automatic review settings September 25, 2026 19:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Repository workflow requires an IN-### JIRA reference in the PR body or commit history.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: None

Resolved since last review (1)

@themarolt themarolt left a comment

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.

lgtm

@gaspergrom gaspergrom left a comment

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.

Approving now, thanks for the update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants