Day 21 — Authorization Before Effects
Today Forge learns the difference between a tool being available and an action being authorized.
Compile policy into an execution decision
Section titled “Compile policy into an execution decision”An approval should bind:
pub struct AuthorizationGrant { pub subject: SubjectId, pub capability: CapabilityId, pub argument_digest: String, pub scope: ResourceScope, pub expires_at: Timestamp, pub max_uses: u32,}“Allow file writes” is too broad. A useful grant says who may invoke which capability, with which exact arguments or bounded scope, until when, and how many times.
Separate read, local write, and external effect
Section titled “Separate read, local write, and external effect”The user may permit reading a repository without permitting edits. A local draft file is different from publishing a message, charging a card, merging a pull request, or deleting cloud data. Make effect class part of policy input.
Produce receipts
Section titled “Produce receipts”A completed effect returns identity, request digest, target, outcome, and idempotency key. Completion logic consumes the receipt; model narration does not substitute for it.
Break it deliberately
Section titled “Break it deliberately”- reuse an expired approval;
- alter one argument after approval;
- broaden a root path;
- replay a one-use grant;
- return success without target-state evidence;
- treat policy denial as a provider error and retry.
Verify no forbidden effect occurs in every failure case.
Completion proof
Section titled “Completion proof”Extend Forge with a local-write tool requiring exact approval. Test permitted, denied, expired, argument-changed, duplicate, and indeterminate outcomes.
Deep references: Authorized tool loop and Threat-model the agent.