Skip to content

Commit 6d87500

Browse files
author
Karl Rankla
committed
Update ERP toolkit documentation: Connector integration type + managed_call use cases, protected field + secure proxy improvements
1 parent 91d4a7e commit 6d87500

2 files changed

Lines changed: 220 additions & 3 deletions

File tree

docs/integrations/erp-toolkit/configuration.md

Lines changed: 192 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ This guide covers how to configure integrations, use cases, and manage your ERP
1010

1111
## Integration Management
1212

13+
### Integration Types
14+
15+
Integrations support two types:
16+
17+
| Type | Description |
18+
|------|-------------|
19+
| `erp` (default) | Standard ERP integration with inbound/outbound use cases |
20+
| `connector` | Complex proxy integration with external APIs using managed calls |
21+
1322
### Creating an Integration
1423

1524
```bash
@@ -22,6 +31,39 @@ curl -X POST 'https://erp-integration.sls.epilot.io/v2/integrations' \
2231
}'
2332
```
2433

34+
**Creating a Connector Integration:**
35+
36+
```bash
37+
curl -X POST 'https://erp-integration.sls.epilot.io/v2/integrations' \
38+
-H 'Authorization: Bearer <token>' \
39+
-H 'Content-Type: application/json' \
40+
-d '{
41+
"name": "Partner API Connector",
42+
"description": "Connector for partner API calls",
43+
"integration_type": "connector",
44+
"connector_config": {
45+
"base_url": "https://api.partner.com",
46+
"auth": {
47+
"type": "oauth2_client_credentials",
48+
"token_url": "{{env.PARTNER_TOKEN_URL}}",
49+
"client_id": "{{env.PARTNER_CLIENT_ID}}",
50+
"client_secret": "{{env.PARTNER_CLIENT_SECRET}}",
51+
"scope": "api:read api:write"
52+
}
53+
}
54+
}'
55+
```
56+
57+
### Integration Properties
58+
59+
| Property | Type | Required | Description |
60+
|----------|------|----------|-------------|
61+
| `name` | string | Yes | Display name |
62+
| `description` | string | No | Human-readable description |
63+
| `integration_type` | string | No | `erp` (default) or `connector` |
64+
| `connector_config` | object | No | Shared config for connector-type integrations (base URL, auth) |
65+
| `protected` | boolean | No | When `true`, prevents deletion and restricts modifications to admin users |
66+
2567
### Listing Integrations
2668

2769
```bash
@@ -75,12 +117,14 @@ curl -X POST 'https://erp-integration.sls.epilot.io/v1/integrations/{integration
75117
| Property | Type | Required | Description |
76118
|----------|------|----------|-------------|
77119
| `name` | string | Yes | Display name for the use case |
78-
| `type` | string | Yes | `inbound`, `outbound`, or `file_proxy` |
120+
| `type` | string | Yes | `inbound`, `outbound`, `file_proxy`, `managed_call`, or `secure_proxy` |
79121
| `enabled` | boolean | Yes | Whether the use case is active |
80-
| `configuration` | object | Yes | Mapping configuration (for inbound/outbound) or [File Proxy configuration](./file-proxy) (for `file_proxy`) |
122+
| `configuration` | object | Yes | Type-specific configuration (see sections below) |
81123

82124
:::info
83-
The `file_proxy` type is used for on-demand file serving from external document systems. See the [File Proxy guide](./file-proxy) for configuration details.
125+
- `file_proxy` — On-demand file serving from external document systems. See the [File Proxy guide](./file-proxy).
126+
- `managed_call` — Synchronous external API calls with JSONata mapping. See [Managed Call Use Cases](#managed-call-use-cases).
127+
- `secure_proxy` — Route requests through VPC Lambdas for static IP or VPN access. See [Secure Proxy Use Cases](#secure-proxy-use-cases).
84128
:::
85129

86130
### Enabling/Disabling a Use Case
@@ -149,6 +193,151 @@ curl -X GET 'https://erp-integration.sls.epilot.io/v1/integrations/{integrationI
149193
}
150194
```
151195

