requestshield 0.1.4 → 0.1.5
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 +211 -13
- package/package.json +16 -10
- package/skills/requestshield/SKILL.md +307 -307
- package/skills/requestshield/assets/AGENTS.codex.md +62 -62
- package/skills/requestshield/references/backend-java-core.md +128 -128
- package/skills/requestshield/references/backend-spring-boot.md +145 -145
- package/skills/requestshield/references/browser-manual.md +210 -210
- package/skills/requestshield/references/browser-seamless.md +164 -164
- package/skills/requestshield/references/cli.md +183 -182
- package/skills/requestshield/references/integration-planning.md +389 -389
- package/skills/requestshield/references/troubleshooting.md +118 -118
- package/src/agent-detector.mjs +102 -74
- package/src/api-client.mjs +100 -5
- package/src/args.mjs +182 -79
- package/src/cli.mjs +255 -51
- package/src/commands/agent-setup.mjs +185 -185
- package/src/commands/apps-get.mjs +64 -0
- package/src/commands/apps-list.mjs +90 -0
- package/src/commands/billing-get.mjs +110 -0
- package/src/commands/challenge-volume.mjs +81 -0
- package/src/commands/contract.mjs +106 -0
- package/src/config.mjs +8 -0
- package/src/main.mjs +24 -24
|
@@ -1,389 +1,389 @@
|
|
|
1
|
-
# Integration planning
|
|
2
|
-
|
|
3
|
-
Use this reference before writing or removing RequestShield integration code. It owns the
|
|
4
|
-
planning steps that are too detailed for `SKILL.md`.
|
|
5
|
-
|
|
6
|
-
## Workflow by operation
|
|
7
|
-
|
|
8
|
-
- **Install** -> `integration-planning.md` full flow: **Credentials check** ->
|
|
9
|
-
**Detect existing integration** -> **Contract check** -> **Gate** -> **Then act on
|
|
10
|
-
what you found** -> **Choosing the mode** -> **Installing** -> **Verifying** ->
|
|
11
|
-
**Negative test**.
|
|
12
|
-
- **Verify / Troubleshoot** -> `integration-planning.md` (Detect existing integration
|
|
13
|
-
only) -> **Verifying**. If a reason code, degraded result, browser mode, backend path,
|
|
14
|
-
or unknown state is involved, read only the matching reference files.
|
|
15
|
-
- **Uninstall** -> `integration-planning.md` (Detect existing integration only) ->
|
|
16
|
-
**Uninstalling**.
|
|
17
|
-
|
|
18
|
-
Do not couple browser mode to backend path. They are independent axes:
|
|
19
|
-
|
|
20
|
-
- Browser mode: Seamless (`browser-seamless.md`) or Manual (`browser-manual.md`).
|
|
21
|
-
- Backend path: Spring Boot 3 starter (`backend-spring-boot.md`) or Java core SDK
|
|
22
|
-
(`backend-java-core.md`).
|
|
23
|
-
|
|
24
|
-
Either browser mode may pair with either supported backend path. The backend stack
|
|
25
|
-
selects the backend path. The way the browser issues the protected request selects the
|
|
26
|
-
browser mode.
|
|
27
|
-
|
|
28
|
-
## Credentials check
|
|
29
|
-
|
|
30
|
-
The **pre-edit** check: confirm a credential source exists before touching backend
|
|
31
|
-
integration code. This step belongs to the Install full flow.
|
|
32
|
-
|
|
33
|
-
- **Install** — always, before editing backend code.
|
|
34
|
-
- **Verify / Troubleshoot** — do not run this as part of the operation route. Start with
|
|
35
|
-
**Detect existing integration only**, then use `troubleshooting.md` if the evidence
|
|
36
|
-
points to a credential failure.
|
|
37
|
-
- **Uninstall** — do not run this step; detect the existing integration only.
|
|
38
|
-
|
|
39
|
-
Diagnosing a credential *failure* is a different question, and `troubleshooting.md`
|
|
40
|
-
owns it — go there for `consume_unauthorized`, `unknown_customer`, or a backend
|
|
41
|
-
rejecting every token, whether or not this check has already passed.
|
|
42
|
-
|
|
43
|
-
RequestShield requires:
|
|
44
|
-
|
|
45
|
-
- an App Key
|
|
46
|
-
- an API Secret
|
|
47
|
-
|
|
48
|
-
Check for credential sources without printing, reading, or echoing their values. Confirm
|
|
49
|
-
presence only; never print, cat, or echo either value:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
# Presence check only. Never print secret values.
|
|
53
|
-
|
|
54
|
-
if env | grep -Eq '^(INTELLIFEND_)?REQUESTSHIELD_(APP_KEY|KEY)='; then
|
|
55
|
-
echo "RequestShield App Key: present"
|
|
56
|
-
else
|
|
57
|
-
echo "RequestShield App Key: not found in current environment"
|
|
58
|
-
fi
|
|
59
|
-
|
|
60
|
-
if env | grep -Eq '^(INTELLIFEND_)?REQUESTSHIELD_(API_SECRET|SECRET)='; then
|
|
61
|
-
echo "RequestShield API Secret: present"
|
|
62
|
-
else
|
|
63
|
-
echo "RequestShield API Secret: not found in current environment"
|
|
64
|
-
fi
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Common variable names are `INTELLIFEND_REQUESTSHIELD_APP_KEY`,
|
|
68
|
-
`REQUESTSHIELD_APP_KEY`, `REQUESTSHIELD_KEY`,
|
|
69
|
-
`INTELLIFEND_REQUESTSHIELD_API_SECRET`, `REQUESTSHIELD_API_SECRET`, and
|
|
70
|
-
`REQUESTSHIELD_SECRET`. A matching non-canonical name is only a credential candidate.
|
|
71
|
-
Confirm that the backend actually reads or maps that variable before treating it as a
|
|
72
|
-
valid RequestShield credential.
|
|
73
|
-
|
|
74
|
-
If the App Key is known, also confirm server-side credential state without exposing the
|
|
75
|
-
secret:
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
requestshield credentials status <app-key>
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
A credential that is not present in the current shell is not necessarily missing from
|
|
82
|
-
the deployed backend. It may be injected at runtime by a secret manager, CI/CD system,
|
|
83
|
-
container runtime, Kubernetes Secret, or deployment environment.
|
|
84
|
-
|
|
85
|
-
Report only what was confirmed:
|
|
86
|
-
|
|
87
|
-
| Finding | Action |
|
|
88
|
-
| --- | --- |
|
|
89
|
-
| Both credential sources are confirmed | Continue. Never read their values. |
|
|
90
|
-
| A non-canonical variable is found and its backend mapping is confirmed | Report the mapping and continue. |
|
|
91
|
-
| Credentials are provisioned, but the runtime source is unknown | Ask how the deployed backend receives them before editing backend integration code. |
|
|
92
|
-
| No credential source can be confirmed | Report the uncertainty and ask before proceeding. |
|
|
93
|
-
| No credential pair has been provisioned | Ask the user to provision credentials before continuing with backend setup. |
|
|
94
|
-
|
|
95
|
-
If no pair has been provisioned yet, the user creates it. You may run the read-only
|
|
96
|
-
`requestshield apps list` to see whether an application already exists. Everything that
|
|
97
|
-
mints or changes a secret stays with the user; see **Key and secret management** in
|
|
98
|
-
`SKILL.md`.
|
|
99
|
-
|
|
100
|
-
## Detect existing integration
|
|
101
|
-
|
|
102
|
-
Search for existing RequestShield code before install, verify/troubleshoot, or uninstall.
|
|
103
|
-
Use `rg` when available. Use `rg -l` for filename-only discovery.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
Browser markers:
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
rg -l "data-app-key|data-protect|IntelliFend|X-IntelliFend-Token" \
|
|
110
|
-
-g "*.html" -g "*.htm" -g "*.js" -g "*.jsx" -g "*.ts" -g "*.tsx" \
|
|
111
|
-
-g "*.vue" -g "*.svelte" -g "*.astro" \
|
|
112
|
-
-g "*.erb" -g "*.haml" -g "*.php" -g "*.jinja*" -g "*.j2" -g "*.twig" \
|
|
113
|
-
-g "*.hbs" -g "*.ejs" -g "*.pug" -g "*.blade.php" \
|
|
114
|
-
-g "!node_modules/**" -g "!**/skills/**" -g "!**/.requestshield/**" .
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
The tag often lives in a server-rendered layout rather than a static `.html` — a Django,
|
|
118
|
-
Rails, Laravel, or Thymeleaf base template — so a scan limited to `.html`/`.js` reports
|
|
119
|
-
"not integrated" on a codebase that already has one, and the install then adds a second
|
|
120
|
-
tag. If the app's templates use an extension not listed above, add it before concluding.
|
|
121
|
-
|
|
122
|
-
Backend markers:
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
|
-
rg -l "RequestShieldClient|RequestShieldProtected|intellifend|requestshield" \
|
|
126
|
-
-g "*.java" -g "*.kt" -g "*.xml" -g "*.yml" -g "*.yaml" \
|
|
127
|
-
-g "*.gradle" -g "*.gradle.kts" \
|
|
128
|
-
-g "!**/skills/**" -g "!**/.requestshield/**" .
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
`rg -l` returns candidate filenames only. Do not follow it with `cat`, an unrestricted
|
|
132
|
-
`sed`, plain `rg -n` without `-o`, or another command that exposes complete matching
|
|
133
|
-
lines or the entire file.
|
|
134
|
-
|
|
135
|
-
Locate known markers without returning the rest of their lines:
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
rg -n -o \
|
|
139
|
-
"data-app-key|data-protect|IntelliFend|getToken|X-IntelliFend-Token" \
|
|
140
|
-
<browser-candidate-file>
|
|
141
|
-
|
|
142
|
-
rg -n -o \
|
|
143
|
-
"RequestShieldClient|RequestShieldProtected|verify|isAllowed|intellifend|requestshield" \
|
|
144
|
-
<backend-candidate-file>
|
|
145
|
-
|
|
146
|
-
rg -n -o \
|
|
147
|
-
"(INTELLIFEND_)?REQUESTSHIELD_(APP_KEY|KEY|API_SECRET|SECRET)" \
|
|
148
|
-
<candidate-configuration-file>
|
|
149
|
-
```
|
|
150
|
-
-o prints only the matched marker or environment-variable name, not the surrounding
|
|
151
|
-
value. Environment-variable names are safe to report; their values are not.
|
|
152
|
-
|
|
153
|
-
When configuration context is required, inspect it only through a secret-aware parser
|
|
154
|
-
or redacted view that masks sensitive values before stdout reaches the agent. Its output
|
|
155
|
-
may contain the filename, line number, configuration key, environment-variable name,
|
|
156
|
-
App Key when needed to identify the integration, and whether the source is an
|
|
157
|
-
environment reference, secret-manager reference, or literal.
|
|
158
|
-
|
|
159
|
-
Replace every API Secret, RequestShield token, session value, CSRF value,
|
|
160
|
-
authorization credential, and other credential literal with <redacted>.
|
|
161
|
-
|
|
162
|
-
If no secret-aware parser or redacted view is available, do not read the candidate
|
|
163
|
-
configuration file verbatim. Ask the user for a sanitized excerpt instead. Switching
|
|
164
|
-
to rg -l and then reading the entire candidate file is not safe.
|
|
165
|
-
|
|
166
|
-
The exclusions matter when this skill is installed inside the repo being scanned —
|
|
167
|
-
browser and backend reference files contain marker strings and would otherwise read as
|
|
168
|
-
an existing integration.
|
|
169
|
-
|
|
170
|
-
Report one of:
|
|
171
|
-
|
|
172
|
-
- **Not integrated**: no browser or backend markers.
|
|
173
|
-
- **Browser only**: tokens may be obtained or attached, but no backend enforcement was
|
|
174
|
-
found. This looks protected and is not.
|
|
175
|
-
- **Backend only**: enforcement exists, but no page sends a token. In BLOCK mode this can
|
|
176
|
-
reject legitimate users.
|
|
177
|
-
- **Fully integrated**: browser mode and backend path are both present. Name both.
|
|
178
|
-
|
|
179
|
-
If a script tag already exists, update it instead of adding a second one. The SDK
|
|
180
|
-
initializes from `document.currentScript`; two tags mean two configurations, and the
|
|
181
|
-
last one to run wins rather than the two merging.
|
|
182
|
-
|
|
183
|
-
## Contract check
|
|
184
|
-
|
|
185
|
-
Run this **after** detection and **before** the Gate: detection says what the codebase
|
|
186
|
-
already does, the contract says what the platform currently allows, and the browser-mode
|
|
187
|
-
decision needs both.
|
|
188
|
-
|
|
189
|
-
```bash
|
|
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.
|
|
197
|
-
|
|
198
|
-
Treat every array as an **allow-list**. There is no "unavailable" flag, so something is
|
|
199
|
-
unavailable when it is absent — and an absent, empty, or unparseable array is
|
|
200
|
-
unavailable, not permission. If the contract is missing or returns `ok: false`, stop and
|
|
201
|
-
report what the CLI returned.
|
|
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. |
|
|
222
|
-
|
|
223
|
-
Per-endpoint, not per-repo: a page may legitimately run Seamless on one endpoint and
|
|
224
|
-
Manual on another. Apply the table to the operation being worked on, not to the codebase
|
|
225
|
-
as a whole.
|
|
226
|
-
|
|
227
|
-
## Gate
|
|
228
|
-
|
|
229
|
-
The backend path is decided by the backend stack, not by browser preference. Establish
|
|
230
|
-
this before proposing edits. Discovering a backend blocker after the browser half is
|
|
231
|
-
written leaves tokens flowing with nothing enforcing them.
|
|
232
|
-
|
|
233
|
-
An integration is one backend path plus one browser mode, and they are independent
|
|
234
|
-
choices. A non-Spring-MVC backend does not rule out Seamless mode; it only rules out the
|
|
235
|
-
Spring Boot 3 starter backend path.
|
|
236
|
-
|
|
237
|
-
Backend path:
|
|
238
|
-
|
|
239
|
-
| Backend path | Requirement | Reference |
|
|
240
|
-
| --- | --- | --- |
|
|
241
|
-
| **Spring Boot 3 starter** | Spring Boot 3 with Spring MVC, and Java 17+ | `backend-spring-boot.md` |
|
|
242
|
-
| **Java core SDK** | Java 17+ | `backend-java-core.md` |
|
|
243
|
-
|
|
244
|
-
Browser mode:
|
|
245
|
-
|
|
246
|
-
| Browser mode | Use when | Reference |
|
|
247
|
-
| --- | --- | --- |
|
|
248
|
-
| **Seamless** | The page reaches the endpoint with `fetch` or async `XMLHttpRequest` | `browser-seamless.md` |
|
|
249
|
-
| **Manual** | The call needs explicit token timing, or a non-header carrier | `browser-manual.md` |
|
|
250
|
-
|
|
251
|
-
Either browser mode pairs with either backend path. The token travels in
|
|
252
|
-
`X-IntelliFend-Token` regardless. Java below 17 blocks both backend paths, and no amount
|
|
253
|
-
of browser-side work substitutes for backend enforcement.
|
|
254
|
-
|
|
255
|
-
### Run the check
|
|
256
|
-
|
|
257
|
-
Find the build file for the module that serves the protected endpoint, not the first one
|
|
258
|
-
in the tree. In a monorepo, locate the route first:
|
|
259
|
-
|
|
260
|
-
```bash
|
|
261
|
-
find . -maxdepth 4 \( -name pom.xml -o -name "build.gradle*" \) \
|
|
262
|
-
-not -path "*/node_modules/*" -not -path "*/build/*" -not -path "*/target/*"
|
|
263
|
-
rg -n "/api/register" -g "*.java" -g "*.kt" .
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
One build file, inspect it. Several, and the route cannot be tied to one of them — or
|
|
267
|
-
several backends could plausibly serve it — **stop and ask which service owns the
|
|
268
|
-
endpoint.** Two backends in a monorepo can differ in both Java version and framework, so
|
|
269
|
-
a guess here invalidates the whole integration rather than needing a tweak.
|
|
270
|
-
|
|
271
|
-
Use repo-wide build-file scans only for discovery. Do not combine a route found in one
|
|
272
|
-
module with Java or Spring evidence from another module.
|
|
273
|
-
|
|
274
|
-
#### Java target version
|
|
275
|
-
|
|
276
|
-
Read the *project's target*, never the machine's JDK.
|
|
277
|
-
|
|
278
|
-
```bash
|
|
279
|
-
rg -n "maven\.compiler\.(release|source|target)|<release>|<java\.version>" <owning-pom.xml>
|
|
280
|
-
rg -n "languageVersion|sourceCompatibility|jvmToolchain|JavaVersion" <owning-build.gradle*>
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
- **Maven** — `maven.compiler.release`, or the compiler plugin's `<release>`, is
|
|
284
|
-
authoritative. Spring Boot's parent POM exposes `<java.version>`, which is the
|
|
285
|
-
idiomatic place in a Boot app. **Check the parent POM too** when the module inherits;
|
|
286
|
-
the value is often not in the module's own file.
|
|
287
|
-
- **Gradle** — `java.toolchain.languageVersion = JavaLanguageVersion.of(21)` and
|
|
288
|
-
`kotlin { jvmToolchain(21) }` are both authoritative, and both easy to miss because
|
|
289
|
-
they sit inside a block rather than on a property line.
|
|
290
|
-
- **When the build file says nothing** — `.java-version`, `.sdkmanrc`, `.tool-versions`,
|
|
291
|
-
a `setup-java` step's `java-version` in `.github/workflows/`, or a JDK base image in a
|
|
292
|
-
`Dockerfile`. These are **hints, not answers**: they describe an environment, which can
|
|
293
|
-
differ from what the build compiles against. A build file that yields only hints is the
|
|
294
|
-
ambiguous row below — ask.
|
|
295
|
-
- `java -version` reports the **local** JDK. A repo targeting 11 builds fine on a machine
|
|
296
|
-
with 21 installed, so it is a last-resort hint and never evidence.
|
|
297
|
-
|
|
298
|
-
Java below 17 blocks **both** backend paths. Report the version and its source and name
|
|
299
|
-
the upgrade as the prerequisite; do not fall back to an older SDK version or write a
|
|
300
|
-
partial browser-only integration.
|
|
301
|
-
|
|
302
|
-
#### Spring Boot 3, and separately Spring MVC
|
|
303
|
-
|
|
304
|
-
Two conditions. Both must hold for the Spring Boot starter.
|
|
305
|
-
|
|
306
|
-
```bash
|
|
307
|
-
rg -n "spring-boot-starter-parent|spring-boot-dependencies|org\.springframework\.boot" \
|
|
308
|
-
<owning-pom.xml-or-build.gradle*> | rg "3\.[0-9]+"
|
|
309
|
-
rg -n "spring-boot-starter-web[\"' :<]|spring-boot-starter-webflux|spring-webmvc" \
|
|
310
|
-
<owning-pom.xml-or-build.gradle*>
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
Read the parent version, the `spring-boot-dependencies` BOM version, or the Gradle plugin
|
|
314
|
-
version. **Spring Boot 2.x does not qualify** — the starter is a Boot 3 artifact, so a
|
|
315
|
-
2.x app needs the core SDK path even though it is Spring.
|
|
316
|
-
|
|
317
|
-
Then MVC versus WebFlux — the trap worth checking every time:
|
|
318
|
-
|
|
319
|
-
- `spring-boot-starter-web` → Spring MVC. The starter is available when the app is also
|
|
320
|
-
Spring Boot 3 on Java 17+.
|
|
321
|
-
- `spring-boot-starter-webflux` with no `-web` → **not** Spring MVC. The starter protects
|
|
322
|
-
Spring MVC handler methods, so `@RequestShieldProtected` does not apply. Such an app is
|
|
323
|
-
Spring Boot 3 on Java 17+ and still needs the Java core SDK — say so explicitly,
|
|
324
|
-
because "Spring Boot 3, Java 21" reads like a starter green light and quietly is not.
|
|
325
|
-
Browser mode is unaffected; Seamless remains available when the request transport
|
|
326
|
-
matches.
|
|
327
|
-
- **Both present** → determine which stack serves the protected route. A
|
|
328
|
-
`@RestController` returning `Mono`/`Flux`, or a `RouterFunction`, indicates the
|
|
329
|
-
reactive path. Ask if it stays unclear.
|
|
330
|
-
|
|
331
|
-
Also not Spring MVC, and therefore the Java core SDK backend path: **Quarkus, Micronaut,
|
|
332
|
-
Dropwizard, Helidon, Ktor, Vert.x, Jakarta EE / JAX-RS on its own, and a plain servlet
|
|
333
|
-
application.**
|
|
334
|
-
|
|
335
|
-
## Then act on what you found
|
|
336
|
-
|
|
337
|
-
This decision chooses the backend path only. Pick the browser mode separately from how
|
|
338
|
-
the page issues the protected request.
|
|
339
|
-
|
|
340
|
-
| Detected | Do this |
|
|
341
|
-
| --- | --- |
|
|
342
|
-
| Java < 17, or no Java backend | Stop before editing. Report the finding and its source; no backend path is available, so nothing can enforce. Name the upgrade as the prerequisite. |
|
|
343
|
-
| Java 17+, no Spring Boot 3 MVC | Use Java core SDK. It is the only backend option; state it rather than asking a fake choice. |
|
|
344
|
-
| Java 17+ and Spring Boot 3 MVC | Both backend paths are viable. Recommend the starter and confirm once. |
|
|
345
|
-
| Ambiguous module, missing build file, version only in environment hints, or unclear MVC/WebFlux ownership | Ask, showing what you found. |
|
|
346
|
-
|
|
347
|
-
Always report the evidence with file and line references:
|
|
348
|
-
|
|
349
|
-
```text
|
|
350
|
-
Backend: theair-customer-backend/build.gradle.kts
|
|
351
|
-
Java 21 - java.toolchain.languageVersion (line 14)
|
|
352
|
-
Spring Boot 3.2.1 - org.springframework.boot plugin (line 3)
|
|
353
|
-
Spring MVC - spring-boot-starter-web (line 20)
|
|
354
|
-
Backend path: Spring Boot 3 starter. Browser mode still depends on released modes and request transport.
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
Detection is inference from build files. If any line would read "unknown", ask rather
|
|
358
|
-
than assume.
|
|
359
|
-
|
|
360
|
-
## Choosing the mode
|
|
361
|
-
|
|
362
|
-
Reach this section only when **Contract check** left a genuine choice: both modes
|
|
363
|
-
released, and this operation not already integrated. If it landed on any other row of
|
|
364
|
-
that table, the mode is already decided — do not re-open it here.
|
|
365
|
-
|
|
366
|
-
This is the browser half. Backend path does not constrain it. Both browser modes deliver
|
|
367
|
-
the token in `X-IntelliFend-Token`, which either backend path reads.
|
|
368
|
-
|
|
369
|
-
| | **Seamless** | **Manual** |
|
|
370
|
-
| --- | --- | --- |
|
|
371
|
-
| Browser | `data-protect` lists exact endpoints; the SDK attaches tokens to matching `fetch` and async XHR requests. | `await IntelliFend.getToken()` at each protected call site, attached in application code. |
|
|
372
|
-
| Requires | The request travels by `fetch` or async XHR from page scope. | Nothing beyond the SDK and a supported carrier. |
|
|
373
|
-
| Code touched | One line of HTML. | Every protected call site, plus every retry path. |
|
|
374
|
-
| Backend work | Identical either way: whichever backend path the Gate selected. | Identical either way: whichever backend path the Gate selected. |
|
|
375
|
-
|
|
376
|
-
Released-mode availability was already settled at **Contract check**. One question is
|
|
377
|
-
left: does the protected request travel by `fetch` or asynchronous `XMLHttpRequest` from
|
|
378
|
-
page scope? Native form POST, `sendBeacon`, WebSocket/EventSource, synchronous XHR,
|
|
379
|
-
`no-cors`, and service-worker-owned requests are not intercepted — read
|
|
380
|
-
`browser-seamless.md` for the full coverage list.
|
|
381
|
-
|
|
382
|
-
Recommend Seamless when that check passes. It touches one line instead of every call
|
|
383
|
-
site, so there is no missed call site or retry path. If it fails, use Manual and give
|
|
384
|
-
the reason; that is a finding, not a preference.
|
|
385
|
-
|
|
386
|
-
A given protected operation uses one mode, not both. Different endpoints on the same
|
|
387
|
-
page may use different modes when necessary. Never use two backend verification paths on
|
|
388
|
-
one request; `@RequestShieldProtected` and manual `RequestShieldClient.verify()` both
|
|
389
|
-
consume the token, so the second returns `token_replayed`.
|
|
1
|
+
# Integration planning
|
|
2
|
+
|
|
3
|
+
Use this reference before writing or removing RequestShield integration code. It owns the
|
|
4
|
+
planning steps that are too detailed for `SKILL.md`.
|
|
5
|
+
|
|
6
|
+
## Workflow by operation
|
|
7
|
+
|
|
8
|
+
- **Install** -> `integration-planning.md` full flow: **Credentials check** ->
|
|
9
|
+
**Detect existing integration** -> **Contract check** -> **Gate** -> **Then act on
|
|
10
|
+
what you found** -> **Choosing the mode** -> **Installing** -> **Verifying** ->
|
|
11
|
+
**Negative test**.
|
|
12
|
+
- **Verify / Troubleshoot** -> `integration-planning.md` (Detect existing integration
|
|
13
|
+
only) -> **Verifying**. If a reason code, degraded result, browser mode, backend path,
|
|
14
|
+
or unknown state is involved, read only the matching reference files.
|
|
15
|
+
- **Uninstall** -> `integration-planning.md` (Detect existing integration only) ->
|
|
16
|
+
**Uninstalling**.
|
|
17
|
+
|
|
18
|
+
Do not couple browser mode to backend path. They are independent axes:
|
|
19
|
+
|
|
20
|
+
- Browser mode: Seamless (`browser-seamless.md`) or Manual (`browser-manual.md`).
|
|
21
|
+
- Backend path: Spring Boot 3 starter (`backend-spring-boot.md`) or Java core SDK
|
|
22
|
+
(`backend-java-core.md`).
|
|
23
|
+
|
|
24
|
+
Either browser mode may pair with either supported backend path. The backend stack
|
|
25
|
+
selects the backend path. The way the browser issues the protected request selects the
|
|
26
|
+
browser mode.
|
|
27
|
+
|
|
28
|
+
## Credentials check
|
|
29
|
+
|
|
30
|
+
The **pre-edit** check: confirm a credential source exists before touching backend
|
|
31
|
+
integration code. This step belongs to the Install full flow.
|
|
32
|
+
|
|
33
|
+
- **Install** — always, before editing backend code.
|
|
34
|
+
- **Verify / Troubleshoot** — do not run this as part of the operation route. Start with
|
|
35
|
+
**Detect existing integration only**, then use `troubleshooting.md` if the evidence
|
|
36
|
+
points to a credential failure.
|
|
37
|
+
- **Uninstall** — do not run this step; detect the existing integration only.
|
|
38
|
+
|
|
39
|
+
Diagnosing a credential *failure* is a different question, and `troubleshooting.md`
|
|
40
|
+
owns it — go there for `consume_unauthorized`, `unknown_customer`, or a backend
|
|
41
|
+
rejecting every token, whether or not this check has already passed.
|
|
42
|
+
|
|
43
|
+
RequestShield requires:
|
|
44
|
+
|
|
45
|
+
- an App Key
|
|
46
|
+
- an API Secret
|
|
47
|
+
|
|
48
|
+
Check for credential sources without printing, reading, or echoing their values. Confirm
|
|
49
|
+
presence only; never print, cat, or echo either value:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Presence check only. Never print secret values.
|
|
53
|
+
|
|
54
|
+
if env | grep -Eq '^(INTELLIFEND_)?REQUESTSHIELD_(APP_KEY|KEY)='; then
|
|
55
|
+
echo "RequestShield App Key: present"
|
|
56
|
+
else
|
|
57
|
+
echo "RequestShield App Key: not found in current environment"
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
if env | grep -Eq '^(INTELLIFEND_)?REQUESTSHIELD_(API_SECRET|SECRET)='; then
|
|
61
|
+
echo "RequestShield API Secret: present"
|
|
62
|
+
else
|
|
63
|
+
echo "RequestShield API Secret: not found in current environment"
|
|
64
|
+
fi
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Common variable names are `INTELLIFEND_REQUESTSHIELD_APP_KEY`,
|
|
68
|
+
`REQUESTSHIELD_APP_KEY`, `REQUESTSHIELD_KEY`,
|
|
69
|
+
`INTELLIFEND_REQUESTSHIELD_API_SECRET`, `REQUESTSHIELD_API_SECRET`, and
|
|
70
|
+
`REQUESTSHIELD_SECRET`. A matching non-canonical name is only a credential candidate.
|
|
71
|
+
Confirm that the backend actually reads or maps that variable before treating it as a
|
|
72
|
+
valid RequestShield credential.
|
|
73
|
+
|
|
74
|
+
If the App Key is known, also confirm server-side credential state without exposing the
|
|
75
|
+
secret:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
requestshield credentials status <app-key>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
A credential that is not present in the current shell is not necessarily missing from
|
|
82
|
+
the deployed backend. It may be injected at runtime by a secret manager, CI/CD system,
|
|
83
|
+
container runtime, Kubernetes Secret, or deployment environment.
|
|
84
|
+
|
|
85
|
+
Report only what was confirmed:
|
|
86
|
+
|
|
87
|
+
| Finding | Action |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| Both credential sources are confirmed | Continue. Never read their values. |
|
|
90
|
+
| A non-canonical variable is found and its backend mapping is confirmed | Report the mapping and continue. |
|
|
91
|
+
| Credentials are provisioned, but the runtime source is unknown | Ask how the deployed backend receives them before editing backend integration code. |
|
|
92
|
+
| No credential source can be confirmed | Report the uncertainty and ask before proceeding. |
|
|
93
|
+
| No credential pair has been provisioned | Ask the user to provision credentials before continuing with backend setup. |
|
|
94
|
+
|
|
95
|
+
If no pair has been provisioned yet, the user creates it. You may run the read-only
|
|
96
|
+
`requestshield apps list` to see whether an application already exists. Everything that
|
|
97
|
+
mints or changes a secret stays with the user; see **Key and secret management** in
|
|
98
|
+
`SKILL.md`.
|
|
99
|
+
|
|
100
|
+
## Detect existing integration
|
|
101
|
+
|
|
102
|
+
Search for existing RequestShield code before install, verify/troubleshoot, or uninstall.
|
|
103
|
+
Use `rg` when available. Use `rg -l` for filename-only discovery.
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
Browser markers:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
rg -l "data-app-key|data-protect|IntelliFend|X-IntelliFend-Token" \
|
|
110
|
+
-g "*.html" -g "*.htm" -g "*.js" -g "*.jsx" -g "*.ts" -g "*.tsx" \
|
|
111
|
+
-g "*.vue" -g "*.svelte" -g "*.astro" \
|
|
112
|
+
-g "*.erb" -g "*.haml" -g "*.php" -g "*.jinja*" -g "*.j2" -g "*.twig" \
|
|
113
|
+
-g "*.hbs" -g "*.ejs" -g "*.pug" -g "*.blade.php" \
|
|
114
|
+
-g "!node_modules/**" -g "!**/skills/**" -g "!**/.requestshield/**" .
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The tag often lives in a server-rendered layout rather than a static `.html` — a Django,
|
|
118
|
+
Rails, Laravel, or Thymeleaf base template — so a scan limited to `.html`/`.js` reports
|
|
119
|
+
"not integrated" on a codebase that already has one, and the install then adds a second
|
|
120
|
+
tag. If the app's templates use an extension not listed above, add it before concluding.
|
|
121
|
+
|
|
122
|
+
Backend markers:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
rg -l "RequestShieldClient|RequestShieldProtected|intellifend|requestshield" \
|
|
126
|
+
-g "*.java" -g "*.kt" -g "*.xml" -g "*.yml" -g "*.yaml" \
|
|
127
|
+
-g "*.gradle" -g "*.gradle.kts" \
|
|
128
|
+
-g "!**/skills/**" -g "!**/.requestshield/**" .
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`rg -l` returns candidate filenames only. Do not follow it with `cat`, an unrestricted
|
|
132
|
+
`sed`, plain `rg -n` without `-o`, or another command that exposes complete matching
|
|
133
|
+
lines or the entire file.
|
|
134
|
+
|
|
135
|
+
Locate known markers without returning the rest of their lines:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
rg -n -o \
|
|
139
|
+
"data-app-key|data-protect|IntelliFend|getToken|X-IntelliFend-Token" \
|
|
140
|
+
<browser-candidate-file>
|
|
141
|
+
|
|
142
|
+
rg -n -o \
|
|
143
|
+
"RequestShieldClient|RequestShieldProtected|verify|isAllowed|intellifend|requestshield" \
|
|
144
|
+
<backend-candidate-file>
|
|
145
|
+
|
|
146
|
+
rg -n -o \
|
|
147
|
+
"(INTELLIFEND_)?REQUESTSHIELD_(APP_KEY|KEY|API_SECRET|SECRET)" \
|
|
148
|
+
<candidate-configuration-file>
|
|
149
|
+
```
|
|
150
|
+
-o prints only the matched marker or environment-variable name, not the surrounding
|
|
151
|
+
value. Environment-variable names are safe to report; their values are not.
|
|
152
|
+
|
|
153
|
+
When configuration context is required, inspect it only through a secret-aware parser
|
|
154
|
+
or redacted view that masks sensitive values before stdout reaches the agent. Its output
|
|
155
|
+
may contain the filename, line number, configuration key, environment-variable name,
|
|
156
|
+
App Key when needed to identify the integration, and whether the source is an
|
|
157
|
+
environment reference, secret-manager reference, or literal.
|
|
158
|
+
|
|
159
|
+
Replace every API Secret, RequestShield token, session value, CSRF value,
|
|
160
|
+
authorization credential, and other credential literal with <redacted>.
|
|
161
|
+
|
|
162
|
+
If no secret-aware parser or redacted view is available, do not read the candidate
|
|
163
|
+
configuration file verbatim. Ask the user for a sanitized excerpt instead. Switching
|
|
164
|
+
to rg -l and then reading the entire candidate file is not safe.
|
|
165
|
+
|
|
166
|
+
The exclusions matter when this skill is installed inside the repo being scanned —
|
|
167
|
+
browser and backend reference files contain marker strings and would otherwise read as
|
|
168
|
+
an existing integration.
|
|
169
|
+
|
|
170
|
+
Report one of:
|
|
171
|
+
|
|
172
|
+
- **Not integrated**: no browser or backend markers.
|
|
173
|
+
- **Browser only**: tokens may be obtained or attached, but no backend enforcement was
|
|
174
|
+
found. This looks protected and is not.
|
|
175
|
+
- **Backend only**: enforcement exists, but no page sends a token. In BLOCK mode this can
|
|
176
|
+
reject legitimate users.
|
|
177
|
+
- **Fully integrated**: browser mode and backend path are both present. Name both.
|
|
178
|
+
|
|
179
|
+
If a script tag already exists, update it instead of adding a second one. The SDK
|
|
180
|
+
initializes from `document.currentScript`; two tags mean two configurations, and the
|
|
181
|
+
last one to run wins rather than the two merging.
|
|
182
|
+
|
|
183
|
+
## Contract check
|
|
184
|
+
|
|
185
|
+
Run this **after** detection and **before** the Gate: detection says what the codebase
|
|
186
|
+
already does, the contract says what the platform currently allows, and the browser-mode
|
|
187
|
+
decision needs both.
|
|
188
|
+
|
|
189
|
+
```bash
|
|
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.
|
|
197
|
+
|
|
198
|
+
Treat every array as an **allow-list**. There is no "unavailable" flag, so something is
|
|
199
|
+
unavailable when it is absent — and an absent, empty, or unparseable array is
|
|
200
|
+
unavailable, not permission. If the contract is missing or returns `ok: false`, stop and
|
|
201
|
+
report what the CLI returned.
|
|
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. |
|
|
222
|
+
|
|
223
|
+
Per-endpoint, not per-repo: a page may legitimately run Seamless on one endpoint and
|
|
224
|
+
Manual on another. Apply the table to the operation being worked on, not to the codebase
|
|
225
|
+
as a whole.
|
|
226
|
+
|
|
227
|
+
## Gate
|
|
228
|
+
|
|
229
|
+
The backend path is decided by the backend stack, not by browser preference. Establish
|
|
230
|
+
this before proposing edits. Discovering a backend blocker after the browser half is
|
|
231
|
+
written leaves tokens flowing with nothing enforcing them.
|
|
232
|
+
|
|
233
|
+
An integration is one backend path plus one browser mode, and they are independent
|
|
234
|
+
choices. A non-Spring-MVC backend does not rule out Seamless mode; it only rules out the
|
|
235
|
+
Spring Boot 3 starter backend path.
|
|
236
|
+
|
|
237
|
+
Backend path:
|
|
238
|
+
|
|
239
|
+
| Backend path | Requirement | Reference |
|
|
240
|
+
| --- | --- | --- |
|
|
241
|
+
| **Spring Boot 3 starter** | Spring Boot 3 with Spring MVC, and Java 17+ | `backend-spring-boot.md` |
|
|
242
|
+
| **Java core SDK** | Java 17+ | `backend-java-core.md` |
|
|
243
|
+
|
|
244
|
+
Browser mode:
|
|
245
|
+
|
|
246
|
+
| Browser mode | Use when | Reference |
|
|
247
|
+
| --- | --- | --- |
|
|
248
|
+
| **Seamless** | The page reaches the endpoint with `fetch` or async `XMLHttpRequest` | `browser-seamless.md` |
|
|
249
|
+
| **Manual** | The call needs explicit token timing, or a non-header carrier | `browser-manual.md` |
|
|
250
|
+
|
|
251
|
+
Either browser mode pairs with either backend path. The token travels in
|
|
252
|
+
`X-IntelliFend-Token` regardless. Java below 17 blocks both backend paths, and no amount
|
|
253
|
+
of browser-side work substitutes for backend enforcement.
|
|
254
|
+
|
|
255
|
+
### Run the check
|
|
256
|
+
|
|
257
|
+
Find the build file for the module that serves the protected endpoint, not the first one
|
|
258
|
+
in the tree. In a monorepo, locate the route first:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
find . -maxdepth 4 \( -name pom.xml -o -name "build.gradle*" \) \
|
|
262
|
+
-not -path "*/node_modules/*" -not -path "*/build/*" -not -path "*/target/*"
|
|
263
|
+
rg -n "/api/register" -g "*.java" -g "*.kt" .
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
One build file, inspect it. Several, and the route cannot be tied to one of them — or
|
|
267
|
+
several backends could plausibly serve it — **stop and ask which service owns the
|
|
268
|
+
endpoint.** Two backends in a monorepo can differ in both Java version and framework, so
|
|
269
|
+
a guess here invalidates the whole integration rather than needing a tweak.
|
|
270
|
+
|
|
271
|
+
Use repo-wide build-file scans only for discovery. Do not combine a route found in one
|
|
272
|
+
module with Java or Spring evidence from another module.
|
|
273
|
+
|
|
274
|
+
#### Java target version
|
|
275
|
+
|
|
276
|
+
Read the *project's target*, never the machine's JDK.
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
rg -n "maven\.compiler\.(release|source|target)|<release>|<java\.version>" <owning-pom.xml>
|
|
280
|
+
rg -n "languageVersion|sourceCompatibility|jvmToolchain|JavaVersion" <owning-build.gradle*>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
- **Maven** — `maven.compiler.release`, or the compiler plugin's `<release>`, is
|
|
284
|
+
authoritative. Spring Boot's parent POM exposes `<java.version>`, which is the
|
|
285
|
+
idiomatic place in a Boot app. **Check the parent POM too** when the module inherits;
|
|
286
|
+
the value is often not in the module's own file.
|
|
287
|
+
- **Gradle** — `java.toolchain.languageVersion = JavaLanguageVersion.of(21)` and
|
|
288
|
+
`kotlin { jvmToolchain(21) }` are both authoritative, and both easy to miss because
|
|
289
|
+
they sit inside a block rather than on a property line.
|
|
290
|
+
- **When the build file says nothing** — `.java-version`, `.sdkmanrc`, `.tool-versions`,
|
|
291
|
+
a `setup-java` step's `java-version` in `.github/workflows/`, or a JDK base image in a
|
|
292
|
+
`Dockerfile`. These are **hints, not answers**: they describe an environment, which can
|
|
293
|
+
differ from what the build compiles against. A build file that yields only hints is the
|
|
294
|
+
ambiguous row below — ask.
|
|
295
|
+
- `java -version` reports the **local** JDK. A repo targeting 11 builds fine on a machine
|
|
296
|
+
with 21 installed, so it is a last-resort hint and never evidence.
|
|
297
|
+
|
|
298
|
+
Java below 17 blocks **both** backend paths. Report the version and its source and name
|
|
299
|
+
the upgrade as the prerequisite; do not fall back to an older SDK version or write a
|
|
300
|
+
partial browser-only integration.
|
|
301
|
+
|
|
302
|
+
#### Spring Boot 3, and separately Spring MVC
|
|
303
|
+
|
|
304
|
+
Two conditions. Both must hold for the Spring Boot starter.
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
rg -n "spring-boot-starter-parent|spring-boot-dependencies|org\.springframework\.boot" \
|
|
308
|
+
<owning-pom.xml-or-build.gradle*> | rg "3\.[0-9]+"
|
|
309
|
+
rg -n "spring-boot-starter-web[\"' :<]|spring-boot-starter-webflux|spring-webmvc" \
|
|
310
|
+
<owning-pom.xml-or-build.gradle*>
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Read the parent version, the `spring-boot-dependencies` BOM version, or the Gradle plugin
|
|
314
|
+
version. **Spring Boot 2.x does not qualify** — the starter is a Boot 3 artifact, so a
|
|
315
|
+
2.x app needs the core SDK path even though it is Spring.
|
|
316
|
+
|
|
317
|
+
Then MVC versus WebFlux — the trap worth checking every time:
|
|
318
|
+
|
|
319
|
+
- `spring-boot-starter-web` → Spring MVC. The starter is available when the app is also
|
|
320
|
+
Spring Boot 3 on Java 17+.
|
|
321
|
+
- `spring-boot-starter-webflux` with no `-web` → **not** Spring MVC. The starter protects
|
|
322
|
+
Spring MVC handler methods, so `@RequestShieldProtected` does not apply. Such an app is
|
|
323
|
+
Spring Boot 3 on Java 17+ and still needs the Java core SDK — say so explicitly,
|
|
324
|
+
because "Spring Boot 3, Java 21" reads like a starter green light and quietly is not.
|
|
325
|
+
Browser mode is unaffected; Seamless remains available when the request transport
|
|
326
|
+
matches.
|
|
327
|
+
- **Both present** → determine which stack serves the protected route. A
|
|
328
|
+
`@RestController` returning `Mono`/`Flux`, or a `RouterFunction`, indicates the
|
|
329
|
+
reactive path. Ask if it stays unclear.
|
|
330
|
+
|
|
331
|
+
Also not Spring MVC, and therefore the Java core SDK backend path: **Quarkus, Micronaut,
|
|
332
|
+
Dropwizard, Helidon, Ktor, Vert.x, Jakarta EE / JAX-RS on its own, and a plain servlet
|
|
333
|
+
application.**
|
|
334
|
+
|
|
335
|
+
## Then act on what you found
|
|
336
|
+
|
|
337
|
+
This decision chooses the backend path only. Pick the browser mode separately from how
|
|
338
|
+
the page issues the protected request.
|
|
339
|
+
|
|
340
|
+
| Detected | Do this |
|
|
341
|
+
| --- | --- |
|
|
342
|
+
| Java < 17, or no Java backend | Stop before editing. Report the finding and its source; no backend path is available, so nothing can enforce. Name the upgrade as the prerequisite. |
|
|
343
|
+
| Java 17+, no Spring Boot 3 MVC | Use Java core SDK. It is the only backend option; state it rather than asking a fake choice. |
|
|
344
|
+
| Java 17+ and Spring Boot 3 MVC | Both backend paths are viable. Recommend the starter and confirm once. |
|
|
345
|
+
| Ambiguous module, missing build file, version only in environment hints, or unclear MVC/WebFlux ownership | Ask, showing what you found. |
|
|
346
|
+
|
|
347
|
+
Always report the evidence with file and line references:
|
|
348
|
+
|
|
349
|
+
```text
|
|
350
|
+
Backend: theair-customer-backend/build.gradle.kts
|
|
351
|
+
Java 21 - java.toolchain.languageVersion (line 14)
|
|
352
|
+
Spring Boot 3.2.1 - org.springframework.boot plugin (line 3)
|
|
353
|
+
Spring MVC - spring-boot-starter-web (line 20)
|
|
354
|
+
Backend path: Spring Boot 3 starter. Browser mode still depends on released modes and request transport.
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Detection is inference from build files. If any line would read "unknown", ask rather
|
|
358
|
+
than assume.
|
|
359
|
+
|
|
360
|
+
## Choosing the mode
|
|
361
|
+
|
|
362
|
+
Reach this section only when **Contract check** left a genuine choice: both modes
|
|
363
|
+
released, and this operation not already integrated. If it landed on any other row of
|
|
364
|
+
that table, the mode is already decided — do not re-open it here.
|
|
365
|
+
|
|
366
|
+
This is the browser half. Backend path does not constrain it. Both browser modes deliver
|
|
367
|
+
the token in `X-IntelliFend-Token`, which either backend path reads.
|
|
368
|
+
|
|
369
|
+
| | **Seamless** | **Manual** |
|
|
370
|
+
| --- | --- | --- |
|
|
371
|
+
| Browser | `data-protect` lists exact endpoints; the SDK attaches tokens to matching `fetch` and async XHR requests. | `await IntelliFend.getToken()` at each protected call site, attached in application code. |
|
|
372
|
+
| Requires | The request travels by `fetch` or async XHR from page scope. | Nothing beyond the SDK and a supported carrier. |
|
|
373
|
+
| Code touched | One line of HTML. | Every protected call site, plus every retry path. |
|
|
374
|
+
| Backend work | Identical either way: whichever backend path the Gate selected. | Identical either way: whichever backend path the Gate selected. |
|
|
375
|
+
|
|
376
|
+
Released-mode availability was already settled at **Contract check**. One question is
|
|
377
|
+
left: does the protected request travel by `fetch` or asynchronous `XMLHttpRequest` from
|
|
378
|
+
page scope? Native form POST, `sendBeacon`, WebSocket/EventSource, synchronous XHR,
|
|
379
|
+
`no-cors`, and service-worker-owned requests are not intercepted — read
|
|
380
|
+
`browser-seamless.md` for the full coverage list.
|
|
381
|
+
|
|
382
|
+
Recommend Seamless when that check passes. It touches one line instead of every call
|
|
383
|
+
site, so there is no missed call site or retry path. If it fails, use Manual and give
|
|
384
|
+
the reason; that is a finding, not a preference.
|
|
385
|
+
|
|
386
|
+
A given protected operation uses one mode, not both. Different endpoints on the same
|
|
387
|
+
page may use different modes when necessary. Never use two backend verification paths on
|
|
388
|
+
one request; `@RequestShieldProtected` and manual `RequestShieldClient.verify()` both
|
|
389
|
+
consume the token, so the second returns `token_replayed`.
|