MAS-WP-0011 finished: peer authentication in mode contract v0.1
CONTRACT.md section 7 (founder-reviewed): pairwise HMAC-SHA256 over TIMESTAMP.BODY in MAS-Modes-* headers, 300 s window; master commands only from the configured master; statuses only at the handoff's tokenized URL from its peer; primed webhooks must name a known peer. mas_modes.signing, signed contract.post, authenticating json_server, EmailMode/stubs/gateway signing. conformance/auth.json vectors + 7 authorization flows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 5787@bnt-lap001 Assistant-Session: 5db26b82-138b-40cc-9856-4d5eb0f752fd
This commit is contained in:
parent
2bc41a3318
commit
bdf200a600
25 changed files with 1603 additions and 151 deletions
|
|
@ -19,23 +19,29 @@ how stable each part is.
|
|||
|
||||
## Integrating as an outside master
|
||||
|
||||
Configure the resource type as `slave` (`mas_modes.email_mode.RoleConfig`)
|
||||
and point `master_url` at your system. You then:
|
||||
Configure the resource type as `slave` (`mas_modes.email_mode.RoleConfig`),
|
||||
point `master_url` at your system, set `master_peer` to your peer id, and
|
||||
exchange a key with the email operator. Every request in both directions is
|
||||
signed (CONTRACT.md section 7; `mas_modes.signing`, standard library only).
|
||||
You then:
|
||||
|
||||
- receive `case.intake` and `case.message`, each carrying a gateway event;
|
||||
- answer `case.assign` with your own case id; email adopts it as
|
||||
`TYPE=ID@domain`;
|
||||
- send replies with `mail.send` (`in_reply_to` a recorded message);
|
||||
principle 10 can refuse them;
|
||||
- decide per case on `autonomous_send` and `transfers` (`block`, or your
|
||||
mode webhook);
|
||||
- decide per case on `autonomous_send` and `transfers`: `block`, or a
|
||||
mode webhook with that mode's `peer`. The peer must be one the email
|
||||
operator has a key for;
|
||||
- own every timeout; end a handoff with `handoff.cancel`.
|
||||
|
||||
## Integrating a mode
|
||||
|
||||
Implement the mode endpoint in CONTRACT.md: accept `handoff.request`,
|
||||
`handoff.update` and `handoff.cancel`, and post `handoff.status` to
|
||||
`status_url` with an increasing `seq`. Never send `timed-out`.
|
||||
`handoff.update` and `handoff.cancel` only when signed by email, and post
|
||||
`handoff.status`, signed with your peer id, to exactly the `status_url` of
|
||||
that handoff (it carries a per-handoff token), with an increasing `seq`.
|
||||
Never send `timed-out`.
|
||||
`mas_modes/stubs/callback.py` is a complete example.
|
||||
|
||||
## Examples only, not products
|
||||
|
|
@ -44,6 +50,7 @@ Implement the mode endpoint in CONTRACT.md: accept `handoff.request`,
|
|||
store for email-mastered cases.
|
||||
- `mas_modes/stubs/`: the callback stub and the stub outside master.
|
||||
They never contact a person or a service.
|
||||
- `mas_modes/email_mode.py`: the reference email side. It is
|
||||
single-process, with SQLite and no authentication on its HTTP endpoints,
|
||||
so it is fit for loopback and tests. The contract is the interface.
|
||||
- `mas_modes/email_mode.py`: the reference email side. It authenticates
|
||||
every peer (section 7), but it is single-process with SQLite, has no key
|
||||
rotation, and serves plain HTTP. Put it behind TLS before exposing it
|
||||
beyond loopback. The contract is the interface.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue