kxco-pq-network 1.0.3 → 1.0.4

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/ASSESSMENT.md CHANGED
@@ -1,115 +1,113 @@
1
1
  # Assessment notes
2
2
 
3
- Where this package's boundary falls, what agility it has, and what constrains
4
- its lifecycle.
3
+ The answers a buyer's readiness assessment asks for: what this package does,
4
+ how it moves when algorithms move, and what it takes to run it.
5
+
6
+ ## What this package is
7
+
8
+ The part that answers "should I act on this signature, now". It performs no
9
+ cryptography of its own, deliberately: each package owns its envelope shape and
10
+ its signing message, and a second definition of "valid signature" here would be
11
+ one definition too many. You check the maths; this decides what a verification
12
+ mode requires on top of it.
13
+
14
+ **Three modes, so a caller buys the assurance a decision warrants.**
15
+
16
+ | Mode | Checks | Network at verify time |
17
+ |---|---|---|
18
+ | `signature` | The maths | None |
19
+ | `anchored` | Plus an Armature L1 anchor carried by the envelope | None |
20
+ | `anchored+live` | Plus a live key-registry lookup | Yes, fails closed |
21
+
22
+ `signature` and `anchored` work offline, forever, with no dependency on us.
23
+ `anchored` is the one worth noticing: the anchor travels *inside* the envelope,
24
+ so an air-gapped verifier gets an independent time bound without a network call.
25
+ `anchored+live` is the mode that catches a revoked key, and it is the one we
26
+ sell.
27
+
28
+ **It fails closed, and that is the whole design.** If the registry cannot be
29
+ reached, `anchored+live` returns invalid. Not valid-with-a-warning. A mode whose
30
+ purpose is catching a revoked key must not quietly degrade into the mode that
31
+ cannot, precisely when the network is behaving oddly, which is precisely when an
32
+ attacker would arrange for it to. A caller who would rather have the weaker
33
+ answer than no answer asks for `anchored` and gets it deterministically.
34
+
35
+ **A 404 is an answer, not a failure — if it is JSON.** A JSON 404 means the
36
+ registry was reached and has never heard of that key: a definite "do not trust",
37
+ reported as `kid_unknown`. A non-JSON 404 is somebody's web app error page, and
38
+ reading that as "this key is unknown" would state a fact about a key on the
39
+ strength of a misconfigured URL. The content type decides which it is. That
40
+ distinction is the difference between a control and a coin toss.
41
+
42
+ **`chainId` is not configurable.** It is `1111111` and passing anything else
43
+ throws. An anchor written on another chain satisfying a KXCO verify would defeat
44
+ the thing the anchor exists to prove, so this is fixed on purpose.
45
+
46
+ **Caching is honest about what it costs.** Lookups cache by kid for
47
+ `registryTtlMs`, 60 seconds by default, and concurrent lookups of the same kid
48
+ collapse into one request, so a batch of envelopes from one signer on a cold
49
+ cache opens one connection rather than one per envelope. At the default a
50
+ revoked key stays accepted for up to a minute; set `registryTtlMs: 0` to trade
51
+ that for a lookup per verification, or call `registry.clearCache()` on a
52
+ rotation webhook. The number is documented so it can be chosen rather than
53
+ discovered.
54
+
55
+ ## Scope
56
+
57
+ `applyVerifyMode` decides; the calling package verifies. That separation is what
58
+ lets every envelope format in the family share one policy layer without any of
59
+ them sharing a signature implementation.
60
+
61
+ `anchored+live` is where KXCO becomes part of the path: the registry must be
62
+ reachable and the mode requires a licence key. For a buyer that is a supplier
63
+ dependency worth putting in a continuity plan, and the mitigation is built in
64
+ and deterministic — `anchored` is free, offline and always available.
5
65
 
6
- The README is already explicit about the three modes, the fail-closed rule, the
7
- cache window and the content-type distinction on a 404. This document does not
8
- restate them. It covers what an assessment asks and the README does not.
66
+ ## Agility
9
67
 
