@patchstack/connect 0.3.25 → 0.3.27
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/AGENT-INSTALL.md +62 -5
- package/README.md +6 -5
- package/dist/cli.js +203 -83
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/protect.cjs +33 -1
- package/dist/protect.cjs.map +1 -1
- package/dist/protect.edge.js +33 -1
- package/dist/protect.edge.js.map +2 -2
- package/dist/protect.js +34 -2
- package/dist/protect.js.map +1 -1
- package/dist/{refresh-manifest-MUWVIPFR.js → refresh-manifest-KZSQD2X3.js} +1 -1
- package/dist/refresh-manifest-KZSQD2X3.js.map +1 -0
- package/package.json +1 -1
- package/dist/refresh-manifest-MUWVIPFR.js.map +0 -1
package/AGENT-INSTALL.md
CHANGED
|
@@ -76,12 +76,13 @@ This versioned reference ships inside `@patchstack/connect` and documents each s
|
|
|
76
76
|
<script src="https://cdn.patchstack.com/patchstack-widget.js" data-site-uuid="<SITE_UUID>" defer></script>
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
Framework-specific placement patterns: https://cdn.patchstack.com/llm.html. The site UUID is public by design — it ships in client-side HTML and is not a secret. The
|
|
79
|
+
Framework-specific placement patterns: https://cdn.patchstack.com/llm.html. The site UUID is public by design — it ships in client-side HTML and is not a secret. The credential is the opposite, and `scan` writes it for you — **there is no manual step, and you should never invent or ask the user for this value**:
|
|
80
80
|
|
|
81
|
-
- `apiKey` (also `PATCHSTACK_API_KEY`, WP format `{secret}-{oauth.id}`) — authenticates block-log reporting through the connector `POST /api/logs/log`, so "Threats blocked" fills in the dashboard.
|
|
82
|
-
- `pulseAuth` (also `PATCHSTACK_PULSE_AUTH`) — authenticates Pulse ingest: the manifest, the attack-surface map and package removal. Exchanged for a short-lived token rather than sent directly. Falls back to `apiKey` when absent, so older projects keep working.
|
|
81
|
+
- `apiKey` (also `PATCHSTACK_API_KEY`, WP format `{secret}-{oauth.id}`) — one credential for both paths. It authenticates **Pulse ingest** (manifest, attack-surface map, package removal), where it is exchanged for a short-lived token rather than sent directly, and **block-log reporting** through the connector `POST /api/logs/log`, so "Threats blocked" fills in the dashboard.
|
|
83
82
|
|
|
84
|
-
|
|
83
|
+
It is server-only. Never put it in the widget tag, client bundles, or public env vars (`NEXT_PUBLIC_*`, etc.). Prefer `PATCHSTACK_API_KEY` in production; `.patchstackrc.json` is fine for local DX. If it is lost, `npx @patchstack/connect login` recovers it via dashboard approval — do not delete the file and re-provision, which would create a second site. Opt out of reporting with `PATCHSTACK_TELEMETRY=off`. If the project must not carry the widget, persist `"widget": false` in `.patchstackrc.json`; otherwise the next scan re-adds it.
|
|
84
|
+
|
|
85
|
+
A `pulseAuth` field is still honoured if a project has one, and `PATCHSTACK_PULSE_AUTH` still overrides it, for deployments that authenticate Pulse ingest with a different credential from block-logs. Do not add either yourself: they are unnecessary when the two share one credential, which is the default.
|
|
85
86
|
|
|
86
87
|
4. **Install and verify runtime protection:**
|
|
87
88
|
|
|
@@ -102,7 +103,7 @@ Both are server-only. Never put either in the widget tag, client bundles, or pub
|
|
|
102
103
|
- The CLI never opens the dashboard link and never asks for Patchstack credentials.
|
|
103
104
|
- Label hosted workspace scans with `PATCHSTACK_ENVIRONMENT=sandbox` in that process only. Leave production builds unset (the default is `production`) and never commit a sandbox label into files shared with production.
|
|
104
105
|
- If a step fails, stop and report it. Don't proceed with placeholders.
|
|
105
|
-
- In CI where `.patchstackrc.json` can't be committed, set `PATCHSTACK_SITE_UUID` and `
|
|
106
|
+
- In CI where `.patchstackrc.json` can't be committed, set `PATCHSTACK_SITE_UUID` and `PATCHSTACK_API_KEY` as env vars instead. Precedence: CLI flag → env var → `.patchstackrc.json`. `login` is interactive and refuses to run in CI, so CI always takes its credential from the environment.
|
|
106
107
|
|
|
107
108
|
## Verifying the install
|
|
108
109
|
|
|
@@ -119,6 +120,62 @@ These are **two independent states** — never conflate them:
|
|
|
119
120
|
|
|
120
121
|
Local files alone cannot tell you whether the site was removed from Patchstack. Run `npx @patchstack/connect status` and read the `Site status` line, then answer with both states. For example, when the site was removed but the local files remain, say: *"The site itself was removed from Patchstack — reporting has stopped and the widget no longer renders. The local integration code (widget tag, `.patchstackrc.json`, the dependency) is still in the project; want me to remove it?"* — not "Patchstack is still installed."
|
|
121
122
|
|
|
123
|
+
## Recovering a lost credential — `login`
|
|
124
|
+
|
|
125
|
+
Use this when the project **already has a site** but its credential is gone or rejected: `.patchstackrc.json` was deleted or never committed, the repo was cloned without it, a container was recycled, or ingest started failing with 401.
|
|
126
|
+
|
|
127
|
+
> **Do not "fix" a missing credential by deleting `.patchstackrc.json` and running `scan` again.** That provisions a **second site**, and the original — with all its history and its widget tag already live on the deployed page — is orphaned. `login` recovers the existing one.
|
|
128
|
+
|
|
129
|
+
### What it does
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
npx @patchstack/connect login
|
|
133
|
+
|
|
134
|
+
Your code: WDJB-MJHT
|
|
135
|
+
Approve at: https://api.patchstack.com/monitor/pulse/device?code=WDJB-MJHT
|
|
136
|
+
|
|
137
|
+
Waiting for approval… ✓ Credential restored
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The command asks Patchstack for a short code, prints a link, and polls until the site's **owner approves it in the dashboard**. On approval it writes the new credential into `.patchstackrc.json` and exits. The link opens the approval page with the code already filled in, so the person only has to confirm.
|
|
141
|
+
|
|
142
|
+
### What you must do, as the agent — two commands, not one
|
|
143
|
+
|
|
144
|
+
**The command exits immediately when you run it.** It detects that its output is being captured rather than watched by a person, prints the link, and returns. It does **not** block waiting for approval, because you would not see the link until it exited — by which time the code would have expired, and it would look like the command had hung.
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
1. npx @patchstack/connect login → prints the link, exits straight away
|
|
148
|
+
2. give the user the link, verbatim → they approve it in the browser
|
|
149
|
+
3. npx @patchstack/connect login → the SAME command again, after they confirm.
|
|
150
|
+
It resumes the request and finishes the flow
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
- **Never wrap step 1 in a timeout or kill it** — it returns on its own. If you find yourself waiting on it, something else is wrong.
|
|
154
|
+
- **Step 3 is the same command.** While a request is still valid it resumes rather than restarting, so running `login` again never invalidates the link the user is looking at. If they have not approved yet it tells you so, with the time remaining, and exits.
|
|
155
|
+
- **Nothing changes until step 3 runs.** Approving only marks the request; the credential is rotated and written when the CLI redeems it. So an abandoned flow is harmless — the site keeps working — but the credential is not restored until you come back.
|
|
156
|
+
- **Surface the link verbatim.** Approval requires the user's signed-in Patchstack account, which you do not have and must never ask for.
|
|
157
|
+
- **Report the outcome.** On success, say the credential was restored *and* that the previous one no longer works — see the warning below.
|
|
158
|
+
|
|
159
|
+
`login --wait` is the blocking variant: it polls until approved instead of returning. Prefer the plain re-run — it keeps each command short, which is what fits a conversation.
|
|
160
|
+
|
|
161
|
+
You cannot complete this alone. It is deliberately a human-in-the-loop step: starting the flow proves nothing about who is running it, so the only authorisation is an owner approving in the browser.
|
|
162
|
+
|
|
163
|
+
(In an interactive terminal the same command prints the link and then waits, since a person can watch it stream. You get the two-step form; a human at a shell gets the one-step form.)
|
|
164
|
+
|
|
165
|
+
### Consequences to tell the user about
|
|
166
|
+
|
|
167
|
+
**Approving rotates the credential — the old one stops working immediately.** Anywhere it was configured needs the new value: CI secrets, hosting-platform env vars, preview environments, other developers' checkouts. Say this before they approve, not after.
|
|
168
|
+
|
|
169
|
+
### When it will not work
|
|
170
|
+
|
|
171
|
+
| Situation | What happens | What to do |
|
|
172
|
+
|---|---|---|
|
|
173
|
+
| Site was never claimed | `409` — no owner exists to approve | Ask the user to claim the site in the dashboard first, or, if the site is disposable, delete `.patchstackrc.json` and `scan` to provision a fresh one |
|
|
174
|
+
| Running in CI | Refuses to start | CI takes its credential from `PATCHSTACK_PULSE_AUTH`; `login` is for a developer machine |
|
|
175
|
+
| No `siteUuid` configured | Refuses to start | There is no site to recover — run `scan` |
|
|
176
|
+
| Code expired | `--wait` ends after 10 minutes | Start again from step 1 for a new code |
|
|
177
|
+
| `--wait` with nothing pending | "No login is waiting for approval" | Run step 1 first; `--wait` resumes a request, it does not start one |
|
|
178
|
+
|
|
122
179
|
## Uninstalling
|
|
123
180
|
|
|
124
181
|
Remove only the pieces that are actually present — check for each first. If none are present, Patchstack isn't installed; report that and stop. If the user asked to remove only one piece (e.g. "just the widget"), remove only that piece.
|
package/README.md
CHANGED
|
@@ -119,22 +119,23 @@ Environment variables:
|
|
|
119
119
|
{
|
|
120
120
|
"siteUuid": "550e8400-e29b-41d4-a716-446655440000",
|
|
121
121
|
"apiKey": "…",
|
|
122
|
-
"pulseAuth": "…",
|
|
123
122
|
"widget": true
|
|
124
123
|
}
|
|
125
124
|
```
|
|
126
125
|
|
|
127
126
|
`"widget"` is optional and defaults to `true`; set it to `false` to stop the connector from managing the disclosure-widget tag (see *The disclosure widget*).
|
|
128
127
|
|
|
129
|
-
**You do not write `apiKey`
|
|
128
|
+
**You do not write `apiKey` yourself.** The first `scan` provisions the site and the connector saves it, so setup needs no manual step.
|
|
130
129
|
|
|
131
130
|
The site UUID identifies the site and is **not** a secret — the disclosure widget ships the same UUID in client-side HTML.
|
|
132
131
|
|
|
133
|
-
`apiKey`
|
|
132
|
+
`apiKey` **is** a secret. One credential authenticates both paths: Pulse ingest (manifest, attack-surface map, package removal), where it is exchanged for a short-lived token rather than sent directly, and block-log reporting. Keep it out of the widget tag, client bundles and public env vars (`NEXT_PUBLIC_*`). For deploys, prefer `PATCHSTACK_API_KEY` in the platform's secret store over the committed file.
|
|
134
133
|
|
|
135
|
-
If
|
|
134
|
+
If it is ever lost, `npx @patchstack/connect login` recovers it — approval happens in the dashboard and rotates the credential.
|
|
136
135
|
|
|
137
|
-
In CI setups where the file isn't committed, set `PATCHSTACK_SITE_UUID` and `
|
|
136
|
+
In CI setups where the file isn't committed, set `PATCHSTACK_SITE_UUID` and `PATCHSTACK_API_KEY`. Precedence is CLI flag → env var → `.patchstackrc.json`.
|
|
137
|
+
|
|
138
|
+
A `pulseAuth` field is still read if present, and `PATCHSTACK_PULSE_AUTH` still overrides, for deployments that authenticate Pulse ingest with a different credential from block-logs. Neither is written by default, and neither is needed when the two share one.
|
|
138
139
|
|
|
139
140
|
### Sandbox and production manifests
|
|
140
141
|
|