Skip to content

feat(agent-bff): mint an agent token from the OAuth principal - #1800

Open
Tonours wants to merge 3 commits into
mainfrom
feature/prd-866-mint-an-agent-token-from-the-oauth-principal
Open

feat(agent-bff): mint an agent token from the OAuth principal#1800
Tonours wants to merge 3 commits into
mainfrom
feature/prd-866-mint-an-agent-token-from-the-oauth-principal

Conversation

@Tonours

@Tonours Tonours commented Aug 4, 2026

Copy link
Copy Markdown
Member

fixes PRD-866

Problem

OAuth bff_access tokens authenticate successfully, but Mode 1 requests fail on agent routes because no downstream agent token is created.

Fix

  • Mint an agent token from the validated OAuth principal.
  • Preserve the caller identity, including role, permissions, tags, and numeric renderingId.
  • Map claims explicitly and exclude session-only type and sid claims.
  • Fail closed when the principal has no usable rendering.
  • Add regression coverage for OAuth routing, token claims, expiry, replay, and Mode 2 compatibility.

Scope and safety

  • Changes are limited to packages/agent-bff.
  • No SaaS round-trip is added.
  • Mode 2 API-key authentication is unchanged.
  • Session and CORS behavior outside the agent chain is unchanged.

How to test

yarn workspace @forestadmin/agent-bff test
yarn workspace @forestadmin/agent-bff build
yarn workspace @forestadmin/agent-bff lint

Definition of Done

General

  • Write an explicit title for the Pull Request, following Conventional Commits specification
  • Test manually the implemented changes
  • Validate the code quality (indentation, syntax, style, simplicity, readability)

Security

  • Consider the security impact of the changes made

@linear-code

linear-code Bot commented Aug 4, 2026

Copy link
Copy Markdown

PRD-866

@qltysh

qltysh Bot commented Aug 4, 2026

Copy link
Copy Markdown

Qlty


Coverage Impact

This PR will not change total coverage.

Modified Files with Diff Coverage (2)

RatingFile% DiffUncovered Line #s
Coverage rating: A Coverage rating: A
packages/agent-bff/src/api-key/agent-token.ts100.0%
Coverage rating: A Coverage rating: A
packages/agent-bff/src/auth/auth-mode-middleware.ts100.0%
Total100.0%
🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@Tonours
Tonours force-pushed the feature/prd-866-mint-an-agent-token-from-the-oauth-principal branch 2 times, most recently from e31fe3f to faa793a Compare August 5, 2026 10:42
@Tonours
Tonours force-pushed the feature/prd-866-mint-an-agent-token-from-the-oauth-principal branch from faa793a to 4d6a0a1 Compare August 6, 2026 13:34
@ShohanRahman

ShohanRahman commented Aug 6, 2026

Copy link
Copy Markdown
Contributor
  1. A genuine 401 with a non-OAuth-shaped body dead-ends into a misleading "check your network" state · oauth-service.ts:64-88 + AuthContext.tsx:416-436
    isSessionRejected only treats a 401 as session-rejection when fromOAuthBody is true. If the OAuth server (or a proxy in front of it) returns an expired-session 401 with a body like {message:"Unauthorized"} instead of {error:"invalid_grant"}, the init path takes the non-rejected branch: it keeps the stale refresh token in storage and shows "Unable to reach Forest Admin. Check your network" for what is actually an expired session. The design (avoid false-logout on gateway noise) is sound and well-tested, but the fallback should still clear tokens / offer re-login rather than leave the user with a network-sounding message and a stale token.

  2. exact?: boolean is a three-state value modeled as an optional boolean, re-typed inline in 5 files · forest-service.ts:165,171-180; also deterministic-matcher.ts:18, record-search.ts:10, ForestContext.tsx:37,207, useRelatedRecordsFromAnalysis.ts:15
    undefined = "auto-detect strictness from field-name heuristics", true = force Equal, false = force fuzzy — three distinct behaviors, but the signature { exact?: boolean } gives a caller no way to know that omitting the key differs from passing false. You already have the right vocabulary internally (LessonMode = 'strict'|'exact'|'fuzzy'). Recommend a single named MatchStrictness = 'auto'|'exact'|'fuzzy' defined once and imported, instead of the inline object retyped in five places.

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.

2 participants