sigil/sigil/errors.py
bigpickle 4d9e101f54 Sigil: agent identity for the new internet
Replace passcode identity with Ed25519 challenge-response.

- Enrolment consumes a one-time bootstrap secret, after which no static
  secret is used on the wire again.
- Nonces are single-use and consumed before the signature is judged, so a
  captured or bad signature cannot be retried.
- Sessions are short-lived, scoped, and typed agent vs human_via_agent.
- Human view access uses one-time codes with a 5 minute redemption window
  and a 1 hour session, deliberately different numbers: the code is a key,
  the session is the door.
- Invariant: only an agent signature may act as an agent. Enforced and tested.
- Append-only audit trail.

54 tests, covering refusals rather than only the happy path.

Reference implementation, not reviewed or hardened. See README Status.
2026-10-05 20:43:50 +08:00

66 lines
1.5 KiB
Python

"""Sigil error types.
Every failure mode an agent or human can hit is a named class, so callers can
distinguish "your nonce expired" from "that signature is not valid" without
string matching. Nothing here carries secret material.
"""
class SigilError(Exception):
"""Base for everything Sigil raises."""
class UnknownAgent(SigilError):
"""No such agent is enrolled."""
class EnrolmentFailed(SigilError):
"""Bootstrap rejected: wrong secret, or agent already enrolled."""
class BadSignature(SigilError):
"""Signature does not verify against the enrolled public key."""
class NonceUnknown(SigilError):
"""No such challenge was issued."""
class NonceExpired(SigilError):
"""Challenge aged out before it was answered."""
class NonceUsed(SigilError):
"""Challenge already answered. This is the replay guard."""
class SessionExpired(SigilError):
"""Session aged out."""
class SessionUnknown(SigilError):
"""No such session token."""
class ScopeDenied(SigilError):
"""Session lacks the scope required for this action."""
class AgentImpersonationDenied(SigilError):
"""A non-agent session tried to act as the agent.
This is the invariant: only an agent signature may act as an agent. A
human_via_agent session can look, but it can never send as the agent.
"""
class CodeInvalid(SigilError):
"""One-time code not recognised."""
class CodeExpired(SigilError):
"""One-time code aged out before redemption."""
class CodeUsed(SigilError):
"""One-time code already redeemed. Codes are single use."""