Skip to content

feat(agiloft): add Agiloft CLM integration with token-based auth#4133

Merged
waleedlatif1 merged 6 commits intostagingfrom
waleedlatif1/add-agiloft
Apr 13, 2026
Merged

feat(agiloft): add Agiloft CLM integration with token-based auth#4133
waleedlatif1 merged 6 commits intostagingfrom
waleedlatif1/add-agiloft

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

@waleedlatif1 waleedlatif1 commented Apr 13, 2026

Summary

  • Add complete Agiloft CLM integration with 12 tools: CRUD operations, search, select, saved search, file attachments (attach, retrieve, remove, info), and record locking
  • Uses token-based authentication via EWLogin/EWLogout — credentials are exchanged for short-lived Bearer tokens and never embedded in API request URLs
  • Includes block with operation dropdown, icon, docs, and internal API route for file attachment uploads

Test plan

  • Verify Agiloft CRUD operations (create, read, update, delete) work with valid credentials
  • Verify search and select return expected records
  • Verify file attach/retrieve/remove work end-to-end
  • Verify lock/unlock/check status operations
  • Confirm Bearer token is used in request headers (no credentials in URLs)
  • Confirm session cleanup (EWLogout) occurs after each operation

Add 12 tools (CRUD, search, select, saved search, attachments, lock),
block, icon, docs, and internal API route for file attachments.
Uses EWLogin/EWLogout for short-lived Bearer tokens — credentials
are never embedded in API request URLs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Apr 13, 2026 9:24pm

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 13, 2026

PR Summary

Medium Risk
Adds a new external-integration surface area (credentialed requests, file upload/download, and new API route) where mistakes could impact security and reliability despite SSRF/auth validations.

Overview
Adds a full Agiloft CLM integration: a new AgiloftBlock with an operation picker wired to 12 new agiloft_* tools (CRUD, search/select/saved search, attachments, and record locking) and registered in the global block/tool registries.

Implements token-based request execution via EWLogin/EWLogout in tools/agiloft/utils.ts plus a dedicated internal API route (/api/tools/agiloft/attach) to handle attachment uploads from stored files with internal auth + SSRF/DNS validation.

Updates the landing integrations data, docs site metadata, and both apps’ icon mappings by adding AgiloftIcon and a new tools/agiloft.mdx documentation page (plus a small Trello doc spacing tweak).

Reviewed by Cursor Bugbot for commit f278a21. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 13, 2026

Greptile Summary

This PR adds a complete Agiloft CLM integration with 12 tools covering CRUD operations, attachment management, search/select, saved searches, and record locking. The implementation uses a token-exchange pattern (EWLogin → Bearer token → EWLogout) and routes file uploads through an internal API endpoint with DNS-level SSRF protection.

All HTTP methods have been verified against the official Agiloft REST API docs — including GET/POST for EWRemoveAttachment, PUT for EWAttach, and GET/PUT/DELETE for EWLock. Prior review feedback on HTTPS enforcement, optional chaining on data.output, the AgiloftSavedSearchParams type alias, and the file attachment guard has been addressed.

Confidence Score: 5/5

Safe to merge — all prior review concerns are resolved, HTTP methods verified against official Agiloft API docs, no new P0/P1 issues found.

All prior feedback (HTTPS guard, optional chaining on data.output, AgiloftSavedSearchParams type alias, file null guard) has been addressed. HTTP methods match the official Agiloft REST API docs. Credential visibility follows the codebase rule (user-only). SSRF protection is in place at both the tool layer and route layer. No remaining P0 or P1 findings.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/tools/agiloft/utils.ts Core auth/URL utilities; HTTPS enforcement via validateExternalUrl, proper try/finally logout, token injected centrally in executeAgiloftRequest.
apps/sim/app/api/tools/agiloft/attach/route.ts File attachment route uses validateUrlWithDNS (DNS-level SSRF guard), processFilesToUserFiles, downloadFileFromStorage, and a correct try/finally for token cleanup.
apps/sim/blocks/blocks/agiloft.ts Block config correctly uses AuthMode.ApiKey, normalizeFileInput for the canonical attachFile param, and proper condition/required rules for all 12 operations.
apps/sim/tools/agiloft/retrieve_attachment.ts Returns base64-encoded file data; FileToolProcessor is applied automatically by the executor, consistent with how other file-output tools work in the codebase.
apps/sim/tools/agiloft/remove_attachment.ts Uses GET method for EWRemoveAttachment, correct per official Agiloft API docs; prior commit using DELETE was corrected in the final commit.
apps/sim/tools/agiloft/types.ts All response interfaces properly typed; AgiloftSavedSearchParams correctly simplified to a type alias per prior review feedback.
apps/sim/tools/agiloft/lock_record.ts getLockHttpMethod correctly maps lock→PUT, unlock→DELETE, check→GET, matching Agiloft API docs.
apps/sim/tools/agiloft/search_records.ts Handles multiple Agiloft response formats including the EWREST_length flat-object pattern; pagination defaults are reasonable.

Sequence Diagram

sequenceDiagram
    participant E as Executor
    participant U as utils.ts
    participant A as Agiloft API

    E->>U: directExecution(params)
    U->>U: validateExternalUrl(instanceUrl)
    U->>A: POST /ewws/EWLogin (KB + credentials in query)
    A-->>U: access_token
    U->>A: Request with Authorization Bearer header
    A-->>U: Response data
    U->>U: transformResponse(response)
    U->>A: POST /ewws/EWLogout (best-effort, finally block)
    U-->>E: ToolResponse

    Note over E,A: attach_file uses internal API route
    E->>+Route: POST /api/tools/agiloft/attach
    Route->>Route: validateUrlWithDNS (DNS-level SSRF guard)
    Route->>A: POST /ewws/EWLogin
    Route->>A: PUT /ewws/EWAttach (binary body, Bearer)
    A-->>Route: attachment count
    Route->>A: POST /ewws/EWLogout (finally block)
    Route-->>-E: success output
Loading

Reviews (4): Last reviewed commit: "fix(agiloft): correct HTTP methods and p..." | Re-trigger Greptile

- Add HTTPS enforcement guard to agiloftLogin to prevent plaintext credential transit
- Add null guard on data.output in attach_file transformResponse
- Change empty AgiloftSavedSearchParams interface to type alias

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Validates user-supplied instanceUrl against private/reserved IP ranges
using validateUrlWithDNS before making any outbound requests. Uses dynamic
import to avoid bundling Node.js dns module in client-side code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace dynamic import of input-validation.server (which Turbopack traces
into the client bundle) with client-safe validateExternalUrl in utils.ts.
Add full DNS-level SSRF validation via validateUrlWithDNS in the attach
API route (server-only file). This matches the Okta pattern for
directExecution tools and the textract pattern for API routes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 762d2ae. Configure here.

The remove_attachment tool was incorrectly using GET instead of DELETE
for the Agiloft EWRemoveAttachment endpoint, which would cause removals
to fail at runtime.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…I docs

- EWRemoveAttachment uses GET, not DELETE (revert incorrect change)
- EWRetrieve uses `filePosition` parameter, not `position`
- EWAttach uses PUT, not POST

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit f278a21. Configure here.

@waleedlatif1 waleedlatif1 merged commit fb4fb9e into staging Apr 13, 2026
12 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/add-agiloft branch April 13, 2026 21:36
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.

1 participant