guardian-risk 0.3.0 → 0.3.1

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.
Files changed (2) hide show
  1. package/README.md +58 -29
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -2,13 +2,17 @@
2
2
 
3
3
  Configurable risk decision engine for TypeScript. Evaluate signals against rules and get an explainable risk score.
4
4
 
5
+ **Production-ready** at `0.3.x` — zero runtime dependencies, hardened validation, async hooks, and official plugins for Express, Redis, VPN, browser, and logging.
6
+
5
7
  ## Install
6
8
 
7
9
  ```bash
8
10
  npm install guardian-risk
9
11
  ```
10
12
 
11
- ## Usage
13
+ ## Usage (core only)
14
+
15
+ No plugins required — sync `analyze()` works when no hooks are registered:
12
16
 
13
17
  ```typescript
14
18
  import { Guardian } from 'guardian-risk';
@@ -41,42 +45,49 @@ Install **core first**, then add only the plugins you need:
41
45
  | Package | Install | Purpose |
42
46
  |---------|---------|---------|
43
47
  | **guardian-risk** (this) | `npm i guardian-risk` | Core engine |
44
- | guardian-risk-express | `npm i guardian-risk-express` | Express request signals |
45
- | guardian-risk-browser | `npm i guardian-risk-browser` | Browser behavioral signals |
46
- | guardian-risk-redis | `npm i guardian-risk-redis` | Redis session counters |
48
+ | guardian-risk-express | `npm i guardian-risk-express` | Express middleware + validated IP |
49
+ | guardian-risk-redis | `npm i guardian-risk-redis` | Redis session counters + rate limits |
47
50
  | guardian-risk-vpn | `npm i guardian-risk-vpn` | VPN / proxy / Tor detection |
51
+ | guardian-risk-browser | `npm i guardian-risk-browser` | Browser behavioral signals |
48
52
  | guardian-risk-logger | `npm i guardian-risk-logger` | Audit logging |
49
53
 
50
54
  ```bash
51
- # Example: Express + VPN + Logger stack
52
- npm install guardian-risk guardian-risk-express guardian-risk-vpn guardian-risk-logger
55
+ npm install guardian-risk guardian-risk-express guardian-risk-redis guardian-risk-vpn guardian-risk-logger
56
+ npm install ioredis # optional, required for Redis in production
53
57
  ```
54
58
 
59
+ ### Production Express example
60
+
55
61
  ```typescript
56
62
  import express from 'express';
57
63
  import { Guardian } from 'guardian-risk';
58
- import { expressPlugin, guardianMiddleware, type ExpressRequest } from 'guardian-risk-express';
64
+ import { expressPlugin, guardianMiddleware } from 'guardian-risk-express';
59
65
  import { redisPlugin } from 'guardian-risk-redis';
60
66
  import { vpnPlugin, StaticIpProvider } from 'guardian-risk-vpn';
61
67
  import { loggerPlugin } from 'guardian-risk-logger';
62
68
 
63
69
  const app = express();
70
+ app.set('trust proxy', 1);
64
71
 
65
- const riskTemplate = new Guardian()
72
+ const template = new Guardian()
66
73
  .use(expressPlugin({ trustProxy: true }))
67
- .use(redisPlugin())
68
- .use(vpnPlugin({ provider: new StaticIpProvider({}) }))
69
- .use(loggerPlugin())
70
- .rule({ name: 'Burst', when: (s) => (s.requestsPerMinute as number) > 30, score: 40 });
71
-
72
- app.use(guardianMiddleware(riskTemplate, { blockAboveScore: 80 }));
73
-
74
- app.post('/login', (req: ExpressRequest, res) => {
75
- res.json(req.riskReport);
76
- });
74
+ .use(redisPlugin({ url: process.env.REDIS_URL, allowInMemoryFallback: false }))
75
+ .use(vpnPlugin({ provider: new StaticIpProvider({}), vpnScore: 25 }))
76
+ .use(loggerPlugin({ minScore: 20 }))
77
+ .rule({ name: 'Burst', when: (s) => (s.requestsInWindow as number) > 30, score: 40 });
78
+
79
+ app.get('/health', (_req, res) => res.json({ ok: true }));
80
+
81
+ app.use(
82
+ guardianMiddleware(template, {
83
+ blockAboveScore: 80,
84
+ onAnalyzeError: 'block',
85
+ exposeBlockDetails: false,
86
+ }),
87
+ );
77
88
  ```
78
89
 
79
- > Plugin packages are early stubsAPIs may change before `1.0.0`.
90
+ > Use your own IP intelligence provider in production (MaxMind, IPinfo, etc.) not the dev-only `IpApiProvider`.
80
91
 
81
92
  ## Plugins API
82
93
 
@@ -86,14 +97,16 @@ import type { Plugin } from 'guardian-risk';
86
97
  const myPlugin: Plugin = {
87
98
  name: 'my-plugin',
88
99
  install(guardian) {
89
- guardian.rule({ name: 'Custom', when: () => true, score: 10 });
100
+ guardian.beforeAnalyze(async ({ guardian: g }) => {
101
+ g.signal('customSignal', true);
102
+ });
90
103
  },
91
104
  };
92
105
 
93
- new Guardian().use(myPlugin);
106
+ await new Guardian().use(myPlugin).analyzeAsync();
94
107
  ```