196+
## Managed Call Use Cases
197+
198+
Managed call use cases define synchronous API operations against external partner systems. They are typically used with `connector`-type integrations.
199+
200+
### Creating a Managed Call Use Case
201+
202+
```bash
203+
curl -X POST 'https://erp-integration.sls.epilot.io/v1/integrations/{integrationId}/use-cases' \
204+
-H 'Authorization: Bearer <token>' \
205+
-H 'Content-Type: application/json' \
206+
-d '{
207+
"name": "Get Customer",
208+
"slug": "get-customer",
209+
"type": "managed_call",
210+
"enabled": true,
211+
"configuration": {
212+
"operation": {
213+
"method": "GET",
214+
"path": "/v1/customers/{{customer_id}}",
215+
"headers": {
216+
"Accept": "application/json"
217+
}
218+
},
219+
"response_mapping": "{ \"name\": data.full_name, \"email\": data.contact.email }",
220+
"inbound_use_case_slug": "sync-customer"
221+
}
222+
}'
223+
```
224+
225+
### Executing a Managed Call
226+
227+
Managed calls are executed via the `/v1/managed-call/{slug}/execute` endpoint, where the slug acts as the RPC method name:
228+
229+
```bash
230+
curl -X POST 'https://erp-integration.sls.epilot.io/v1/managed-call/get-customer/execute' \
231+
-H 'Authorization: Bearer <token>' \
232+
-H 'Content-Type: application/json' \
233+
-d '{
234+
"integration_id": "<integration-id>",
235+
"payload": {
236+
"customer_id": "C001"
237+
}
238+
}'
239+
```
240+
241+
**Response:**
242+
243+
```json
244+
{
245+
"success": true,
246+
"data": {
247+
"name": "John Doe",
248+
"email": "john@example.com"
249+
},
250+
"inbound_queued": true,
251+
"inbound_event_id": "evt-abc-123"
252+
}
253+
```
254+
255+
### Managed Call Configuration Fields
256+
257+
| Field | Required | Description |
258+
|-------|----------|-------------|
259+
| `operation.method` | Yes | HTTP method: `GET`, `POST`, `PUT`, `PATCH`, or `DELETE` |
260+
| `operation.path` | Yes | URL path template with `{{variable}}` interpolation, appended to the connector's `base_url` |
261+
| `operation.headers` | No | Additional request headers |
262+
| `operation.query_params` | No | Query parameters |
263+
| `request_mapping` | No | JSONata expression to transform the request body before sending |
264+
| `response_mapping` | No | JSONata expression to transform the response before returning |
265+
| `inbound_use_case_slug` | No | Slug of an inbound use case to route the response to for async entity processing |
266+
267+
### Connector Authentication
268+
269+
Authentication is configured at the integration level via `connector_config.auth` and applied automatically to all managed call requests:
270+
271+
| Auth Type | Fields |
272+
|-----------|--------|
273+
| `oauth2_client_credentials` | `token_url`, `client_id`, `client_secret`, `scope`, `audience`, `resource`, `body_params`, `headers`, `query_params` |
274+
| `api_key` | `api_key_header` (default: `X-API-Key`), `api_key` |
275+
| `bearer` | `token` |
276+
277+
Secrets must use `{{env.KEY}}` references to resolve values from the [Environments API](/docs/integrations/webhooks/environments-secrets).
278+
279+
## Secure Proxy Use Cases
280+
281+
Secure proxy use cases route HTTP requests through VPC-deployed Lambda functions for static IP egress or VPN access to customer private networks.
282+
283+
### Creating a Secure Proxy Use Case
284+
285+
```bash
286+
curl -X POST 'https://erp-integration.sls.epilot.io/v1/integrations/{integrationId}/use-cases' \
287+
-H 'Authorization: Bearer <token>' \
288+
-H 'Content-Type: application/json' \
289+
-d '{
290+
"name": "Partner API Proxy",
291+
"slug": "partner-api",
292+
"type": "secure_proxy",
293+
"enabled": true,
294+
"configuration": {
295+
"vpc_mode": "secure_link"
296+
}
297+
}'
298+
```
299+
300+
### Secure Proxy Configuration Fields
301+
302+
| Field | Required | Mutable | Description |
303+
|-------|----------|---------|-------------|
304+
| `vpc_mode` | Yes | No (immutable) | `"static_ip"` (NAT Gateway for fixed outbound IP) or `"secure_link"` (VPN for private networks) |
305+
| `allowed_domains` | No | Admin only | Array of allowed domain patterns. Supports exact match and wildcard prefix (e.g., `*.example.com`). Managed via admin script only. |
306+
| `allowed_ips` | No | Admin only | Array of allowed IP ranges in CIDR notation (e.g., `10.0.1.0/24`). Required for `secure_link` mode. Managed via admin script only. |
307+
308+
### Sending a Proxy Request
309+
310+
```bash
311+
curl -X POST 'https://erp-integration.sls.epilot.io/v1/secure-proxy' \
312+
-H 'Authorization: Bearer <token>' \
313+
-H 'Content-Type: application/json' \
314+
-d '{
315+
"integration_id": "<integration-id>",
316+
"use_case_slug": "partner-api",
317+
"url": "https://api.partner.com/v1/data",
318+
"method": "GET",
319+
"headers": {
320+
"Authorization": "Bearer external-token"
321+
}
322+
}'
323+
```
324+
325+
### Domain Whitelist and IP Allowlist
326+
327+
- **Domain whitelist**: Controls which hostnames the proxy can reach. Wildcard patterns must have at least 2 suffix labels (e.g., `*.example.com` is valid, `*.com` is rejected).
328+
- **IP allowlist**: Controls which IP addresses are permitted in `secure_link` mode using CIDR notation. Validation is applied both at the URL level (direct IP targets) and DNS level (resolved IPs must match).
329+
- Both fields are read-only in the API and can only be managed via the admin script (`scripts/manage-secure-proxy-whitelist.ts`).
330+
331+
### Security
332+
333+
| Concern | Static IP mode | Secure Link mode |
334+
|---------|---------------|-----------------|
335+
| SSRF protection | Full (private IPs blocked) | Protocol + localhost only (private IPs allowed for VPN) |
336+
| Domain whitelist | Optional | Required |
337+
| IP allowlist | N/A | Required |
338+
| Request size limit | 4 MB | 4 MB |
339+
| Timeout | 25s (VPC Lambda) / 30s (API Gateway) | 25s (VPC Lambda) / 30s (API Gateway) |
340+
152341
## Event Configuration
153342

