Vote for your favorite SkillMD. The submission with the most likes wins the $1,000 Audience Choice Award for the NandaHack x HCLTech hackathon. Voting is open through September 25.Vote now →
mergedhumanPR #89Identity

stellarminds-ai: AAE permit gate — pre-action authorization with signed denial receipts

Layer: trust · Persona: stellarminds-ai

Author

Sharathvc23 avatar

@Sharathvc23

github profile →
Status
Merged
Merged on
Jul 8
Branch
hackathon/stellarminds-ai-aae-permit-gate

Description

The pitch.

**Layer:** trust · **Persona:** stellarminds-ai

## Motivation

Every trust plugin in the town — the reference `score_average`, EigenTrust variants, receipt-corroborated reputation, all of it — scores what an agent **did**. None of them decide what an agent **may do**. That gap has a name: a well-reputed agent attempting an unauthorized action sails through every post-hoc reputation layer, because reputation is measured *after* the fact and the unauthorized action is exactly the one no prior good behavior should license.

Capability-token work (Problem 04) governs who may *hold* an authority. This plugin governs each *exercise* of it: it evaluates an action before it runs, and — crucially — a denial is a first-class, signed, verifiable receipt rather than a silent absence.

## Design

`aae_permit_gate` issues a **pre-action envelope** for every evaluation. Eight fields: `agent_id`, `action{verb,resource,params}`, `policy_id`, `outcome` (`authorized`|`denied`|`conditional`), `prev_hash` (per-agent causal chain), `issued_at`, `sig` (Ed25519 over the canonical envelope minus `sig`), `pubkey`.

- **Evaluate before acting.** The engine does not intercept actions, so gating is a scenario contract: an agent calls `evaluate(...)` and proceeds only on an authorized envelope. Plugins without an `evaluate` method are consulted as scores, so scenarios stay drop-in (`hasattr` capability-gate — the house pattern).
- **Deny by default.** Unmatched actions are denied; the posture is explicit and documented.
- **Signed denials.** A denied action does not execute, and the denial envelope *is* the receipt — anyone can verify the town refused it, under which policy, when.
- **Per-agent chain.** Each envelope's `prev_hash` points at the agent's previous one; `order_chain` recovers the unique order and rejects gaps, forks, deleted interior links, and foreign-agent splices.
- Self-contained: stdlib + `cryptography` only. Deterministic: every timestamp is supplied by the caller's virtual clock; same seed → byte-identical envelopes.

Registered both ways — `_BUILTINS[("trust","aae_permit_gate")]` and the `nest.plugins.trust` entry point in `nest-plugins-reference/pyproject.toml`.

## Adversarial validator (mandatory)

`rogue_trusted_agent_blocked` catches a high-reputation agent reaching outside its authorization. In the `rogue_trusted_agent` scenario one agent earns a strong reputation through eight in-policy actions, then attempts `spend town/treasury`:

```
exec:veteran:read:town/events                       <- reputation accrued
rogue_attempt:veteran:spend:town/treasury
permit:veteran:spend:town/treasury:denied:84773277  <- signed denial
blocked:veteran:spend:town/treasury                 <- never executes
```

**FAILS against `trust: score_average`** — reputation buys the treasury, the rogue action executes:

```
rogue_attempt:veteran:spend:town/treasury
exec:veteran:spend:town/treasury                    <- rogue action executes
```

**PASSES against `trust: aae_permit_gate`** — refused before it runs. No crash on either trace. A second validator, `rogue_trusted_agent_reputation`, corroborates that the veteran genuinely accrued reputation first and that no in-policy action was ever spuriously denied — so "reputation is irrelevant to the verdict" is grounded in the trace, not asserted.

## How to verify

```
make ci-local                                              # all 5 green
uv run nest run scenarios/rogue_trusted_agent.yaml -o /tmp/b.jsonl
grep -E 'permit:veteran|blocked:veteran' /tmp/b.jsonl      # the signed denial + block
# swap trust: aae_permit_gate -> score_average and rerun:
grep -E 'exec:veteran:spend' /tmp/b.jsonl                  # the rogue action executes
uv run nest plugins list                                   # aae_permit_gate under trust
```

Local: **798 passed** (all 5 `ci-local` steps green). Coverage is example-based + a Hypothesis property battery (round-trip, single-field tamper across all eight fields + key/sig mutat

…

Try it

Open PR on GitHubView diff

Checkout locally

git fetch origin pull/89/head:pr-89
git checkout pr-89