Skip to content

Day 21 — Authorization Before Effects

Today Forge learns the difference between a tool being available and an action being authorized.

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.

A completed effect returns identity, request digest, target, outcome, and idempotency key. Completion logic consumes the receipt; model narration does not substitute for it.

  • 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.

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.

Next: Day 22 — Trace, Replay, and Memory →.