kxco-pq-network 1.0.2 → 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 +91 -86
- package/CHANGELOG.md +29 -0
- package/README.md +6 -1
- package/package.json +1 -1
package/ASSESSMENT.md
CHANGED
|
@@ -1,108 +1,113 @@
|
|
|
1
1
|
# Assessment notes
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
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
|
-
|
|
11
|
-
|
|
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
|
-
|
|
71
|
+
What this package pins on purpose is the chain identity, for the reason above.
|
|
15
72
|
|
|
16
|
-
|
|
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
|
-
**
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
**
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
48
|
-
|
|
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.
|
|
64
|
-
|
|
65
|
-
## Agility
|
|
66
|
-
|
|
67
|
-
**None of its own, and that is correct.** This package does no cryptography, so
|
|
68
|
-
it has no algorithms to change. Agility here belongs to whichever package
|
|
69
|
-
produced the envelope being checked, and to `kxco-post-quantum` beneath it.
|
|
95
|
+
So the connection carrying a registry lookup is itself protected against an
|
|
96
|
+
adversary recording it today to break later.
|
|
70
97
|
|
|
71
|
-
**
|
|
72
|
-
|
|
73
|
-
written on another chain satisfying a KXCO verify would defeat the thing the
|
|
74
|
-
anchor exists to prove. Recorded here so it is read as a decision rather than a
|
|
75
|
-
limitation.
|
|
98
|
+
**Configuration.** Everything a deployment sets is an environment variable, and
|
|
99
|
+
the defaults are the production ones:
|
|
76
100
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
about this tree and not a guarantee; `02-primitives.json` records what was
|
|
85
|
-
installed.
|
|
86
|
-
|
|
87
|
-
**Ceiling.** No hardware or runtime ceiling. The constraint is the registry
|
|
88
|
-
round trip in `anchored+live`, and the cache is the lever: concurrent lookups
|
|
89
|
-
of one kid collapse into a single request, so a batch from one signer costs one
|
|
90
|
-
connection. Setting `registryTtlMs: 0` removes the revocation window at the
|
|
91
|
-
cost of a lookup per verification.
|
|
92
|
-
|
|
93
|
-
**The dependency that is ours rather than a supplier's.** Everywhere else in
|
|
94
|
-
this family a blocking dependency means an upstream library. Here it means the
|
|
95
|
-
KXCO registry service and its licence. A buyer's continuity plan for
|
|
96
|
-
`anchored+live` needs an answer for what happens if that service is
|
|
97
|
-
unavailable for an extended period, and the honest answer available today is
|
|
98
|
-
falling back to `anchored`, which cannot detect revocation.
|
|
99
|
-
|
|
100
|
-
**Roadmap.** No external audit, no bug bounty. No published availability target
|
|
101
|
-
for the registry service, which for a fail-closed dependency is the number a
|
|
102
|
-
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
|
+
```
|
|
103
108
|
|
|
104
109
|
## Correcting this document
|
|
105
110
|
|
|
106
|
-
|
|
107
|
-
|
|
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
|
|
108
113
|
worth reporting through the repository's issues.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
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
|
+
|
|
17
|
+
## 1.0.3
|
|
18
|
+
|
|
19
|
+
This release carries a SLSA provenance attestation. No source change.
|
|
20
|
+
|
|
21
|
+
**`--provenance` is back on.** It was deliberately omitted while this repository
|
|
22
|
+
was private, because npm signs provenance only for builds from a public source
|
|
23
|
+
repository and a private one is refused with `E422 ... Unsupported GitHub
|
|
24
|
+
Actions source repository visibility`. The repository is public now, so the
|
|
25
|
+
constraint is gone. The flag outlived the reason for it, and 1.0.2 shipped
|
|
26
|
+
without an attestation it could have had.
|
|
27
|
+
|
|
28
|
+
Verify it with `npm audit signatures kxco-pq-network`. Until now the README
|
|
29
|
+
pointed at `kxco-post-quantum` for the provenance claim, because that was the
|
|
30
|
+
only package in the pair that could make it. This one makes its own from here.
|
|
31
|
+
|
|
3
32
|
## 1.0.2
|
|
4
33
|
|
|
5
34
|
Documentation and a dependency refresh. No source change.
|
package/README.md
CHANGED
|
@@ -160,7 +160,12 @@ base package's, and it is reproducible on your own machine:
|
|
|
160
160
|
- **2,103 NIST ACVP vectors: 1,793 passed, 0 failed, 310 skipped** across FIPS 203, 204 and 205, pinned by digest
|
|
161
161
|
- **225 interoperability checks passed, 0 failed, 42 not applicable** against OpenSSL 3.5, liboqs, Bouncy Castle and dilithium-py/kyber-py, in both directions and with negative controls
|
|
162
162
|
- **SLSA provenance** on every [`kxco-post-quantum`](https://www.npmjs.com/package/kxco-post-quantum) release — verify with `npm audit signatures kxco-post-quantum`
|
|
163
|
-
|
|
163
|
+
|
|
164
|
+
This package carries its own evidence too, and from 1.0.3 its own attestation:
|
|
165
|
+
|
|
166
|
+
- **SLSA provenance on this package**, from 1.0.3 onward — verify with `npm audit signatures kxco-pq-network`
|
|
167
|
+
- `npm run evidence` here records what only this package can say: identity, its own tests, its SBOM, registry signature verification, and the `kxco-post-quantum` version actually installed rather than the range declared
|
|
168
|
+
- `npm run evidence` in the base package regenerates the conformance bundle from source
|
|
164
169
|
|
|
165
170
|
Third-party dependencies here are pinned to exact versions, never ranges, so the
|
|
166
171
|
code that performs the cryptography cannot change without a release.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kxco-pq-network",
|
|
3
|
-
"version": "1.0.
|
|
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",
|