Commit 6663cda
feat(0.14.0): rate limits + approval-gated leases
Two related capabilities in one release.
Rate limits
- AppRoles gain three optional caps (per-minute/hour/day) settable via
the UI or POST/PUT /v1/auth/approle. Per-secret minute caps come from
metadata.rate_limit_per_minute. Both apply independently; the most
restrictive wins.
- Fixed-window counters keyed on Math.floor(now/window_ms), in-memory.
Hard ceilings 10K/min, 100K/hour, 1M/day.
- 429 with Retry-After when hit. Root tokens and user JWTs exempt.
- New audit actions: proxy.blocked.rate_limit.
Approval-gated leases (unified model)
- metadata.requires_approval=true gates a secret. Agents must call
gatehouse_request_access(path, ttl, justification) and wait for a
human approval before gatehouse_proxy or gatehouse_lease succeeds.
- The approved lease IS the access window. Revoke once, atomic kill.
No second checkout lease; each value-reveal audits as lease.access
against the approval lease_id.
- Status drives lifecycle: pending -> approved/denied/expired. revoked
boolean stays orthogonal.
- Auto-approve via metadata.auto_approve_from_ip (CIDR list) plus
optional auto_approve_ttl_seconds.
- Webhook on lease.request_created (GATEHOUSE_APPROVAL_WEBHOOK_URL).
Optional HMAC-SHA256 signing over `${timestamp}.${body}` with
X-Gatehouse-Timestamp and X-Gatehouse-Signature headers when
GATEHOUSE_APPROVAL_WEBHOOK_SECRET is set; 5-minute replay window.
- AppRole delete clears that identity's pending leases.
Shared
- enforceProxyGates() helper consumed by REST proxy and MCP proxy so
the three gates (AppRole rate limit, per-secret rate limit, approval)
stay consistent across surfaces.
- AuthContext gains role_id (extracted from JWT payload in middleware).
- New MCP tool gatehouse_request_access; gatehouse_status now returns
pending_leases.
- New SSE events lease_request_created and lease_status_changed,
identity-scoped server-side.
UI
- Leases page: Active / Pending Approval tabs. Approve / Deny actions
with justification preview. Sidebar pending badge updated via SSE.
- AppRole modals: three rate-limit inputs. List row gets a small
rate-limited badge when any limit is set.
- Secrets tree: approval chip on gated secrets. Detail panel: banner
+ Active Approved Leases section.
Migration
- Schema-only. Six nullable columns on leases (status defaulting to
'approved' so every existing row stays valid) and three on app_roles.
New index idx_leases_pending.
Tests: 497 pass (up from 459). New: test/rateLimits.test.ts,
test/leaseApproval.test.ts, test/leaseWebhook.test.ts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent a2cdb74 commit 6663cda
23 files changed
Lines changed: 3179 additions & 85 deletions
File tree
- src
- api
- auth
- db
- events
- lease
- mcp
- rateLimits
- templates
- ui
- test
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
8 | 38 | | |
9 | 39 | | |
10 | 40 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| 30 | + | |
| 31 | + | |
30 | 32 | | |
31 | 33 | | |
32 | 34 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
| 11 | + | |
10 | 12 | | |
11 | 13 | | |
12 | 14 | | |
| |||
55 | 57 | | |
56 | 58 | | |
57 | 59 | | |
58 | | - | |
| 60 | + | |
59 | 61 | | |
60 | 62 | | |
61 | 63 | | |
| |||
616 | 618 | | |
617 | 619 | | |
618 | 620 | | |
619 | | - | |
| 621 | + | |
620 | 622 | | |
621 | 623 | | |
622 | 624 | | |
| |||
628 | 630 | | |
629 | 631 | | |
630 | 632 | | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
631 | 636 | | |
632 | 637 | | |
633 | 638 | | |
| |||
644 | 649 | | |
645 | 650 | | |
646 | 651 | | |
647 | | - | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
648 | 660 | | |
649 | 661 | | |
650 | 662 | | |
| |||
672 | 684 | | |
673 | 685 | | |
674 | 686 | | |
675 | | - | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
676 | 711 | | |
677 | 712 | | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
678 | 717 | | |
679 | 718 | | |
680 | 719 | | |
681 | 720 | | |
682 | 721 | | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
683 | 728 | | |
684 | 729 | | |
685 | 730 | | |
686 | 731 | | |
687 | 732 | | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
688 | 736 | | |
689 | 737 | | |
690 | 738 | | |
| |||
725 | 773 | | |
726 | 774 | | |
727 | 775 | | |
728 | | - | |
| 776 | + | |
729 | 777 | | |
730 | 778 | | |
731 | 779 | | |
732 | 780 | | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
733 | 790 | | |
734 | 791 | | |
735 | 792 | | |
| |||
1066 | 1123 | | |
1067 | 1124 | | |
1068 | 1125 | | |
1069 | | - | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
1070 | 1134 | | |
1071 | 1135 | | |
1072 | 1136 | | |
| |||
1093 | 1157 | | |
1094 | 1158 | | |
1095 | 1159 | | |
| 1160 | + | |
| 1161 | + | |
| 1162 | + | |
| 1163 | + | |
| 1164 | + | |
| 1165 | + | |
| 1166 | + | |
| 1167 | + | |
| 1168 | + | |
1096 | 1169 | | |
1097 | 1170 | | |
1098 | 1171 | | |
1099 | 1172 | | |
1100 | 1173 | | |
1101 | | - | |
1102 | | - | |
| 1174 | + | |
| 1175 | + | |
| 1176 | + | |
| 1177 | + | |
| 1178 | + | |
| 1179 | + | |
| 1180 | + | |
| 1181 | + | |
| 1182 | + | |
| 1183 | + | |
| 1184 | + | |
1103 | 1185 | | |
1104 | 1186 | | |
1105 | 1187 | | |
| |||
1108 | 1190 | | |
1109 | 1191 | | |
1110 | 1192 | | |
| 1193 | + | |
| 1194 | + | |
| 1195 | + | |
1111 | 1196 | | |
1112 | 1197 | | |
1113 | 1198 | | |
| |||
0 commit comments