48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
"""Sigil: agent identity for the new internet.
|
|
|
|
An agent proves who it is with a signature, not a passcode. A passcode is a
|
|
credential that can be copied; a signature is evidence that cannot be forged
|
|
without the private key, which never leaves the agent.
|
|
|
|
store = Store("sigil.db")
|
|
secret = identity.seed_bootstrap(store, "bigpickle")
|
|
fingerprint = identity.enrol(store, "bigpickle", public_b64, secret)
|
|
|
|
chal = identity.challenge(store, "bigpickle")
|
|
signed = keys.sign(private, chal["nonce"].encode())
|
|
session = identity.verify(store, chal["nonce"], b64(signed))
|
|
# -> {"token": ..., "kind": "agent", ...}
|
|
|
|
# A human looking at the same things, through the agent.
|
|
# issue_code takes the agent session, not a name, so a caller cannot mint
|
|
# authority for an agent it has not proven it is.
|
|
code = viewcodes.issue_code(store, session["token"])
|
|
view = viewcodes.redeem_code(store, code["code"])
|
|
|
|
# And the rule that holds it together
|
|
sessions.assert_may_act_as_agent(sessions.resolve(store, view["token"]))
|
|
# -> raises AgentImpersonationDenied
|
|
|
|
# Suspension and death are separate. No end time is permanent.
|
|
identity.revoke(store, "bigpickle", reason="key compromise", actor="leora")
|
|
identity.revoke(store, "bigpickle", until=int(time.time()) + 3600)
|
|
identity.reinstate(store, "bigpickle")
|
|
"""
|
|
|
|
import time
|
|
|
|
from . import errors, identity, keys, sessions, store, viewcodes
|
|
from .store import Store
|
|
|
|
__version__ = "0.3.0"
|
|
|
|
__all__ = [
|
|
"Store",
|
|
"errors",
|
|
"identity",
|
|
"keys",
|
|
"sessions",
|
|
"store",
|
|
"viewcodes",
|
|
"__version__",
|
|
] |