95
108
 
96
- ## Typed signals & presets (v0.3)
109
+ ## Typed signals & presets
97
110
 
98
111
  ```typescript
99
112
  import { defineSignals, applyRules, botDetectionRules } from 'guardian-risk';
@@ -107,7 +120,7 @@ const guardian = applyRules(bot.create(), botDetectionRules)
107
120
  const report = await guardian.analyzeAsync();
108
121
  ```
109
122
 
110
- ## Rule groups (v0.3)
123
+ ## Rule groups
111
124
 
112
125
  ```typescript
113
126
  guardian.ruleGroup({
@@ -119,37 +132,53 @@ guardian.ruleGroup({
119
132
  });
120
133
  ```
121
134
 
122
- See [MIGRATION.md](../../MIGRATION.md) when upgrading versions.
123
-
124
135
  ## API
125
136
 
126
137
  | Method | Description |
127
138
  |--------|-------------|
128
139
  | `guardian.signal(key, value)` | Add a signal |
140
+ | `guardian.getSignal(key)` | Read a signal without modifying state |
129
141
  | `guardian.rule({ name, when, score, reason? })` | Register a rule |
142
+ | `guardian.ruleGroup({ name, maxScore, rules })` | Register capped rule group |
130
143
  | `guardian.use(plugin)` | Install a plugin (once per name) |
131
144
  | `guardian.beforeAnalyze(hook)` | Run hook before evaluation (async OK) |
132
145
  | `guardian.afterAnalyze(hook)` | Run hook after report is built |
133
- | `guardian.analyze()` | Sync analysis (no hooks registered) |
146
+ | `guardian.analyze()` | Sync analysis (only when no hooks registered) |
134
147
  | `guardian.analyzeAsync(context?)` | Async analysis with lifecycle hooks |
135
148
  | `guardian.fork()` | Clone rules/plugins for per-request use |
136
149
  | `guardian.reset()` | Clear signals (rules + plugins persist) |
137
150
  | `guardian.getInstalledPlugins()` | List installed plugin names |
138
151
 
152
+ ## Production checklist
153
+
154
+ 1. One **template** `Guardian` at startup; `fork()` or middleware per request
155
+ 2. `await analyzeAsync(req)` when plugins are installed
156
+ 3. `app.set('trust proxy', 1)` behind load balancers
157
+ 4. `REDIS_URL` set; `allowInMemoryFallback: false` in production
158
+ 5. Your own VPN/IP provider — not default external APIs
159
+ 6. `onAnalyzeError: 'block'` and `exposeBlockDetails: false` when blocking
160
+ 7. Browser/client signals are hints only — never sole auth factor
161
+
162
+ Full details: [SECURITY.md](https://github.com/himanshu6306singh/guardian-risk/blob/main/SECURITY.md)
163
+
139
164
  ## Security
140
165
 
141
166
  - **Zero runtime dependencies** — minimal supply chain risk
142
167
  - **No install scripts** — nothing runs on `npm install`
168
+ - String signals capped at 4 KB; `NaN`/`Infinity` rejected
143
169
  - Prototype pollution protection on signal keys
144
170
  - Rule `when()` errors isolated — engine stays stable
171
+ - Hook timeout (10s); rules/plugins locked during `analyzeAsync()`
172
+ - Deep-frozen matched rules in reports
145
173
  - Score bounds: ±10,000 per rule, ±1,000,000 total
146
- - Plugin `install()` failures throw `PluginInstallError` without registering
147
- - See [SECURITY.md](SECURITY.md) for vulnerability reporting
174
+
175
+ See [SECURITY.md](https://github.com/himanshu6306singh/guardian-risk/blob/main/SECURITY.md) for vulnerability reporting.
148
176
 
149
177
  ## Links
150
178
 
151
179
  - [GitHub monorepo](https://github.com/himanshu6306singh/guardian-risk)
152
- - [All packages guide](https://github.com/himanshu6306singh/guardian-risk/blob/main/ECOSYSTEM.md)
180
+ - [Migration guide](https://github.com/himanshu6306singh/guardian-risk/blob/main/MIGRATION.md)
181
+ - [All packages](https://github.com/himanshu6306singh/guardian-risk/blob/main/ECOSYSTEM.md)
153
182
 
154
183
  ## License
155
184
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "guardian-risk",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Configurable risk decision engine using signals, rules, and scoring. Zero runtime dependencies.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",