feat: add public API foundation with OAuth2 authentication (CM-965)#3841
Merged
feat: add public API foundation with OAuth2 authentication (CM-965)#3841
Conversation
…guration validation
… next() for error propagation
…adjust Actor type to 'service'
…or improved clarity
themarolt
approved these changes
Feb 20, 2026
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
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.
Context
CDP is expanding beyond internal frontend usage. LFX One will consume CDP data through new transactional APIs for identity, role, and work experience verification. This PR lays the authentication, error handling, and routing foundation that all future public endpoints will build on.
The auth setup is based on Eric’s proposal: Auth0 client credentials (M2M) grant, where the LFX Angular SSR backend acts as a machine client. CDP trusts Auth0 as the IdP and never handles credential rotation directly. Scopes are statically defined in Auth0/Terraform and enforced per-endpoint.
What Changed
backend/src/api/publicwith versioned routing (/api/v1/...).express-oauth2-jwt-bearer.req.actor) and token-to-actor resolution (sub/azp + scopes), so handlers rely on identity abstraction, not raw tokens.requireScopes) and centralized scope definitions (security/scopes.ts), including scopes for members, identities, roles, work experiences, and project affiliations.publicRouterat/apiinbackend/src/api/index.tsbefore internal tenant/segment route flow, so public endpoints run with their own auth/error pipeline and stay isolated from internal middleware assumptions.issuerBaseURL,audience) in config types/env mappings.identities) as a foundation wiring check.Cross-cutting Improvements Included
@crowd/common(HttpError+ concrete classes), while keeping legacy error classes underdeprecated.429responses viaRateLimitError.HttpErrorJSON shape.Why These Decisions
Out of Scope in This PR
Next Steps
members/search, identities/roles/work experiences flows).Note
Medium Risk
Introduces a new externally-consumable API surface with OAuth2/JWT validation and scope enforcement; misconfiguration or middleware ordering issues could unintentionally expose or block endpoints. Also changes error/429 response shapes across multiple services, which may affect clients expecting plain-text errors.
Overview
Adds a new public API surface under
backend/src/api/publicwith versioned routing (/v1) protected by Auth0 OAuth2 JWT validation (express-oauth2-jwt-bearer), anActoridentity abstraction onreq.actor, and per-route scope enforcement viarequireScopesand centralizedSCOPES.Mounts the
publicRouter()before the existing internal auth/tenant middleware stack, and wires new Auth0 config (issuerBaseURL,audience) into env/config types. Standardizes structured JSON HTTP errors across the backend and webhook/search-sync/nango services by introducingHttpErrorclasses (includingRateLimitError) and updating rate limiting and various handlers to return{ error: { code, message } }instead of string messages; legacy error classes are moved undererrors/deprecated.Written by Cursor Bugbot for commit 49d0dab. This will update automatically on new commits. Configure here.