requestshield 0.1.5 → 0.1.7
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/README.md +407 -269
- package/config/.env.prod +5 -0
- package/package.json +8 -5
- package/skills/requestshield/SKILL.md +55 -63
- package/skills/requestshield/assets/AGENTS.codex.md +17 -17
- package/skills/requestshield/references/backend-java-core.md +3 -3
- package/skills/requestshield/references/backend-spring-boot.md +3 -3
- package/skills/requestshield/references/browser-manual.md +4 -4
- package/skills/requestshield/references/browser-seamless.md +7 -15
- package/skills/requestshield/references/cli.md +93 -169
- package/skills/requestshield/references/integration-planning.md +19 -46
- package/skills/requestshield/references/troubleshooting.md +26 -30
- package/src/api-client.mjs +106 -165
- package/src/args.mjs +108 -151
- package/src/browser-opener.mjs +32 -0
- package/src/cli.mjs +50 -28
- package/src/commands/agent-setup.mjs +34 -37
- package/src/commands/application-mutations.mjs +33 -0
- package/src/commands/application-response.mjs +55 -0
- package/src/commands/apps-get.mjs +3 -47
- package/src/commands/apps-list.mjs +40 -36
- package/src/commands/auth-status.mjs +37 -0
- package/src/commands/keys-create.mjs +7 -38
- package/src/commands/mutation-support.mjs +110 -0
- package/src/commands/secret-commands.mjs +45 -0
- package/src/commands/signin.mjs +70 -57
- package/src/commands/signout.mjs +9 -0
- package/src/commands/update-check.mjs +12 -4
- package/src/config.mjs +145 -3
- package/src/entrypoint.mjs +24 -0
- package/src/errors.mjs +3 -1
- package/src/main.mjs +2 -21
- package/src/oauth-client.mjs +153 -0
- package/src/oauth-loopback.mjs +120 -0
- package/src/session-files.mjs +213 -0
- package/src/session-store.mjs +177 -64
- package/src/commands/billing-get.mjs +0 -110
- package/src/commands/challenge-volume.mjs +0 -81
- package/src/commands/contract.mjs +0 -106
|
@@ -1,183 +1,107 @@
|
|
|
1
1
|
# `requestshield` CLI reference
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- [General](#general)
|
|
18
|
-
- [Authentication](#authentication)
|
|
19
|
-
- [Key management](#key-management)
|
|
20
|
-
- [Integration contract](#integration-contract)
|
|
21
|
-
- [Applications](#applications)
|
|
22
|
-
- [Credentials](#credentials)
|
|
23
|
-
- [Service and monitoring](#service-and-monitoring)
|
|
24
|
-
- [Billing](#billing)
|
|
25
|
-
- [Agent integration](#agent-integration)
|
|
26
|
-
|
|
27
|
-
## General
|
|
28
|
-
|
|
29
|
-
| Command | Purpose |
|
|
30
|
-
| --- | --- |
|
|
31
|
-
| `requestshield --help` | Usage and the full command list. Run this if a command below is rejected — the installed CLI may be older or newer than this file. |
|
|
32
|
-
| `requestshield --version` | Installed CLI version, e.g. `requestshield 1.0.0`. |
|
|
33
|
-
| `requestshield update check` | Latest available version. Use it when behaviour disagrees with this reference. |
|
|
34
|
-
|
|
35
|
-
## Authentication
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
requestshield signin
|
|
39
|
-
requestshield auth status
|
|
3
|
+
Check `requestshield --version` and `requestshield --help` against this guide.
|
|
4
|
+
An older published version may not contain these commands. Use the CLI for its
|
|
5
|
+
supported application and credential operations; do not invent endpoints for
|
|
6
|
+
unavailable commands.
|
|
7
|
+
|
|
8
|
+
## Authentication and local commands
|
|
9
|
+
|
|
10
|
+
```console
|
|
11
|
+
requestshield signin [--no-open]
|
|
12
|
+
requestshield auth status [--json]
|
|
13
|
+
requestshield signout
|
|
14
|
+
requestshield --help
|
|
15
|
+
requestshield --version
|
|
40
16
|
```
|
|
41
17
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
`
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
## Key management
|
|
53
|
-
|
|
54
|
-
**The user runs these, not you.** They print the API Secret or change state for a live
|
|
55
|
-
App Key, so hand over the exact command and let them run it in their own terminal. See
|
|
56
|
-
"Key and secret management" in `SKILL.md` for the hand-off and the follow-up
|
|
57
|
-
presence check.
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
requestshield keys create --app-name <name>
|
|
61
|
-
requestshield keys deactive --app-key <app-key> # or --app-name <name>
|
|
62
|
-
requestshield app key rotate --app-key <app-key> # or --app-name <name>
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
`keys create` returns both halves:
|
|
66
|
-
|
|
67
|
-
```
|
|
68
|
-
App Key: app_123
|
|
69
|
-
Secret Key: rs_sk_xxxxx
|
|
70
|
-
Save this Secret Key now. It will not be shown again.
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
The Secret Key appears exactly once. Warn the user *before* they run the command that
|
|
74
|
-
they need somewhere to put it, and afterwards point them at the environment variable
|
|
75
|
-
rather than repeating the value. Never ask them to paste the secret back — confirm it
|
|
76
|
-
only by presence. See the secret-handling rules in `SKILL.md`.
|
|
77
|
-
|
|
78
|
-
`keys deactive` (spelled that way in the CLI) needs at least one of `--app-key` or
|
|
79
|
-
`--app-name`; if both are given, `--app-key` wins. Deactivation stops traffic being
|
|
80
|
-
verified for that key, so name the affected app explicitly when you hand the command
|
|
81
|
-
over and make sure the user means that key.
|
|
82
|
-
|
|
83
|
-
`app key rotate` issues a new Secret Key for an existing App Key and deactivates the
|
|
84
|
-
previous one. This is the correct response to a leaked or lost secret — it keeps the
|
|
85
|
-
App Key stable, so no browser or config change is needed beyond the new secret. Like
|
|
86
|
-
`keys create`, the user runs it.
|
|
87
|
-
|
|
88
|
-
## Integration contract
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
requestshield contract
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**auth.** The authoritative integration surface — run this before writing any
|
|
95
|
-
integration code. The block below is an **illustration of the shape only**; never read
|
|
96
|
-
values out of it, and in particular do not treat its `available_modes` as the modes your
|
|
97
|
-
customer has:
|
|
98
|
-
|
|
99
|
-
```json
|
|
100
|
-
{"ok":true,"data":{
|
|
101
|
-
"contract_version":"2026-08-27",
|
|
102
|
-
"browser":{"script_url":"https://.../intellifend.js","token_header":"X-IntelliFend-Token",
|
|
103
|
-
"available_modes":["manual"]},
|
|
104
|
-
"backend":{"supported_languages":["java"],"min_jdk":17},
|
|
105
|
-
"release_state":"..."}}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Use `script_url` and `token_header` verbatim. Check `available_modes` before committing
|
|
109
|
-
to seamless or manual — a mode absent from that list is not released, and writing an
|
|
110
|
-
integration against it produces code that will not work. Check `supported_languages`
|
|
111
|
-
before promising a backend integration for a stack that is not listed; the browser side
|
|
112
|
-
alone provides no protection, so an unsupported backend means the honest answer is
|
|
113
|
-
"not yet supported here".
|
|
18
|
+
Sign-in uses the user's browser on the same computer. Let the user complete it;
|
|
19
|
+
never ask for their password, tokens or callback URL. `auth status --json` reads
|
|
20
|
+
local metadata only and does not contact the provider or refresh credentials.
|
|
21
|
+
It returns `profile`, `apiUrl`, `issuer`, `clientId`, `state`, `localOnly: true`
|
|
22
|
+
and applicable `expiresAt`/`scopes`, never tokens or a customer/account identity.
|
|
23
|
+
States are `signed_out`, `valid`, `expired`, `refresh_uncertain`, `config_mismatch`,
|
|
24
|
+
`invalid` and `configuration_error`. Local validity is not provider acceptance.
|
|
25
|
+
Sign-out removes only the selected local session, not the browser session or
|
|
26
|
+
provider grant.
|
|
114
27
|
|
|
115
28
|
## Applications
|
|
116
29
|
|
|
117
|
-
```
|
|
118
|
-
requestshield apps list
|
|
30
|
+
```console
|
|
31
|
+
requestshield apps list [--json] [--limit <1-100>] [--cursor <cursor> | --all]
|
|
119
32
|
requestshield apps get <app-key>
|
|
33
|
+
requestshield apps rename <app-key> --name <name> [--idempotency-key <key>]
|
|
34
|
+
requestshield apps enable <app-key> [--idempotency-key <key>]
|
|
35
|
+
requestshield apps disable <app-key> [--idempotency-key <key>] [--yes]
|
|
120
36
|
```
|
|
121
37
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
is
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
requestshield server
|
|
147
|
-
requestshield challenge volume <app-key> [--from <time>] [--to <time>] [--granularity <value>]
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**auth.** `server` reports `healthy` or `degraded`. Check it first when an integration
|
|
151
|
-
that was working starts behaving oddly — a degraded platform explains fail-open
|
|
152
|
-
behaviour on the backend without anything being wrong in the customer's code.
|
|
153
|
-
|
|
154
|
-
`challenge volume` is runtime evidence that the browser/platform half is active. It is
|
|
155
|
-
not proof that the protected backend enforces a blocking decision; the controlled
|
|
156
|
-
negative test in `SKILL.md` provides that evidence. Times are ISO-8601
|
|
157
|
-
(`2026-08-01T00:00:00Z`); `--granularity` takes values such as `hour` or `day`. A
|
|
158
|
-
`challenge_count` of zero after the user has exercised the endpoint means the browser
|
|
159
|
-
half is not firing — that is a browser-side bug, not a backend one, so start with the
|
|
160
|
-
mode's reference file.
|
|
161
|
-
|
|
162
|
-
## Billing
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
requestshield get billing <app-key>
|
|
38
|
+
These commands require sign-in. Existing-app commands use exact App Keys; names
|
|
39
|
+
are not unique. List defaults to one page. `--all` follows at most 100 pages and
|
|
40
|
+
fails for repeated cursors or unfinished traversal at that bound. It cannot be
|
|
41
|
+
combined with `--cursor`. For name discovery, inspect all necessary pages and
|
|
42
|
+
resolve ambiguity with the user before choosing an App Key.
|
|
43
|
+
|
|
44
|
+
JSON list output is `{data:Application[],nextCursor}`. Detail and rename output
|
|
45
|
+
is `{data:Application}`. Application has exactly `appKey`, `name`, `status`,
|
|
46
|
+
`createdAt`, `updatedAt`. Status is `pending`, `enabled`, `disabled`, `revoked`
|
|
47
|
+
or `attention_required`; it describes configuration, not traffic or enforcement.
|
|
48
|
+
Pending, attention and disabled states do not expose the exact credential state.
|
|
49
|
+
Disable retains the secret; enable requires an active one.
|
|
50
|
+
|
|
51
|
+
## Key and secret management
|
|
52
|
+
|
|
53
|
+
Have the user run commands that print secrets in their own terminal so secret
|
|
54
|
+
values stay out of tool output and transcripts. Give the exact command and
|
|
55
|
+
confirm storage by presence only.
|
|
56
|
+
|
|
57
|
+
```console
|
|
58
|
+
requestshield keys create --app-name <name> [--idempotency-key <key>]
|
|
59
|
+
requestshield keys rotate <app-key> [--idempotency-key <key>] [--yes]
|
|
60
|
+
requestshield keys reveal <app-key> [--yes]
|
|
61
|
+
requestshield keys revoke <app-key> [--idempotency-key <key>] [--yes]
|
|
166
62
|
```
|
|
167
63
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
64
|
+
Create makes a new application and initial secret. Rotate preserves the App Key
|
|
65
|
+
and replaces the secret. Reveal retrieves the current active secret; use it to
|
|
66
|
+
recover a lost issuance response. Exposure requires rotation, not reveal.
|
|
67
|
+
Revoke invalidates the current secret. Create, rotate and reveal can display an
|
|
68
|
+
API secret; the CLI never persists it. Store it in backend secret storage.
|
|
69
|
+
|
|
70
|
+
Create, rename and enable have no prompt. Disable, rotate, revoke and reveal
|
|
71
|
+
require confirmation; `--yes` skips it. These commands can change live state or
|
|
72
|
+
disclose secrets, so ensure the target and action match the user's request.
|
|
73
|
+
|
|
74
|
+
All mutations except reveal accept an idempotency key. A fresh key is generated
|
|
75
|
+
per invocation when omitted and printed to stderr before dispatch so interrupted
|
|
76
|
+
commands can reuse it; JSON stdout is unchanged. There is no automatic mutation retry. On uncertainty,
|
|
77
|
+
repeat the identical request and key printed in the error within seven days.
|
|
78
|
+
A new key is a new operation. After seven days inspect state before acting.
|
|
79
|
+
Create/rotate replay can have `apiSecret: null`; the CLI directs explicit reveal
|
|
80
|
+
without running it. HTTP 202 and `enabled` do not prove global propagation.
|
|
81
|
+
|
|
82
|
+
## Agent setup and updates
|
|
83
|
+
|
|
84
|
+
```console
|
|
85
|
+
requestshield agent setup [--codex | --claude] [--force]
|
|
86
|
+
requestshield update check
|
|
177
87
|
```
|
|
178
88
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
89
|
+
Agent setup copies the skill to `~/.agents/skills/requestshield` for Codex or
|
|
90
|
+
`~/.claude/skills/requestshield` for Claude. With neither flag, it detects the
|
|
91
|
+
agent or asks if both are available. `--force` replaces an existing installation.
|
|
92
|
+
It does not edit repository `AGENTS.md` or customer application code.
|
|
93
|
+
|
|
94
|
+
Production update check queries npm and asks before a global installation.
|
|
95
|
+
Explain that target before accepting an update; it does not update a pinned
|
|
96
|
+
invocation or source checkout. Repository-only QAT/STG runners return local
|
|
97
|
+
source-update guidance without registry access or installation.
|
|
98
|
+
|
|
99
|
+
## Unavailable commands
|
|
100
|
+
|
|
101
|
+
Integration contract, service health, credential-status metadata, challenge
|
|
102
|
+
volume and billing are not implemented CLI capabilities. `contract`,
|
|
103
|
+
`challenge volume` and `get billing` fail with `COMMAND_UNAVAILABLE` before
|
|
104
|
+
configuration, authentication or network access. `server` and
|
|
105
|
+
`credentials status` are unsupported. Use the published SDK documentation for
|
|
106
|
+
the chosen release and safe browser/backend observations for integration checks.
|
|
107
|
+
Do not infer traffic or enforcement from `apps get` status.
|
|
@@ -71,12 +71,10 @@ Common variable names are `INTELLIFEND_REQUESTSHIELD_APP_KEY`,
|
|
|
71
71
|
Confirm that the backend actually reads or maps that variable before treating it as a
|
|
72
72
|
valid RequestShield credential.
|
|
73
73
|
|
|
74
|
-
If the App Key is known,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
requestshield credentials status <app-key>
|
|
79
|
-
```
|
|
74
|
+
If the App Key is known, inspect its aggregate application configuration with
|
|
75
|
+
`requestshield apps get <app-key>`. That status does not prove the exact credential
|
|
76
|
+
state or that the deployed backend has received its secret. The CLI has no separate
|
|
77
|
+
credential-status command; check runtime injection by presence only.
|
|
80
78
|
|
|
81
79
|
A credential that is not present in the current shell is not necessarily missing from
|
|
82
80
|
the deployed backend. It may be injected at runtime by a secret manager, CI/CD system,
|
|
@@ -182,47 +180,22 @@ last one to run wins rather than the two merging.
|
|
|
182
180
|
|
|
183
181
|
## Contract check
|
|
184
182
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
requestshield contract
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
It is authoritative for `browser.script_url`, `browser.token_header`,
|
|
194
|
-
`browser.available_modes`, `backend.supported_languages`, and `backend.min_jdk`. Use
|
|
195
|
-
those values verbatim; a stale hardcoded script URL produces a page that loads nothing
|
|
196
|
-
and fails silently.
|
|
183
|
+
After detecting the current integration, consult the customer Browser SDK and Java
|
|
184
|
+
SDK documentation for the selected release. Confirm the script URL, token header,
|
|
185
|
+
supported browser modes, backend languages and minimum Java version before editing.
|
|
186
|
+
The CLI integration-contract command is unavailable; do not require it as a preflight
|
|
187
|
+
or fabricate its output.
|
|
197
188
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
### Backend consequences — these feed the Gate
|
|
204
|
-
|
|
205
|
-
- `backend.supported_languages` missing the customer's backend language → **stop.** No
|
|
206
|
-
backend path exists, and a browser-only install protects nothing.
|
|
207
|
-
- `backend.min_jdk` above the project's Java target → **stop.** The JDK upgrade is the
|
|
208
|
-
prerequisite; do not fall back to an older SDK version.
|
|
209
|
-
|
|
210
|
-
### Browser-mode consequences — these decide the mode
|
|
211
|
-
|
|
212
|
-
Read `browser.available_modes` together with what detection found in the codebase:
|
|
213
|
-
|
|
214
|
-
| Released modes | Codebase today | Do this |
|
|
215
|
-
| --- | --- | --- |
|
|
216
|
-
| **One mode** | already uses that mode | Keep it. Nothing to change on the browser side. |
|
|
217
|
-
| **One mode** | uses the *other* mode | **This is a finding, not a preference.** The mode in the codebase is not released, so it cannot be relied on. Report it and migrate the client to the released mode. |
|
|
218
|
-
| **One mode** | not integrated | No choice to make. Install that mode, and say which one and why. |
|
|
219
|
-
| **Both modes** | already uses one of them | **Keep the mode already in use.** Change it only for a concrete reason — the transport is one Seamless cannot cover, or the user asks. A mode switch rewrites working call sites and risks leaving an endpoint half-migrated. |
|
|
220
|
-
| **Both modes** | not integrated | A genuine choice. Go to **Choosing the mode** below. |
|
|
221
|
-
| **Neither** | any | **Stop.** No browser mode is released; report the contract output. |
|
|
189
|
+
The documented backend paths here require Java 17 or newer. The Spring Boot starter
|
|
190
|
+
also requires Spring Boot 3 with Spring MVC; Java core is a separate supported path.
|
|
191
|
+
Do not promise support for another backend language without its release documentation.
|
|
192
|
+
A browser-only installation does not enforce protection.
|
|
222
193
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
194
|
+
Select a browser mode supported by the selected release and the request transport.
|
|
195
|
+
Keep an existing supported mode unless the transport requires a change or the user
|
|
196
|
+
requests one. If release documentation is missing, resolve that evidence before
|
|
197
|
+
making the dependent integration change. A page may use different modes for different
|
|
198
|
+
operations, but each operation uses exactly one mode.
|
|
226
199
|
|
|
227
200
|
## Gate
|
|
228
201
|
|
|
@@ -347,7 +320,7 @@ the page issues the protected request.
|
|
|
347
320
|
Always report the evidence with file and line references:
|
|
348
321
|
|
|
349
322
|
```text
|
|
350
|
-
Backend:
|
|
323
|
+
Backend: customer-backend/build.gradle.kts
|
|
351
324
|
Java 21 - java.toolchain.languageVersion (line 14)
|
|
352
325
|
Spring Boot 3.2.1 - org.springframework.boot plugin (line 3)
|
|
353
326
|
Spring MVC - spring-boot-starter-web (line 20)
|
|
@@ -4,23 +4,22 @@ Work outward from the request, not from the code. Most reports of "RequestShield
|
|
|
4
4
|
broken" are one of four things: the browser never attached a token, CORS stripped the
|
|
5
5
|
header, the backend never verified it, or one token was verified twice.
|
|
6
6
|
|
|
7
|
-
## First
|
|
7
|
+
## First checks
|
|
8
8
|
|
|
9
|
-
```
|
|
10
|
-
requestshield
|
|
11
|
-
requestshield apps get <app-key>
|
|
12
|
-
requestshield credentials status <app-key> # provisioned and active?
|
|
9
|
+
```console
|
|
10
|
+
requestshield auth status --json
|
|
11
|
+
requestshield apps get <app-key>
|
|
13
12
|
```
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
browser
|
|
14
|
+
Session status is local only. Application status is configuration state, not
|
|
15
|
+
traffic: `pending`, `enabled`, `disabled`, `revoked` or `attention_required`.
|
|
16
|
+
It cannot prove that the browser sent a request or that a deployed backend has the
|
|
17
|
+
current secret. Inspect browser requests and safe backend decision metrics separately.
|
|
18
|
+
The CLI has no service-health or credential-status command.
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
can be rotated, or missed by the deploy environment, after it passed. This is the check
|
|
23
|
-
that answers `consume_unauthorized`.
|
|
20
|
+
Confirm runtime secret injection by presence only. A secret absent from the current
|
|
21
|
+
shell may still be supplied by the deployed environment; a rotated secret may not
|
|
22
|
+
have reached that backend yet. Never read or print the value to diagnose this.
|
|
24
23
|
|
|
25
24
|
## Reason codes
|
|
26
25
|
|
|
@@ -40,10 +39,10 @@ name.
|
|
|
40
39
|
| `token_tampered` | Token failed integrity checks | Something modified the value in transit — a proxy rewriting headers, or application code trimming or re-encoding it. Pass the value through unchanged. |
|
|
41
40
|
| `token_expired` | Token too old | The page held a token instead of obtaining a fresh one per request, or a very slow round trip. |
|
|
42
41
|
| `token_replayed` | Already consumed | The same token verified twice: a retry reusing the first token, or two verification paths on one request (`@RequestShieldProtected` plus a manual `verify()`, or a filter plus a controller). |
|
|
43
|
-
| `consume_unauthorized` | Backend credentials rejected | API Secret wrong, rotated, or not injected —
|
|
42
|
+
| `consume_unauthorized` | Backend credentials rejected | API Secret wrong, rotated, or not injected — confirm runtime secret injection and recent rotations without reading the value. |
|
|
44
43
|
| `invalid_request` | Malformed verification request | Usually a mis-set `challenge-server-url`. |
|
|
45
44
|
| `not_found` | Token unknown to the platform | Cross-environment mismatch — a staging page's token verified against production, or the reverse. |
|
|
46
|
-
| `service_unavailable` | Platform unreachable | Check
|
|
45
|
+
| `service_unavailable` | Platform unreachable | Check backend connectivity and safe health metrics. See degraded behaviour below. |
|
|
47
46
|
|
|
48
47
|
## "It blocks everything"
|
|
49
48
|
|
|
@@ -61,7 +60,7 @@ cheap and rules out a whole class:
|
|
|
61
60
|
strips it before it ever leaves.
|
|
62
61
|
4. **Header present but empty** → the SDK ran and could not obtain a token. Check the CSP
|
|
63
62
|
includes `worker-src 'self' blob:` and that `connect-src` allows the challenge host,
|
|
64
|
-
then check
|
|
63
|
+
then check connectivity and safe backend health observations. (In Manual mode an empty token means the header
|
|
65
64
|
should be omitted, not sent empty — see `browser-manual.md`.)
|
|
66
65
|
5. **Header present and populated** → backend half. Compare the App Key on both sides
|
|
67
66
|
character for character, then confirm the secret is actually injected at runtime.
|
|
@@ -89,20 +88,16 @@ platform outage cannot take down a customer's checkout flow.
|
|
|
89
88
|
|
|
90
89
|
Communicate the consequence clearly: during a degraded window, traffic passes without
|
|
91
90
|
real verification. Log the degraded rate as its own metric so it is visible, and check
|
|
92
|
-
|
|
91
|
+
backend connectivity and service health through established monitoring when it rises. Never "fix" a degraded result by overriding
|
|
93
92
|
`isAllowed()` — that converts a platform incident into a customer-facing outage.
|
|
94
93
|
|
|
95
|
-
## Confirming traffic
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
requestshield challenge volume <app-key> --from 2026-08-01T00:00:00Z \
|
|
99
|
-
--to 2026-08-27T23:59:59Z --granularity day
|
|
100
|
-
```
|
|
94
|
+
## Confirming traffic and enforcement
|
|
101
95
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
96
|
+
Use browser network observations and existing safe backend metrics in an authorized
|
|
97
|
+
environment. Do not record raw tokens or secrets. CLI challenge-volume analytics are
|
|
98
|
+
unavailable; application status is not a traffic measurement. Report static correctness,
|
|
99
|
+
observed requests and backend enforcement separately. Use the controlled negative
|
|
100
|
+
test in `SKILL.md` to demonstrate enforcement.
|
|
106
101
|
|
|
107
102
|
## Secret exposure
|
|
108
103
|
|
|
@@ -110,9 +105,10 @@ If the API Secret appears in a repo, a log, a build artifact, or a chat transcri
|
|
|
110
105
|
rotate it — deleting the line does not un-expose it:
|
|
111
106
|
|
|
112
107
|
```bash
|
|
113
|
-
requestshield
|
|
108
|
+
requestshield keys rotate <app-key>
|
|
114
109
|
```
|
|
115
110
|
|
|
116
111
|
The App Key is unchanged, so no browser edit is needed. Deploy the new secret to backend
|
|
117
|
-
secret storage
|
|
118
|
-
secret is displayed
|
|
112
|
+
secret storage. Rotation replaces the previous secret, but publication is asynchronous.
|
|
113
|
+
Warn the user that the new secret is displayed and must stay out of transcripts. A lost
|
|
114
|
+
response can be recovered with explicit reveal; an exposed secret requires rotation.
|