feat: quote template and render token security - #2
Open
christopher-talke wants to merge 3 commits into
Open
Conversation
- Add active: boolean to metadata.json; GET /api/v1/templates filters inactive templates out - Add RenderTokenPayload + signRenderToken/verifyRenderToken to jwt.ts (5 min expiry, scoped to proposalId + tenantId) - Add requireRenderToken middleware - Add GET /api/v1/render/proposal/:id - minimal endpoint only accessible with a valid render token; no user auth, no service token - Server PDF endpoint generates a render token and passes it to the templater as x-render-token - Templater /download/ validates and threads the render token through generatePdf() into the Puppeteer URL - getProposalData() uses the render token against /api/v1/render/proposal/:id instead of the broad service token path https://claude.ai/code/session_01HgpVh7XS9BHcU2YAJeJ1L8
There was a problem hiding this comment.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
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.
Summary
quick-quoteEJS template - a compact 1-2 page PDF alternative to the full proposal template, covering product line items, totals summary, and an authorization signature blockGET /api/v1/templatesendpoint on the templater that discovers available templates viametadata.jsonin each template folder (filtered byactive: true)proposalId + tenantId) so the templater can only access the specific proposal it was asked to render - no broad service token access to proposal dataGET /api/v1/render/proposal/:idon the server - a minimal endpoint only reachable with a valid render token, no user auth or service token bypassSecurity model
The templater now receives a
x-render-tokenJWT alongside the existingx-service-token. The render token is signed by the server at request time, scoped to one proposal + tenant, and expires in 5 minutes. The templater threads this token through the Puppeteer render chain and uses it to call the new/render/proposal/:idendpoint - the only server endpoint it needs. A malicious EJS template running in the templater process can at most re-request the same proposal it was already authorised to render.Test plan
GET /api/v1/templatesreturns only templates withactive: truein theirmetadata.jsonGET /api/v1/render/proposal/:idwithout a token return 401403 Forbidden)