@7h3/protocol 0.5.3 → 0.5.6

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/gateway.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type KeyRegistry } from './keyRegistry';
2
2
  import { type RoutePolicy } from './routePolicy';
3
- import { SlidingWindowRateLimiter } from './rateLimiter';
3
+ import { SlidingWindowRateLimiter, type RateLimitStore } from './rateLimiter';
4
4
  import type { ReplayStore } from './replayStores';
5
5
  export type { KeyRegistry, RoutePolicy };
6
6
  export interface GatewayConfig {
@@ -15,6 +15,14 @@ export interface GatewayConfig {
15
15
  metricsPath?: string;
16
16
  /** Optional distributed replay store — prevents nonce reuse across gateway instances. */
17
17
  replayStore?: ReplayStore;
18
+ /**
19
+ * Optional persistent rate-limit store — required for correct rate limiting
20
+ * whenever the gateway is rebuilt per-request (e.g. inside a Workers/Lambda
21
+ * fetch handler). Without it, rate limiting falls back to the in-memory
22
+ * SlidingWindowRateLimiter, which only works if this Gateway instance
23
+ * persists across the requests it's limiting.
24
+ */
25
+ rateLimitStore?: RateLimitStore;
18
26
  /** Optional capability token registry for capability-based auth. */
19
27
  capabilityRegistry?: {
20
28
  getPublicKey(id: string): Promise<string | null>;
@@ -38,16 +46,42 @@ export type GatewayVerifyOutcome = {
38
46
  envelopeId?: string;
39
47
  } | {
40
48
  ok: false;
41
- status: 401 | 403 | 429;
49
+ status: 400 | 401 | 403 | 429;
42
50
  reason: string;
43
51
  };
52
+ /**
53
+ * Normalize a request path before it's used for both policy matching and
54
+ * upstream forwarding. Without this, a path like `/public/../admin/secret`
55
+ * matches a permissive `/public/**` policy (or no policy at all, under
56
+ * `defaultPolicy: 'allow'`) as a literal string, is forwarded unverified,
57
+ * and then gets collapsed by the URL parser inside `fetch()` on the way out
58
+ * — landing on `/admin/secret` at the upstream with zero verification ever
59
+ * having been performed against the path that's actually reached. Matching
60
+ * and forwarding must both operate on the same fully-normalized path so
61
+ * there's no gap between what was checked and what was sent.
62
+ *
63
+ * Returns null for anything that isn't a clean absolute path — including a
64
+ * `..` that would escape above the root, or percent-encoding that doesn't
65
+ * settle after a bounded number of decode passes (double-encoding is a
66
+ * classic way to smuggle a traversal past a single decode).
67
+ */
68
+ export declare function normalizeGatewayPath(rawPath: string): string | null;
44
69
  declare class Protocol7h3Gateway {
45
70
  private config;
46
71
  private rateLimiter;
47
72
  constructor(config: GatewayConfig);
73
+ private checkSenderAndRateLimit;
48
74
  verify(req: GatewayRequest): Promise<GatewayVerifyOutcome>;
49
75
  handle(req: GatewayRequest): Promise<GatewayResponse>;
50
76
  getRateLimiter(): SlidingWindowRateLimiter;
51
77
  }
52
78
  export declare function createGateway(config: GatewayConfig): Protocol7h3Gateway;
79
+ /**
80
+ * Hardened preset for production deployments: fails fast (rather than
81
+ * silently falling back to permissive defaults) if `defaultPolicy` isn't
82
+ * explicitly `'deny'` or `replayStore` isn't configured. Use this instead of
83
+ * `createGateway()` wherever a misconfiguration should be a deploy-time error,
84
+ * not a runtime security gap discovered later.
85
+ */
86
+ export declare function createProductionGateway(config: GatewayConfig): Protocol7h3Gateway;
53
87
  export { Protocol7h3Gateway };