feat(integrations): add support for meilisearch#6713
Conversation
There was a problem hiding this comment.
3 issues found across 23 files
Confidence score: 2/5
- In
integrations/meilisearch/meilisearch/actions/generate-tenant-token.ts, auto-resolvingapiKeyUidby putting the raw API key in the URL path can leak secrets into proxy/access/APM logs, creating a concrete credential-exposure risk if merged as-is — switch to a non-secret identifier lookup path (or resolve via body/header) before merging. - In
integrations/meilisearch/meilisearch/lib/schemas.ts, using.catchall(z.unknown())for tenant-token search rules allows misspelled keys likefiltersto validate even though Meilisearch only honorsfilter, so policies can silently fail and produce broader-than-expected search access — restrict/whitelist allowed keys (or reject unknown keys) before merging. - In
integrations/meilisearch/meilisearch/actions/add-documents.ts,z.array(...).min(1)may not enforce non-empty document batches in deployed actions (per the noted refinement stripping), so empty submissions can slip through and cause runtime/API errors in production — add an explicit runtime length check in action logic before merging.
Not reviewed (too large): packages/providers/providers.yaml (~29 lines), docs/llms-full.txt (~1 lines) - if these are generated or fixture files, add them to ignored paths to exclude them from future reviews.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="integrations/meilisearch/meilisearch/lib/schemas.ts">
<violation number="1" location="integrations/meilisearch/meilisearch/lib/schemas.ts:14">
P1: The tenant-token search-rule schema allows arbitrary object keys because `.catchall(z.unknown())` is used. Meilisearch only recognizes the `filter` key in search rules, so a typo like `filters` passes validation and gets signed into the JWT. If Meilisearch ignores the unknown key, the token silently drops its intended restriction and broadens access. Replacing `.catchall(z.unknown())` with `.strict()` rejects unknown keys at validation time while still permitting `{}` (no restriction) and `null` through the union. This aligns with the team's preference for strict, explicit schemas over broad pass-through validation.</violation>
</file>
<file name="integrations/meilisearch/meilisearch/actions/add-documents.ts">
<violation number="1" location="integrations/meilisearch/meilisearch/actions/add-documents.ts:8">
P1: The `z.array(...).min(1)` guard on `documents` does not reliably enforce non-empty batches in deployed Nango actions because the same PR explicitly notes that declarative Zod refinements are stripped from deployed JSON schemas. In `delete-documents.ts`, a runtime length check is added with a comment explaining this exact limitation (`Enforced here because declarative zod refinements are stripped...`), but `add-documents.ts` omits that guard. An empty `documents` array could therefore be forwarded to Meilisearch at runtime instead of failing with a clear action error.
Consider adding a runtime length check inside `exec`, e.g.:
```typescript
if (input.documents.length === 0) {
throw new nango.ActionError({ message: '"documents" must contain at least one document.' });
}
```</violation>
</file>
<file name="integrations/meilisearch/meilisearch/actions/generate-tenant-token.ts">
<violation number="1" location="integrations/meilisearch/meilisearch/actions/generate-tenant-token.ts:46">
P1: The auto-resolution of `apiKeyUid` sends the raw Meilisearch API key in the request URL path. URL paths are captured by HTTP access logs, reverse proxies, and APM traces, and typical header-redaction does not scrub secrets embedded in the path. Because this lookup is the default whenever `apiKeyUid` is omitted, callers may unknowingly expose their connection API key in logs. Consider adding a prominent warning to the action description or making the lookup opt-in so users are aware of the credential-exposure risk before it happens.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 6 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 7 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
- Restructure to canonical zero-yaml layout (meilisearch/actions/) so the CLI derives providerConfigKey 'meilisearch' instead of '.' - Switch connection verification from GET /keys to GET /version (cheaper, narrower ACL requirement) and add an instanceUrl pattern rejecting trailing slashes and scheme-less values - Enforce delete-documents ids/filter XOR and non-empty searchRules imperatively in exec (zod refinements are stripped from deployed schemas and never run at runtime) - Fix searchRules grammar (allow null rules, reject booleans/arrays) and accept nested-array filter expressions across search/get/delete - Default tenant tokens to a 1h TTL, document expiresAt precedence, and raise a descriptive error when the key uid cannot be resolved - Add ids input to get-documents, nango devDependency, and simplify base64url to Buffer's native encoding; regenerate LLM doc indexes
- Make searchRule objects strict and re-validate searchRules inside exec:
Meilisearch ignores unknown rule keys, so a typo'd key would silently
broaden a signed tenant token's access
- Resolve the signing key uid by listing keys and matching locally instead
of GET /keys/{key}, which put the raw key in the URL path where proxy
and access logs record it unredacted
- Enforce non-empty document batches at runtime in add/update-documents
(action input schemas are not validated at runtime)
Declared input schemas are not enforced by the platform at runtime, so a missing or non-array documents field would throw a raw TypeError instead of a clean ActionError. All actions now validate their declared schema inside exec with nango.zodValidateInput; search/fetch keep forwarding the raw body so extra Meilisearch params pass through.
…ough search-documents and get-documents forward extra keys to Meilisearch, but their plain z.object schemas published additionalProperties: false. Use z.looseObject so the declared contract matches the passthrough behavior, and forward the validated data instead of the raw input.
59b9d85 to
34e112e
Compare
|
Some context on why we built this, from the Meilisearch side 👋 I'm Quentin, co-founder/CEO of Meilisearch. Our customers constantly ask how to get data into their indexes from tools like Slack, Notion, Google Drive, Zendesk, HubSpot, Salesforce, Shopify, GitHub, or Gong. Nango's pre-built syncs already cover ~170 of these sources. This provider closes the loop: syncs pull the data out, and these actions push it into Meilisearch (including per-tenant search ACLs via the tenant-token action). A few things we're planning around it:
We'd love to make this a real partnership. If that's interesting, ping me here or at quentin@meilisearch.com and we'll set something up. |
Summary
Adds Meilisearch as an integration: an
API_KEYprovider plus 7 pre-built zero-yaml actions covering document read/write, batch & partial updates, deletion, async-task polling, and tenant-token generation for per-tenant search ACLs.Provider (
packages/providers/providers.yaml)API_KEYauth against a user-suppliedinstanceUrl(Meilisearch Cloud or self-hosted),authorization: Bearer ${apiKey}.GET /version(works with the Default Admin API Key and any custom key holding theversionaction, without requiring key-management ACLs).instanceUrlpattern rejects scheme-less values and trailing slashes (a trailing slash survives proxy interpolation and would 404 every call).Actions (
integrations/meilisearch/)search-documents/get-documentsadd-documents/update-documentsEnqueuedTask)delete-documentsexecsince zod refinements are stripped from deployed schemasget-taskgenerate-tenant-tokensearchRules(per-index filters). Hand-rolled withcrypto(runner allowlist has nojsonwebtoken); key uid auto-resolved viaGET /keys/{key}with a descriptive error when the key lackskeys.get; 1h default TTLFilter inputs accept Meilisearch's full grammar (string, array, nested OR-of-ANDs arrays);
searchRulesvalues accept objects ornull.Docs
docs/integrations/all/meilisearch.mdx,docs.jsonnav entry, logo, regenerated LLM indexes (npm run docs:generate:llms).Test Plan
npx vitest run integrations/meilisearchnpm run lint/ prettier clean; providers tests passnango deploy devregisters all 7 actions, and every action triggered viaPOST /action/triggerexecutes through the runner. The Nango-minted tenant token was verified to be accepted by Meilisearch and to enforce its filter (token sees only its tenant's documents and cannot widen scope).