feat(egress): add controlled_egress SDK helper emitting agent-signed egress_receipt/1#10
Merged
Merged
Conversation
Add an SDK-owned HTTPS egress helper that evaluates Runtime Gate, performs the send only on ALLOW, and emits agent-signed egress_receipt/1 artifacts with dual hash handling.\n\nIncludes SDK-local receipt signer/verifier coverage, DID binding checks, and focused stub-driven tests.\n\nImplemented by Claude and reviewed with assistance from Codex.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
AVPAgent.controlled_egress(...), the first SDK boundary that emits an agent-signedegress_receipt/1. The helper performs the HTTPS request itself (no caller-suppliedsendcallback); receipts record what the helper actually did, not what the caller declared it would do.What the helper does
payload_digest_hex = sha256(body).hexdigest()andruntime_payload_hash = f"sha256:{payload_digest_hex}"./v1/runtime/evaluatewithaction="network.egress",payload_hash=runtime_payload_hash, and the caller's delegation receipt.ALLOW→ opens the HTTPS connection via embeddedhttpx.Clientand signs anegress_receipt/1withoutcome=SENT(orFAILEDon connection-class error, with sanitized error class only).BLOCK→ does NOT open the connection; signs receipt withoutcome=BLOCKED.WAITING_FOR_HUMAN_APPROVAL→ does NOT open the connection; returnsstatus="approval_required"with no receipt in v0.1.Receipts are agent-signed, not backend-signed. The signer DID equals the agent's identity DID. Customers verify via
verify_egress_receipt(receipt_jcs, trusted_signer_dids=[agent.did]).Agent-DID binding
Both the signer and the verifier enforce
body.agent_did == proof signer DID. Without this an agent-signed receipt could claim another identity performed the egress, breaking offline audit attribution.Dependency
Depends on AVP backend PR: https://github.com/agentveil-protocol/avp/pull/1
That PR adds
network.egressto the Runtime Gate catalog. Until it is deployed,controlled_egress(...)will safely degrade toapproval_requiredfor unknown-action WAITING responses.What this does NOT claim
controlled_egress(...)calls are recorded.requests.post(...)— false. Customers must use the helper for the receipt to be produced.Files changed
agentveil/egress.pyagentveil/agent.pyagentveil/__init__.pytests/test_egress_sdk_wrapper.pyTests run
python3 -m pytest tests/test_egress_sdk_wrapper.py -q→10 passedpython3 -m pytest tests/test_controlled_action.py tests/test_contract.py tests/test_auth.py tests/test_delegation_issuance.py tests/test_identity.py -q→65 passedgit diff origin/main..HEAD --check→ cleanRemaining non-blocking gaps
/v1/egress/sign).egress_receipt/2schema withdecision_receipt_hashcross-reference.Implemented by Claude and reviewed with assistance from Codex.