Feat/v0.0.5 beta access requests - #2
Conversation
Add suspend-and-resume access request flow: when an agent is denied by constraints, the call blocks waiting for out-of-band human approval via HMAC-signed verification codes the agent cannot forge. - AccessRequestManager: HMAC-SHA256 code generation, pending request tracking, approve/deny/expire with rate limiting - ApprovalStore: encrypted tamper-proof rule storage with HMAC integrity checks (rules wiped if store is tampered with) - 4 approval scopes: call (one-time), value (session), capability (session), global (persistent across restarts) - Context preservation: blocked calls suspend on a Promise closure holding capability, args, and targetFn — resumes exactly where it left off after approval - Pluggable AccessRequestNotifier interface for email/SMS/push/webhook - AppChain.approve()/deny()/getPendingRequests()/getApprovalRules()/ revokeApproval() API surface - 57 new tests covering manager, store, and full integration Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…execution The call scope rule was not handled in getExpandedConstraints, so the re-execution after approval hit the same constraint violation again. Fix: treat call scope the same as value scope when expanding the in list. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR adds a complete access request and approval workflow system to AgentChain, enabling agents to request out-of-band human approval for denied capability calls. The implementation includes HMAC-verified request codes, scoped approval rules, encrypted persistent storage with integrity checking, and seamless integration into the capability execution interception path. ChangesAccess Request and Approval Workflow
🎯 4 (Complex) | ⏱️ ~60 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds an optional “access request” escalation flow to the AppChain runtime so that denied/constraint-violating agent calls can be suspended and later resumed after out-of-band human approval, with approvals stored as encrypted rules.
Changes:
- Introduces access-request domain types plus
AccessRequestManager(pending requests + HMAC verification codes) andApprovalStore(encrypted approval rules with integrity tagging). - Integrates access-request suspension/resume and approval-rule constraint expansion into
wrapApp()execution. - Exposes new APIs/exports on
AppChainand adds a comprehensive test suite for the access-request system.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/types/chain.ts | Adds accessRequests config surface to enable the feature. |
| src/types/audit.ts | Extends audit result/entry types for access-request-related outcomes/metadata. |
| src/types/access-request.ts | Introduces access-request, decision, notifier, and approval-rule type definitions. |
| src/index.ts | Exports the new access-request modules and types from the public entrypoint. |
| src/errors/chain-error.ts | Adds new access_request_* error codes to ChainErrorCode. |
| src/chain.ts | Wires access-request manager/store creation, lifecycle, and new AppChain APIs. |
| src/app/app-wrapper.ts | Implements suspend/resume flow and constraint expansion during capability execution. |
| src/access/approval-store.ts | New encrypted approval-rule store with integrity checking and rule querying. |
| src/access/access-request-manager.ts | New access request lifecycle manager (create/approve/deny/expire) with HMAC codes. |
| src/tests/access-requests.test.ts | Adds unit + integration tests for the access-request system. |
| package.json | Updates package version and expands the test script to include new tests. |
| .npmignore | Minor ignore-file formatting adjustment. |
| .gitignore | Ignores OVERVIEW.md. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const fieldMatch = err.message.match(/field "([^"]+)"/); | ||
| const valueMatch = err.message.match(/field "[^"]+": "([^"]*)"/) ?? | ||
| err.message.match(/field "[^"]+": (\S+)/); | ||
|
|
||
| return { | ||
| violatedField: fieldMatch?.[1], | ||
| violatedValue: valueMatch?.[1], | ||
| }; |
| // Rule exists but constraint enforcement still failed — | ||
| // this shouldn't happen if getEffectiveConstraints worked. | ||
| // Re-execute with fresh auth token (the approval rule | ||
| // will take effect via getEffectiveConstraints). | ||
| return executeWithAccessRequest(capabilityName, callArgs, ctx, targetFn); |
| /** | ||
| * Get the expanded constraints from all active rules for a capability. | ||
| * These get merged into the grant constraints before enforcement. | ||
| */ | ||
| /** | ||
| * Get the expanded constraints from all active rules for a capability. | ||
| * These get merged into the grant constraints before enforcement. | ||
| * | ||
| * Returns: | ||
| * - `null` → a capability/global rule bypasses ALL constraints | ||
| * - `undefined` → no matching rules found, no expansions (use original constraints) | ||
| * - `GrantConstraints` → merged expansions to apply on top of the grant constraints | ||
| */ |
| if (inc.not_in) { | ||
| // Remove from not_in if we're approving it | ||
| merged.not_in = (merged.not_in ?? []).filter( | ||
| (v) => !inc.in?.includes(v) | ||
| ); | ||
| if (merged.not_in.length === 0) delete merged.not_in; | ||
| } |
| | "access_request_pending" | ||
| | "access_request_denied" | ||
| | "access_request_expired"; |
| { | ||
| "name": "agents-chain", | ||
| "version": "0.0.45", | ||
| "version": "0.0.5-1", |
| const existing = merged[field]; | ||
| if (!existing) continue; // Don't add new constraints, only expand existing ones |
| /** Verification codes are truncated to this many hex chars for human-friendliness. */ | ||
| const CODE_LENGTH = 8; |
| capability: params.capability, | ||
| args: params.args, | ||
| reason: params.reason, |
Summary by CodeRabbit
New Features
Tests
Chores
.gitignoreand.npmignoreconfigurations.