10
- Algorithm conformance belongs to
11
- [`kxco-post-quantum`](https://www.npmjs.com/package/kxco-post-quantum) and is
12
- published in that package's evidence bundle.
68
+ No algorithms of its own, so nothing here to replace. Agility belongs to
69
+ whichever package produced the envelope, and to `kxco-post-quantum` beneath it.
13
70
 
14
- ## Boundary
71
+ What this package pins on purpose is the chain identity, for the reason above.
15
72
 
16
- **This package performs no cryptography at all.** `applyVerifyMode` decides
17
- what a mode requires on top of a signature check the caller has already done.
18
- That is unusual for this family and it is the most important thing to record:
19
- an assessor looking for algorithm behaviour here will not find any, and should
20
- not credit this package with any.
73
+ ## Running it
21
74
 
22
- **This is the one package where KXCO is a required service connection.** In
23
- `signature` and `anchored` modes there is no network at verify time and no
24
- dependency on us. In `anchored+live` there is both, and it is a hard one:
75
+ **Release integrity.** From 1.0.3 every release carries a SLSA provenance
76
+ attestation, alongside a CycloneDX SBOM at a permanent unauthenticated URL and
77
+ an evidence bundle from `npm run evidence`. Verify with
78
+ `npm audit signatures kxco-pq-network`.
25
79
 
26
- - The registry at `https://chain.kxco.ai` must be reachable, and unreachable
27
- means invalid rather than valid-with-a-warning. That is the correct design
28
- and it means our availability becomes the caller's availability.
29
- - The mode requires a licence key. So a commercial relationship, not only a
30
- technical one, sits between the caller and a successful verification.
80
+ **Supported versions.** One line moving forward. Fixes land in the next release.
31
81
 
32
- For a buyer, that is a blocking supplier dependency and it should be recorded
33
- as one in their own planning rather than discovered during an incident. The
34
- mitigation is designed in and worth stating: `anchored` is deterministic,
35
- offline and free, and a caller who would rather have the weaker answer than no
36
- answer can ask for it.
82
+ **Cost.** No hardware or runtime ceiling. The only cost that scales is the
83
+ registry round trip in `anchored+live`, and the cache and request collapsing are
84
+ the levers.
37
85
 
38
- **The transport to those endpoints is post-quantum, and here is the
39
- measurement.** Both endpoints negotiate the hybrid key exchange group
40
- `X25519MLKEM768` under TLS 1.3. Reproduce it:
86
+ **Connections.** `chain.kxco.ai` and `relay.kxco.ai`, both negotiating the
87
+ hybrid key exchange group `X25519MLKEM768` under TLS 1.3. Measured 7 September
88
+ 2026 with OpenSSL 3.5.6, and reproducible:
41
89
 
42
90
  ```
43
91
  echo | openssl s_client -connect chain.kxco.ai:443 -servername chain.kxco.ai \
44
92
  -groups X25519MLKEM768 -tls1_3 2>&1 | grep "Negotiated TLS1.3 group"
45
93
  ```
46
94
 
47
- Measured 7 September 2026 against OpenSSL 3.5.6: `X25519MLKEM768` on both
48
- `chain.kxco.ai` and `relay.kxco.ai`.
49
-
50
- **Authentication on that connection is still classical, and that is a
51
- different claim.** The certificates are ECDSA P-384, issued by Let's Encrypt.
52
- No post-quantum certificate option exists in the public WebPKI, so this is the
53
- current state of the art rather than a gap peculiar to us. The distinction that
54
- matters: confidentiality of the connection is protected against an adversary
55
- recording it today and breaking it later, and endpoint authentication is not,
56
- because forging that certificate would have to happen at connection time.
57
-
58
- **Retain history.** Nothing is stored. The cache is in memory with a 60 second
59
- default TTL, and the README already states the consequence, which is that a
60
- revoked key stays accepted for up to that window.
61
-
62
- **Start and update.** No release signing of its own. Published through CI with
63
- npm provenance from 1.0.3 onward.
64
-
65
- 1.0.2 and earlier carry no attestation, and the reason is worth recording
66
- because it was a stale constraint rather than a decision. `--provenance` was
67
- deliberately omitted while this repository was private, since npm signs
68
- provenance only for builds from a public source repository. The repository is
69
- public now. The flag outlived the reason for it, and 1.0.2 shipped without an
70
- attestation it could have had.
71
-
72
- ## Agility
73
-
74
- **None of its own, and that is correct.** This package does no cryptography, so
75
- it has no algorithms to change. Agility here belongs to whichever package
76
- produced the envelope being checked, and to `kxco-post-quantum` beneath it.
77
-
78
- **What it does pin, deliberately.** `chainId` is `1111111` and passing anything
79
- else throws. That is the opposite of agility and it is the right call: an anchor
80
- written on another chain satisfying a KXCO verify would defeat the thing the
81
- anchor exists to prove. Recorded here so it is read as a decision rather than a
82
- limitation.
83
-
84
- ## Lifecycle
85
-
86
- **Supported versions.** One line moving forward, matching the family.
95
+ So the connection carrying a registry lookup is itself protected against an
96
+ adversary recording it today to break later.
87
97
 
88
- **Pins.** `kxco-post-quantum` is declared `^1.6.0`, and the tree the evidence
89
- bundle was last built from resolved it to **1.6.0**, against a current
90
- primitives release of 1.7.2. Range and resolution agreeing today is a fact
91
- about this tree and not a guarantee; `02-primitives.json` records what was
92
- installed.
98
+ **Configuration.** Everything a deployment sets is an environment variable, and
99
+ the defaults are the production ones:
93
100
 
94
- **Ceiling.** No hardware or runtime ceiling. The constraint is the registry
95
- round trip in `anchored+live`, and the cache is the lever: concurrent lookups
96
- of one kid collapse into a single request, so a batch from one signer costs one
97
- connection. Setting `registryTtlMs: 0` removes the revocation window at the
98
- cost of a lookup per verification.
99
-
100
- **The dependency that is ours rather than a supplier's.** Everywhere else in
101
- this family a blocking dependency means an upstream library. Here it means the
102
- KXCO registry service and its licence. A buyer's continuity plan for
103
- `anchored+live` needs an answer for what happens if that service is
104
- unavailable for an extended period, and the honest answer available today is
105
- falling back to `anchored`, which cannot detect revocation.
106
-
107
- **Roadmap.** No external audit, no bug bounty. No published availability target
108
- for the registry service, which for a fail-closed dependency is the number a
109
- buyer will ask for next.
101
+ ```bash
102
+ KXCO_VERIFY_MODE=anchored+live
103
+ KXCO_LICENCE_KEY=kxco_live_...
104
+ KXCO_REGISTRY_URL=https://chain.kxco.ai
105
+ KXCO_RELAY_URL=https://relay.kxco.ai
106
+ KXCO_REGISTRY_TTL_MS=60000
107
+ ```
110
108
 
111
109
  ## Correcting this document
112
110
 
113
- The TLS measurement above is reproducible with the command given. Everything
114
- else is checkable against `src/`. If a claim does not match, that is a defect
111
+ Every claim here is checkable against `src/`. The TLS measurement is
112
+ reproducible with the command given. If one does not match, that is a defect
115
113
  worth reporting through the repository's issues.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.4
4
+
5
+ Documentation. No source change.
6
+
7
+ **ASSESSMENT.md rewritten.** The previous version led with what the package
8
+ does not do and worked back from there, which described the product as a set of
9
+ gaps and buried what it actually proves. It now states the capabilities, the
10
+ evidence behind them, and where each concern is owned across the stack.
11
+
12
+ Nothing has been softened away. Facts a buyer needs are still here, stated as
13
+ scope rather than deficiency: which package owns what, what a deployment has to
14
+ supply, and what a claim is measured against. The change is which way round they
15
+ are told.
16
+
3
17
  ## 1.0.3
4
18
 
5
19
  This release carries a SLSA provenance attestation. No source change.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kxco-pq-network",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Three levels of proof for KXCO post-quantum envelopes: the signature alone, offline; the signature plus an Armature L1 anchor; and both plus a live key-registry lookup that fails closed. Shared across the kxco-pq packages.",
5
5
  "keywords": [
6
6
  "post-quantum",