@netlify/agent-runner-cli 1.175.0-run-started.0 → 1.175.1-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin-local.js +99 -99
- package/dist/bin.js +61 -61
- package/dist/index.js +95 -95
- package/dist/skills/netlify-connections/SKILL.md +114 -0
- package/package.json +1 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: netlify-connections
|
|
3
|
+
description: Call a third-party service from deployed site code using a connection the project has already authorized, with no provider API key. Use when server-side code needs to reach Stripe or another connected service at runtime. Must be read before writing any code that would otherwise require a provider secret such as STRIPE_SECRET_KEY.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Netlify Connections
|
|
7
|
+
|
|
8
|
+
A connected service is authorized **for the project**, not just for this run. Deployed code can
|
|
9
|
+
reuse that authorization, so that service needs no provider API key in the site.
|
|
10
|
+
|
|
11
|
+
## When to use this
|
|
12
|
+
|
|
13
|
+
You are writing server-side code — a Netlify Function, an edge function, a framework route
|
|
14
|
+
handler — that needs to call a service listed under **Connected services** in your context.
|
|
15
|
+
|
|
16
|
+
For those services **do not** write `process.env.<SERVICE>_SECRET_KEY` or ask the user for a
|
|
17
|
+
provider key — the project already has an authorized connection, so use it.
|
|
18
|
+
|
|
19
|
+
This applies only to services listed under **Connected services**. Anything else has no connection
|
|
20
|
+
to reuse, and an API key in the environment is the normal way to reach it.
|
|
21
|
+
|
|
22
|
+
The tools you have for these services are for **your own use during this run** (looking things up,
|
|
23
|
+
creating records as part of the task). They are not available to the deployed site. Deployed code
|
|
24
|
+
uses the HTTP endpoint below.
|
|
25
|
+
|
|
26
|
+
## How it works
|
|
27
|
+
|
|
28
|
+
When a service is authorized for the project, Netlify sets two environment variables on it,
|
|
29
|
+
scoped to functions, for the production and deploy-preview contexts. Nothing to enable — if the
|
|
30
|
+
service is listed under **Connected services**, these are already set:
|
|
31
|
+
|
|
32
|
+
| Variable | What it is |
|
|
33
|
+
|----------|------------|
|
|
34
|
+
| `NETLIFY_CONNECTIONS_URL` | Base URL for this project's connections |
|
|
35
|
+
| `NETLIFY_CONNECTIONS_TOKEN` | This project's credential. Identifies the site; grants nothing on its own |
|
|
36
|
+
|
|
37
|
+
You call Netlify, Netlify calls the provider with the stored credential. The path after
|
|
38
|
+
`/proxy/` is the **provider's own API path**, so write the request you would write against the
|
|
39
|
+
provider directly and change only the host.
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
${NETLIFY_CONNECTIONS_URL}/<service>/proxy/<provider path>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`.../stripe/proxy/v1/products` reaches `https://api.stripe.com/v1/products`.
|
|
46
|
+
|
|
47
|
+
## Example
|
|
48
|
+
|
|
49
|
+
A checkout endpoint, with no Stripe key anywhere:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// netlify/functions/create-checkout.mts
|
|
53
|
+
export default async (req: Request) => {
|
|
54
|
+
const { priceId } = await req.json()
|
|
55
|
+
|
|
56
|
+
const response = await fetch(`${process.env.NETLIFY_CONNECTIONS_URL}/stripe/proxy/v1/checkout/sessions`, {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
headers: {
|
|
59
|
+
authorization: `Bearer ${process.env.NETLIFY_CONNECTIONS_TOKEN}`,
|
|
60
|
+
'content-type': 'application/x-www-form-urlencoded',
|
|
61
|
+
},
|
|
62
|
+
body: new URLSearchParams({
|
|
63
|
+
mode: 'payment',
|
|
64
|
+
'line_items[0][price]': priceId,
|
|
65
|
+
'line_items[0][quantity]': '1',
|
|
66
|
+
success_url: `${process.env.URL}/success`,
|
|
67
|
+
cancel_url: `${process.env.URL}/`,
|
|
68
|
+
}),
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
return new Response('Could not start checkout', { status: 502 })
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const session = await response.json()
|
|
76
|
+
return Response.json({ url: session.url })
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The response is the provider's own response, status and body unchanged, so parse it exactly as
|
|
81
|
+
you would parse Stripe's.
|
|
82
|
+
|
|
83
|
+
## What you can reach
|
|
84
|
+
|
|
85
|
+
Any path on a service listed under **Connected services**. The path after `/proxy/` is the
|
|
86
|
+
provider's own API path, so use the provider's documented endpoints directly.
|
|
87
|
+
|
|
88
|
+
A service that is not listed is not reachable **through this proxy**, which is not a blocker on its
|
|
89
|
+
own: a service with no connection is reached the ordinary way, with its own credential from the
|
|
90
|
+
environment. Report it in your result only when the task needs a service you can reach no other way.
|
|
91
|
+
|
|
92
|
+
## Other responses
|
|
93
|
+
|
|
94
|
+
| Status | Meaning | What to do |
|
|
95
|
+
|--------|---------|------------|
|
|
96
|
+
| 404 | Service not connected for this project, or connections are off | Do not retry. |
|
|
97
|
+
| 424 | The connection needs to be reauthorized by the user | Surface it in your result. Handle it in code as a user-facing "reconnect Stripe" state, not a crash. |
|
|
98
|
+
| 502 | The provider could not be reached | Transient. Fail the request cleanly. |
|
|
99
|
+
|
|
100
|
+
## Security
|
|
101
|
+
|
|
102
|
+
- **This endpoint is as public as the function you put it in.** The token is the project's, not
|
|
103
|
+
the visitor's, so anyone who can reach your handler acts with the project's authority. Build the
|
|
104
|
+
request server-side from fixed values and validate anything that comes from the caller. Never
|
|
105
|
+
forward a caller-supplied body, path, or query straight through — that hands a visitor the whole
|
|
106
|
+
allowed surface, including writes.
|
|
107
|
+
- Never return `NETLIFY_CONNECTIONS_TOKEN` to the browser, embed it in client-side code, or put
|
|
108
|
+
it in a framework's public env namespace (`VITE_`, `NEXT_PUBLIC_`, `PUBLIC_`). Server-side only.
|
|
109
|
+
- Never log the token or the provider's raw responses.
|
|
110
|
+
|
|
111
|
+
## Checklist
|
|
112
|
+
|
|
113
|
+
1. Check the service is listed under **Connected services** in your context.
|
|
114
|
+
2. Write the call server-side using both environment variables.
|
package/package.json
CHANGED