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.
@@ -1,145 +1,145 @@
1
- # Backend SDK — Spring Boot 3 starter
2
-
3
- The backend is where protection actually happens. Everything the browser does is
4
- transport to deliver a token here; this file is where the request is allowed or refused.
5
-
6
- This is one of two backend paths. It is the declarative one, and it removes the most
7
- common hand-rolled mistakes, so prefer it whenever the stack allows. The other is the
8
- framework-neutral core SDK → `backend-java-core.md`.
9
-
10
- **Requires Spring Boot 3 with Spring MVC, and Java 17 or newer.** A Spring Boot 3 app
11
- built on WebFlux is not Spring MVC and cannot use this path. Confirm the stack before
12
- writing anything — the detection recipes are in `integration-planning.md`, under **Gate
13
- -> Run the check**. Also needed: the same
14
- App Key the browser uses, and the backend-only API Secret.
15
-
16
- Confirm the baseline and supported languages with `requestshield contract` first. If the
17
- customer's backend language is not listed, the honest answer is that the integration is
18
- not supported yet, because a browser-only install protects nothing.
19
-
20
- The browser mode does not decide this path. Either Seamless or Manual mode delivers the
21
- token in `X-IntelliFend-Token`, and the starter reads that header without caring how it
22
- got there.
23
-
24
- Use exactly **one** verification path per request. A RequestShield token is used once, so
25
- a handler covered by the annotation must not also call `verify()`.
26
-
27
- ## 1. Repository and dependency
28
-
29
- ```xml title="pom.xml"
30
- <repositories>
31
- <repository>
32
- <id>intellifend-maven</id>
33
- <url>https://sdk.intellifend.com/packages/maven</url>
34
- </repository>
35
- </repositories>
36
-
37
- <dependency>
38
- <groupId>com.intellifend.requestshield</groupId>
39
- <artifactId>requestshield-spring-boot3-starter</artifactId>
40
- <version>2.0.0</version>
41
- </dependency>
42
- ```
43
-
44
- ```kotlin title="build.gradle.kts"
45
- repositories {
46
- maven { url = uri("https://sdk.intellifend.com/packages/maven") }
47
- }
48
-
49
- dependencies {
50
- implementation("com.intellifend.requestshield:requestshield-spring-boot3-starter:2.0.0")
51
- }
52
- ```
53
-
54
- The starter includes `requestshield-backend-sdk:2.0.0` — do not declare both.
55
-
56
- ## 2. Configure
57
-
58
- ```yaml title="application.yml"
59
- intellifend:
60
- requestshield:
61
- app-key: ${INTELLIFEND_REQUESTSHIELD_APP_KEY}
62
- api-secret: ${INTELLIFEND_REQUESTSHIELD_API_SECRET}
63
- challenge-server-url: https://challenge.intellifend.ai
64
- mode: BLOCK
65
- ```
66
-
67
- | Property | Required | Notes |
68
- | --- | --- | --- |
69
- | `app-key` | Yes | Must be the same value as the browser's `data-app-key`. |
70
- | `api-secret` | Yes | Backend runtime secret storage. Pass the supplied value unchanged. |
71
- | `challenge-server-url` | No | Defaults to the RequestShield service. |
72
- | `mode` | No | Global mode, `BLOCK` or `MONITOR`. Defaults to `BLOCK`. |
73
-
74
- Bind the secret with no fallback default, so an environment that fails to inject it
75
- fails at startup. A backend that starts with a placeholder secret rejects every real
76
- token, which surfaces days later as "RequestShield is blocking all our users" — a
77
- startup failure is far cheaper to diagnose than that.
78
-
79
- ## 3. Annotate the protected method
80
-
81
- ```java
82
- import com.intellifend.requestshield.spring.boot.ProtectionMode;
83
- import com.intellifend.requestshield.spring.boot.RequestShieldProtected;
84
-
85
- @PostMapping("/api/register")
86
- @RequestShieldProtected(mode = ProtectionMode.DEFAULT)
87
- public RegisterResponse register(@RequestBody RegisterRequest request) {
88
- return accountService.create(request);
89
- }
90
- ```
91
-
92
- The annotation applies to methods. Put it on the handler that performs the protected
93
- mutation — not on a wrapper or a read-only route in front of it, where the mutation
94
- could still be reached another way.
95
-
96
- The annotation declares no path, action, domain, or browser URL list. It creates no
97
- browser configuration.
98
-
99
- ## 4. Enforcement mode
100
-
101
- | Mode | Behaviour |
102
- | --- | --- |
103
- | `BLOCK` | Enforce the decision before the method runs. |
104
- | `MONITOR` | Evaluate the request while allowing the method to continue. |
105
- | `DEFAULT` | Inherit the global mode. |
106
-
107
- The global property accepts `BLOCK` or `MONITOR` and defaults to `BLOCK`. A method-level
108
- `BLOCK` or `MONITOR` overrides the global setting.
109
-
110
- `MONITOR` is the right first deploy on live traffic: it produces real decisions and
111
- volume data with no risk of turning away genuine users, so you can confirm tokens are
112
- arriving before switching to `BLOCK`. State clearly whenever an endpoint is in
113
- `MONITOR` — it is protection-shaped and is not protection, and it is easy to forget.
114
-
115
- ## 5. Align the browser side
116
-
117
- Configure exactly one browser mode for the same operation:
118
-
119
- - Seamless mode → add the endpoint URL to `data-protect`. See `browser-seamless.md`.
120
- - Manual mode → send the obtained token in `X-IntelliFend-Token`. See
121
- `browser-manual.md`.
122
-
123
- Browser configuration does not create backend protection, and the annotation does not
124
- create browser configuration. Land both halves in the same change. For a cross-origin
125
- API, configure CORS to allow the token header.
126
-
127
- ## Migrating from manual verification
128
-
129
- For an endpoint already calling `RequestShieldClient.verify()`, remove that call and add
130
- the annotation **in the same backend release**. Running both consumes the same
131
- single-use token twice, so every request fails — and it fails only once both are
132
- deployed, which makes it look like the annotation broke the endpoint.
133
-
134
- Reason codes and what each means for debugging: `troubleshooting.md`.
135
-
136
- ## Security requirements
137
-
138
- - The API Secret lives in backend runtime secret storage only — never in source, a
139
- committed `.env`, an image layer, a client-visible response, or a log line.
140
- - The App Key must be identical in browser and backend, or every token fails.
141
- - One token per protected request, verified exactly once.
142
- - Never log or persist raw tokens, decoded claims, or the secret. Reason codes exist so
143
- diagnostics need none of that.
144
- - Enforce the decision before the business mutation, not after — verification that runs
145
- after the order is written is an audit log, not protection.
1
+ # Backend SDK — Spring Boot 3 starter
2
+
3
+ The backend is where protection actually happens. Everything the browser does is
4
+ transport to deliver a token here; this file is where the request is allowed or refused.
5
+
6
+ This is one of two backend paths. It is the declarative one, and it removes the most
7
+ common hand-rolled mistakes, so prefer it whenever the stack allows. The other is the
8
+ framework-neutral core SDK → `backend-java-core.md`.
9
+
10
+ **Requires Spring Boot 3 with Spring MVC, and Java 17 or newer.** A Spring Boot 3 app
11
+ built on WebFlux is not Spring MVC and cannot use this path. Confirm the stack before
12
+ writing anything — the detection recipes are in `integration-planning.md`, under **Gate
13
+ -> Run the check**. Also needed: the same
14
+ App Key the browser uses, and the backend-only API Secret.
15
+
16
+ Confirm the baseline and supported languages with `requestshield contract` first. If the
17
+ customer's backend language is not listed, the honest answer is that the integration is
18
+ not supported yet, because a browser-only install protects nothing.
19
+
20
+ The browser mode does not decide this path. Either Seamless or Manual mode delivers the
21
+ token in `X-IntelliFend-Token`, and the starter reads that header without caring how it
22
+ got there.
23
+
24
+ Use exactly **one** verification path per request. A RequestShield token is used once, so
25
+ a handler covered by the annotation must not also call `verify()`.
26
+
27
+ ## 1. Repository and dependency
28
+
29
+ ```xml title="pom.xml"
30
+ <repositories>
31
+ <repository>
32
+ <id>intellifend-maven</id>
33
+ <url>https://sdk.intellifend.com/packages/maven</url>
34
+ </repository>
35
+ </repositories>
36
+
37
+ <dependency>
38
+ <groupId>com.intellifend.requestshield</groupId>
39
+ <artifactId>requestshield-spring-boot3-starter</artifactId>
40
+ <version>2.0.0</version>
41
+ </dependency>
42
+ ```
43
+
44
+ ```kotlin title="build.gradle.kts"
45
+ repositories {
46
+ maven { url = uri("https://sdk.intellifend.com/packages/maven") }
47
+ }
48
+
49
+ dependencies {
50
+ implementation("com.intellifend.requestshield:requestshield-spring-boot3-starter:2.0.0")
51
+ }
52
+ ```
53
+
54
+ The starter includes `requestshield-backend-sdk:2.0.0` — do not declare both.
55
+
56
+ ## 2. Configure
57
+
58
+ ```yaml title="application.yml"
59
+ intellifend:
60
+ requestshield:
61
+ app-key: ${INTELLIFEND_REQUESTSHIELD_APP_KEY}
62
+ api-secret: ${INTELLIFEND_REQUESTSHIELD_API_SECRET}
63
+ challenge-server-url: https://challenge.intellifend.ai
64
+ mode: BLOCK
65
+ ```
66
+
67
+ | Property | Required | Notes |
68
+ | --- | --- | --- |
69
+ | `app-key` | Yes | Must be the same value as the browser's `data-app-key`. |
70
+ | `api-secret` | Yes | Backend runtime secret storage. Pass the supplied value unchanged. |
71
+ | `challenge-server-url` | No | Defaults to the RequestShield service. |
72
+ | `mode` | No | Global mode, `BLOCK` or `MONITOR`. Defaults to `BLOCK`. |
73
+
74
+ Bind the secret with no fallback default, so an environment that fails to inject it
75
+ fails at startup. A backend that starts with a placeholder secret rejects every real
76
+ token, which surfaces days later as "RequestShield is blocking all our users" — a
77
+ startup failure is far cheaper to diagnose than that.
78
+
79
+ ## 3. Annotate the protected method
80
+
81
+ ```java
82
+ import com.intellifend.requestshield.spring.boot.ProtectionMode;
83
+ import com.intellifend.requestshield.spring.boot.RequestShieldProtected;
84
+
85
+ @PostMapping("/api/register")
86
+ @RequestShieldProtected(mode = ProtectionMode.DEFAULT)
87
+ public RegisterResponse register(@RequestBody RegisterRequest request) {
88
+ return accountService.create(request);
89
+ }
90
+ ```
91
+
92
+ The annotation applies to methods. Put it on the handler that performs the protected
93
+ mutation — not on a wrapper or a read-only route in front of it, where the mutation
94
+ could still be reached another way.
95
+
96
+ The annotation declares no path, action, domain, or browser URL list. It creates no
97
+ browser configuration.
98
+
99
+ ## 4. Enforcement mode
100
+
101
+ | Mode | Behaviour |
102
+ | --- | --- |
103
+ | `BLOCK` | Enforce the decision before the method runs. |
104
+ | `MONITOR` | Evaluate the request while allowing the method to continue. |
105
+ | `DEFAULT` | Inherit the global mode. |
106
+
107
+ The global property accepts `BLOCK` or `MONITOR` and defaults to `BLOCK`. A method-level
108
+ `BLOCK` or `MONITOR` overrides the global setting.
109
+
110
+ `MONITOR` is the right first deploy on live traffic: it produces real decisions and
111
+ volume data with no risk of turning away genuine users, so you can confirm tokens are
112
+ arriving before switching to `BLOCK`. State clearly whenever an endpoint is in
113
+ `MONITOR` — it is protection-shaped and is not protection, and it is easy to forget.
114
+
115
+ ## 5. Align the browser side
116
+
117
+ Configure exactly one browser mode for the same operation:
118
+
119
+ - Seamless mode → add the endpoint URL to `data-protect`. See `browser-seamless.md`.
120
+ - Manual mode → send the obtained token in `X-IntelliFend-Token`. See
121
+ `browser-manual.md`.
122
+
123
+ Browser configuration does not create backend protection, and the annotation does not
124
+ create browser configuration. Land both halves in the same change. For a cross-origin
125
+ API, configure CORS to allow the token header.
126
+
127
+ ## Migrating from manual verification
128
+
129
+ For an endpoint already calling `RequestShieldClient.verify()`, remove that call and add
130
+ the annotation **in the same backend release**. Running both consumes the same
131
+ single-use token twice, so every request fails — and it fails only once both are
132
+ deployed, which makes it look like the annotation broke the endpoint.
133
+
134
+ Reason codes and what each means for debugging: `troubleshooting.md`.
135
+
136
+ ## Security requirements
137
+
138
+ - The API Secret lives in backend runtime secret storage only — never in source, a
139
+ committed `.env`, an image layer, a client-visible response, or a log line.
140
+ - The App Key must be identical in browser and backend, or every token fails.
141
+ - One token per protected request, verified exactly once.
142
+ - Never log or persist raw tokens, decoded claims, or the secret. Reason codes exist so
143
+ diagnostics need none of that.
144
+ - Enforce the decision before the business mutation, not after — verification that runs
145
+ after the order is written is an audit log, not protection.