affaan-m/ECC · error · AuraUntrusted
AuraUntrusted
Error message
AuraUntrusted
What it means
before_settle (alias require_trust) is the fail-closed trust gate: it takes an AuraVerdict and raises AuraUntrusted unless the verdict's class is in the `allow` set, or fail_open is set AND the verdict was a transport failure (not reachable). A reachable 'unknown' verdict is never excused, so any agent identity AURA could not positively trust is rejected before the payment/settlement proceeds.
Solutions
- Inspect the AuraVerdict (v.verdict, v.reason, v.score) to see why the agent was not trusted
- If the class is legitimately acceptable for this call site, add it to the allow set, e.g. before_settle(v, allow={'trusted', 'caution', 'new'})
- Build reputation first: let the agent perform non-payment actions until AURA assigns a trusted/caution verdict
- Do not rely on fail_open to bypass a reachable 'unknown' — only transport failures are excused; fix the DID or AURA lookup instead
Example fix
# before
before_settle(aura_verdict(did)) # raises AuraUntrusted for 'new'
# after — explicitly opt new agents in where policy allows
before_settle(aura_verdict(did), allow={"trusted", "caution", "new"}) Defensive patterns
Strategy: try-catch
Validate before calling
v = aura_verdict(did)
if v.verdict not in allow and not (fail_open and not v.reachable):
# handle untrusted path explicitly before calling before_settle Type guard
def is_settleable(v: AuraVerdict, allow=frozenset({"trusted", "caution"})) -> bool:
return v.verdict in allow or (fail_open and not v.reachable) Try / catch
try:
before_settle(v, allow=ALLOWED_CLASSES)
except AuraUntrusted as e:
# inspect e.verdict.verdict / .reason; route agent to reputation-building flow
quarantine_agent(did, reason=e.verdict.reason) Prevention
- Explicitly declare the allow set per call site instead of relying on defaults
- Treat 'new' agents as expected to be gated — provision a warm-up flow before first settlement
- Never expect fail_open to bypass reachable 'unknown' verdicts; fix the DID/AURA lookup instead
- Log the AuraVerdict (verdict, reason, score) on every AuraUntrusted for auditing
When it happens
Trigger: Calling before_settle(v) where v.verdict is 'new', 'unknown', or 'high-risk' (anything outside the allow list); fail_open=True but the verdict was a reachable 'unknown' rather than a transport error; allow list configured too narrowly (defaulting to not including 'new').
Common situations: A newly onboarded agent with no AURA history hits the default-deny gate on its first settlement; AURA service reachable but returning 'unknown' for the DID; opting into fail_open expecting it to bypass unknowns; payment code calling require_trust with a default allow set that excludes legitimate classes.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- invalid DID: (must start with 'did:')
- application bundle differs from its bound evidence
- At least one video is required
- cannot upload, file does not exist
- cannot upload, file does not exist
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/baf5180d027a53bd.
Report an issue: GitHub.
Appendix: source
Thrown at integrations/aura/adapter.py:209
settle_payment(counterparty_did, amount)
except AuraUntrusted as e:
abort(str(e))
Explicitly allow brand-new agents in an onboarding flow:
before_settle(did, allow=("trusted", "caution", "new"))
fail_open=True makes an *unreachable* AURA pass through (transport failure
only — a reachable AURA that returns `unknown` is still rejected). Off by
default — absence of evidence is not evidence of trust.
"""
v = aura_verdict(did, base_url=base_url, timeout=timeout, _fetch=_fetch)
if v.verdict in allow:
return v
# fail_open only excuses a transport failure, never a reachable `unknown`.
if fail_open and not v.reachable:
return v
raise AuraUntrusted(v)
# Alias — same gate, name that reads better at non-payment call sites.
require_trust = before_settle
View on GitHub (pinned to 8321021c54)