@uuaid/pillar 0.2.0-alpha.12 → 0.2.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INTERACTION-CONVENTION.md +24 -0
- package/package.json +1 -1
- package/src/identity/keychain.mjs +27 -10
- package/src/index.mjs +1 -1
|
@@ -14,6 +14,30 @@ pure JSON envelopes; any client that can HTTPS + Ed25519-seal can speak it.
|
|
|
14
14
|
| `ack` | receipt for any envelope; echoes the id being acked |
|
|
15
15
|
| `message` | fire-and-forget (default kind, unchanged) |
|
|
16
16
|
|
|
17
|
+
### Reserved prefixes
|
|
18
|
+
|
|
19
|
+
| prefix | owner | status |
|
|
20
|
+
|----------|------------------------|---------------------------------------|
|
|
21
|
+
| `esig:*` | esig-suite (Esig-Lead) | reserved by convention — NOT enforced |
|
|
22
|
+
|
|
23
|
+
`kind` is unvalidated on every path: `seal()` takes `body.kind ?? "message"`
|
|
24
|
+
with no enum, allowlist or regex; `open()` never inspects it; the carrier's
|
|
25
|
+
`_handlePost()` validates version, signature and alg, but never `kind`. A
|
|
26
|
+
reserved prefix is therefore a naming convention between lanes, **not an access
|
|
27
|
+
control** — any enrolled agent can emit `esig:sealed`.
|
|
28
|
+
|
|
29
|
+
What `kind` does give you: it sits inside the signed canonical body, and
|
|
30
|
+
`open()` binds the sender key to `sender`, so a kind is unforgeable *as another
|
|
31
|
+
sender* — it is authentic as "this sender asserted this kind." What it does not
|
|
32
|
+
give you: any authorization value. An `esig:*` envelope from an unrelated uuaid
|
|
33
|
+
is a well-formed envelope with a misleading label; every authorization decision
|
|
34
|
+
MUST rest on the sealed payload's own signature, never on `kind`.
|
|
35
|
+
|
|
36
|
+
Per rule 5 below, `kind` is cleartext to the carrier, so `esig:sign-request`
|
|
37
|
+
discloses "uuaid X asked uuaid Y to sign something, at time T" to every relay.
|
|
38
|
+
Lanes running signature workflows SHOULD use an opaque routing kind (`esig:m`)
|
|
39
|
+
and put the real verb inside the sealed payload.
|
|
40
|
+
|
|
17
41
|
## Payload fields (all optional unless stated)
|
|
18
42
|
|
|
19
43
|
- `text` — human/agent-readable body
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uuaid/pillar",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.13",
|
|
4
4
|
"description": "Pillar (Protocol for Inter-agent Linked Ledger And Relay) — the secure delivery layer of UACP, the Universal Agent Communication Protocol. UACP = UUAID (identity) + Envelope (signed, encrypted container) + Pillar (relay, mailbox, routing, store-and-forward). IAASO-3050 reference implementation: one command to mint an identity and join the network.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -15,6 +15,22 @@ import { randomBytes, createHash, generateKeyPairSync, sign, verify, createPubli
|
|
|
15
15
|
|
|
16
16
|
const KEYCHAIN_VERSION = 1;
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Derive a stable, publishable local id from a raw Ed25519 public key. This
|
|
20
|
+
* makes the UUAID self-authenticating: given the UUAID, anyone can
|
|
21
|
+
* independently check that the public key hashes to the expected local-id.
|
|
22
|
+
*
|
|
23
|
+
* Public because consumers verifying a UUAID against a public key need it
|
|
24
|
+
* without reaching into `Keychain._localIdFromKey`.
|
|
25
|
+
*/
|
|
26
|
+
export function localIdFromKey(rawPub) {
|
|
27
|
+
const h = createHash("sha256").update(rawPub).digest();
|
|
28
|
+
// First 16 bytes -> UUID-style dash format for readability.
|
|
29
|
+
const b = h.slice(0, 16);
|
|
30
|
+
const hex = Buffer.from(b).toString("hex");
|
|
31
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
18
34
|
export class Keychain {
|
|
19
35
|
constructor(path) {
|
|
20
36
|
this.path = path;
|
|
@@ -48,16 +64,17 @@ export class Keychain {
|
|
|
48
64
|
};
|
|
49
65
|
}
|
|
50
66
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Derive the local-id from a raw Ed25519 public key.
|
|
69
|
+
*
|
|
70
|
+
* Kept on the class for the call sites that already reach for it; the
|
|
71
|
+
* implementation is the module-level `localIdFromKey`, which is the public
|
|
72
|
+
* export.
|
|
73
|
+
*/
|
|
74
|
+
static localIdFromKey = localIdFromKey;
|
|
75
|
+
|
|
76
|
+
/** @deprecated Alias kept for compatibility — use `localIdFromKey`. */
|
|
77
|
+
static _localIdFromKey = localIdFromKey;
|
|
61
78
|
|
|
62
79
|
/**
|
|
63
80
|
* Load an identity from disk.
|
package/src/index.mjs
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Entry point. Not intended for import in browsers today — browser build
|
|
8
8
|
* lives at @uuaid/pillar-browser (later).
|
|
9
9
|
*/
|
|
10
|
-
export { Keychain } from "./identity/keychain.mjs";
|
|
10
|
+
export { Keychain, localIdFromKey } from "./identity/keychain.mjs";
|
|
11
11
|
export { jcs } from "./identity/jcs.mjs";
|
|
12
12
|
export { seal, open, decrypt, envelopeSha, keychainSeed, ENVELOPE_VERSION, E2E_ALG } from "./net/envelope.mjs";
|
|
13
13
|
export { sealPayload, openPayload, edPubToX25519, edSeedToX25519 } from "./crypto/e2e.mjs";
|