mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 09:21:35 +00:00
docs(plugin-sdk): document sender authentication strength types
Adds a channel-ingress guide section for the two newly public SDK types (IdentifierAuthentication, SubjectIdentifierAuthentication): the graded scale, entry vs per-message claims, the min(entry, subject) gate, and the dangerous/mutableIdentifierMatching compatibility mapping. Addresses the ClawSweeper P2 on openclaw#117121. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7666,6 +7666,8 @@ Do not edit it by hand; run `pnpm docs:map:gen`.
|
||||
- Headings:
|
||||
- H2: Runtime resolver
|
||||
- H2: Result
|
||||
- H2: Sender authentication strength
|
||||
- H3: Compatibility
|
||||
- H2: Access groups
|
||||
- H2: Event modes
|
||||
- H2: Routes and activation
|
||||
|
||||
@@ -74,6 +74,73 @@ Deprecated third-party SDK helpers may rebuild older shapes internally. New
|
||||
bundled receive paths should not translate modern results back into local
|
||||
DTOs.
|
||||
|
||||
## Sender authentication strength
|
||||
|
||||
`IdentifierAuthentication` grades how strongly an identifier proves its holder,
|
||||
as an ordered scale (strongest first):
|
||||
|
||||
| Value | Meaning |
|
||||
| ------------ | --------------------------------------------------------------- |
|
||||
| `verified` | a transport fact proves the holder for this identifier |
|
||||
| `asserted` | a session-authenticated transport vouches for it (the default) |
|
||||
| `unverified` | an alias two senders could hold at once, such as a display name |
|
||||
| `mutable` | exact and stable, but this message did not prove its ownership |
|
||||
|
||||
Two independent claims feed the gate:
|
||||
|
||||
- **Entry side** (static): `ChannelIngressIdentityField.authentication`, how
|
||||
strongly a field names its holder. Omitted means `asserted`; declare
|
||||
`verified` only with a transport fact behind it.
|
||||
- **Subject side** (per message): `subject.authentication`, a map keyed like
|
||||
`subject.aliases` (with `stableId` under the primary field key) of what _this
|
||||
message_ proved. Supply it only from a transport that authenticates messages
|
||||
rather than sessions; omitting it weakens nothing. Resolved state exposes it
|
||||
as `SubjectIdentifierAuthentication`.
|
||||
|
||||
The gate takes `min(entry, subject)` per identifier kind and compares it to
|
||||
`policy.minIdentifierAuthentication` (default `asserted`). An unforgeable
|
||||
identifier proves nothing when its message was never authenticated; an
|
||||
authenticated message proves nothing when the identifier it carries is an alias.
|
||||
|
||||
```ts
|
||||
const identity = defineStableChannelIngressIdentity({
|
||||
key: "email",
|
||||
normalize: normalizeEmail,
|
||||
sensitivity: "pii",
|
||||
authentication: "verified", // the address exactly names its holder…
|
||||
});
|
||||
|
||||
const result = await resolveChannelMessageIngress({
|
||||
// …but a given message only proves that when it arrives DKIM-aligned.
|
||||
identity,
|
||||
subject: {
|
||||
stableId: fromAddress,
|
||||
authentication: { email: dkimAligned ? "verified" : "unverified" },
|
||||
},
|
||||
policy: { dmPolicy, groupPolicy, minIdentifierAuthentication: "verified" },
|
||||
// …
|
||||
});
|
||||
```
|
||||
|
||||
Silence caps an entry at `asserted`: a channel cannot satisfy a `verified`
|
||||
minimum by declaring nothing, so reaching `verified` is always an explicit claim.
|
||||
|
||||
### Compatibility
|
||||
|
||||
The scale supersedes the two-level `dangerous` / `mutableIdentifierMatching`
|
||||
boolean, which stay honored but deprecated:
|
||||
|
||||
| Legacy | Graded equivalent |
|
||||
| -------------------------------------- | ------------------ |
|
||||
| entry with no `dangerous` | `asserted` |
|
||||
| `dangerous: true` | `mutable` |
|
||||
| default policy | minimum `asserted` |
|
||||
| `mutableIdentifierMatching: "enabled"` | minimum `mutable` |
|
||||
|
||||
`asserted` clears an `asserted` minimum and `mutable` does not, so every
|
||||
existing admission and rejection is preserved. `subject.authentication` is
|
||||
optional; absent reads the same as empty.
|
||||
|
||||
## Access groups
|
||||
|
||||
`accessGroup:<name>` entries stay redacted. Core resolves static
|
||||
|
||||
Reference in New Issue
Block a user