154343
### Event Message Structure

docs/integrations/erp-toolkit/overview.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ The ERP Toolkit is composed of the following components. Each plays a specific r
3333
| **[Webhooks](/docs/integrations/webhooks)** | Push events from epilot to ERPs via core events | Stable |
3434
| **[JSONata Mapping](#jsonata-mapping)** | Transformation language for inbound and outbound data | Stable |
3535
| **[File Proxy](./file-proxy)** | Serve files from external archives on demand without migrating them into epilot | Stable |
36+
| **[Managed Calls](#managed-calls)** | Synchronous external API calls with JSONata mapping via connector integrations | Stable |
37+
| **[Secure Proxy](#secure-proxy)** | Route HTTP requests through VPC Lambdas for static IP egress or VPN access | Stable |
3638
| **[Monitoring and ACKs](#monitoring-and-acks)** | Central logging, error tracking, and event replay | In progress |
3739
| **[Blueprints](https://marketplace.epilot.cloud/en/blueprints)** | Packaged, installable integration setups | Stable |
3840
| **[Apps](https://marketplace.epilot.cloud/en/apps)** | Custom automation actions and portal extensions for ERP logic | In progress |
@@ -49,8 +51,12 @@ The `/v2/integrations` CRUD API centralizes all integration configuration in one
4951
- **API tokens** with scoped roles and permissions
5052
- **Inbound use cases** with entity mappings
5153
- **Outbound use cases** with event mappings
54+
- **Managed call use cases** for synchronous external API calls (connector integrations)
55+
- **Secure proxy use cases** for VPC-routed HTTP requests
5256
- **Associated Apps and portal extensions**
5357

58+
Integrations support two types: `erp` (default, for standard ERP flows) and `connector` (for complex proxy integrations with external APIs).
59+
5460
See the [Configuration Guide](./configuration) for API details.
5561

5662
### Inbound API
@@ -79,6 +85,28 @@ See the [Use Cases](./use-cases) page for a complete list of inbound and outboun
7985

8086
The [File Proxy](./file-proxy) enables epilot to serve files from external document systems (e.g., ERP archives, DMS) on demand. Instead of migrating file content during inbound sync, file entities are created with a `custom_download_url` pointing to the proxy. When a user views the file, the proxy fetches the document from the external system in real time using a declarative, multi-step HTTP configuration.
8187

88+
### Managed Calls
89+
90+
Managed Calls enable synchronous API calls to external partner systems with built-in authentication, JSONata mapping, and optional inbound routing. They are configured as `managed_call` use cases within `connector`-type integrations.
91+
92+
Key capabilities:
93+
- **Authentication** — OAuth2 client credentials, API key, or bearer token with automatic token management
94+
- **JSONata mapping** — Transform request and response payloads using JSONata expressions
95+
- **Inbound routing** — Optionally queue the response to the inbound pipeline for async entity processing
96+
- **Secure proxy support** — Route calls through static IP or VPN VPCs when needed
97+
98+
See the [Configuration Guide](./configuration#managed-call-use-cases) for setup details.
99+
100+
### Secure Proxy
101+
102+
The Secure Proxy routes HTTP requests through VPC-deployed Lambda functions, providing either **static IP egress** (for IP-allowlisted external APIs) or **VPN access** (for customer private networks). It acts as the single authenticated gateway between epilot and customer networks.
103+
104+
- **Static IP mode** — Routes through a NAT Gateway for a fixed outbound IP address
105+
- **Secure Link mode** — Routes through a VPN-connected VPC for access to private networks
106+
- Domain whitelisting and CIDR-based IP allowlisting enforce strict access control
107+
108+
See the [Configuration Guide](./configuration#secure-proxy-use-cases) for setup details.
109+
82110
### JSONata Mapping
83111

84112
[JSONata](https://jsonata.org/) is the core transformation language for defining mappings between epilot's standardized entity/event schemas and ERP-specific data models. It is used across:

0 commit comments

Comments
 (0)