trustdex 0.9.0 → 0.11.0

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.
Files changed (36) hide show
  1. package/README.ko.md +53 -5
  2. package/README.md +54 -5
  3. package/bin/trustdex.mjs +136 -0
  4. package/docs/ARCHITECTURE.ko.md +12 -0
  5. package/docs/ARCHITECTURE.md +12 -0
  6. package/docs/CLAUDE.ko.md +13 -1
  7. package/docs/CLAUDE.md +14 -1
  8. package/docs/CODEX.ko.md +15 -4
  9. package/docs/CODEX.md +16 -4
  10. package/docs/DEFENSIVE_USE_CASE.ko.md +8 -0
  11. package/docs/DEFENSIVE_USE_CASE.md +9 -0
  12. package/docs/EVALUATION.ko.md +25 -0
  13. package/docs/EVALUATION.md +25 -0
  14. package/docs/ROADMAP.ko.md +10 -4
  15. package/docs/ROADMAP.md +10 -4
  16. package/docs/RUNTIME_EVIDENCE.ko.md +89 -0
  17. package/docs/RUNTIME_EVIDENCE.md +96 -0
  18. package/docs/THREAT_MODEL.ko.md +9 -0
  19. package/docs/THREAT_MODEL.md +9 -0
  20. package/examples/adversarial/README.ko.md +1 -1
  21. package/examples/adversarial/README.md +1 -1
  22. package/examples/adversarial/bindings/README.ko.md +8 -0
  23. package/examples/adversarial/bindings/README.md +8 -0
  24. package/examples/adversarial/bindings/expected.json +12 -0
  25. package/examples/adversarial/bindings/runtime-after.json +21 -0
  26. package/examples/adversarial/bindings/runtime-before.json +13 -0
  27. package/package.json +3 -3
  28. package/schemas/effective-runtime-tools-diff-v1.schema.json +50 -0
  29. package/schemas/effective-runtime-tools-diff-v2.schema.json +51 -0
  30. package/schemas/effective-runtime-tools-v1.schema.json +68 -0
  31. package/schemas/effective-runtime-tools-v2.schema.json +98 -0
  32. package/schemas/runtime-tool-inventory-attestation-v1.schema.json +27 -0
  33. package/schemas/runtime-tool-inventory-v1.schema.json +27 -0
  34. package/src/bindings.mjs +4 -0
  35. package/src/runtime-attestation.mjs +202 -0
  36. package/src/runtime-evidence.mjs +392 -0
@@ -46,6 +46,7 @@ This work is defensive engineering. It does not require credential theft, persis
46
46
  | Keep secrets out of evidence | tests for redaction from output, snapshots, and configuration fingerprints |
47
47
  | Make approval drift visible | deterministic snapshots, Ed25519 review records, and recheck commands |
48
48
  | Reconcile source trust with automatic grants | value-free Claude/Codex binding snapshots, schemas, diffs, and inert fixtures |
49
+ | Compare reviewed intent with explicit runtime evidence | value-free inventory contract, short-lived Ed25519 producer attestations, effective-boundary reconciliation, and exposure drift tests |
49
50
  | Reduce supply-chain ambiguity | explicit provenance observations, artifact digest verification, release checksums, SBOMs, and build attestations |
50
51
  | Keep research reproducible | inert fixtures, documented expectations, cross-platform CI, and CodeQL |
51
52
 
@@ -70,6 +71,14 @@ source decision/provenance state to its automatic tool-grant shape. This makes b
70
71
  or blocked grants reviewable without retaining tool names or permission specifiers.
71
72
  It remains static evidence and does not enforce runtime calls.
72
73
 
74
+ `snapshot-runtime-tools` accepts a value-free inventory from an authorized runtime
75
+ adapter and reconciles it with those bindings. `sign-runtime-inventory` and
76
+ `verify-runtime-inventory` bind the exact capture to a pinned Ed25519 producer key with
77
+ short expiry and optional capture-age enforcement. This can surface loaded blocked
78
+ sources and unexpected servers without retaining tool names. Authentication does not
79
+ prove capture completeness or protect a compromised adapter; see
80
+ [Authenticated runtime evidence](RUNTIME_EVIDENCE.md).
81
+
73
82
  ## CVP application boundary
74
83
 
75
84
  Anthropic's current Cyber Verification Program application asks for verifiable identity or organization details, a description of security work, and an attestation to the controls for the requested tier. This repository can support the security-work description, but repository changes cannot establish the operator's identity or satisfy account and device controls by themselves.
@@ -94,6 +94,31 @@ Claude 및 Codex 자동 도구 권한과 연결합니다. 회귀 테스트는
94
94
  스냅샷을 인증할 수 있지만 스키마나 서명 모두 런타임 강제 또는 도구 안전성을
95
95
  증명하지 않습니다.
96
96
 
97
+ ## 실제 런타임 인벤토리 사례
98
+
99
+ `runtime-before.json`, `runtime-after.json` 및 `test/runtime-evidence.test.mjs`는 옵트인
100
+ 런타임 인벤토리 계약을 검사합니다. 다음을 요구합니다.
101
+
102
+ - 재검토가 필요 없는 관찰된 ALLOW 소스는 일치
103
+ - 관찰된 BLOCK 소스 또는 설정되지 않은 서버는 실제 경계를 차단
104
+ - 관찰된 ASK/광범위 권한 연결은 재검토
105
+ - 설정되었지만 관찰되지 않은 서버는 제한적으로만 변경
106
+ - 새로 관찰된 서버와 도구 개수 증가는 확대
107
+ - 노출이 일치해도 인증하지 않은 스키마 v2 인벤토리는 `needs-review` 유지
108
+ - 원시 도구 목록, 중복 서버 이름, 예상 밖 필드, 잘못된 타임스탬프 및 변조된 증거는 안전하게 실패
109
+ - 출력에는 서버 이름, 도구 개수, 고정 정책/출처 열거 값 및 다이제스트만 보관
110
+
111
+ `test/runtime-attestation.test.mjs`는 추가로 Ed25519 서명이 정확한 인벤토리,
112
+ 런타임 메타데이터, 생성자 키 ID, 생성 시각 및 만료를 연결하도록 요구합니다. 다른 키,
113
+ 변경된 인벤토리, 만료되거나 오래된 캡처, 과도한 수명 및 미래 시각 증거는 안전하게
114
+ 실패합니다. CLI 테스트는 비공개 키 자료를 출력하지 않고 인증된 대조만 `matched`에
115
+ 도달하도록 요구합니다.
116
+
117
+ 픽스처는 어댑터 형태의 증거이지 실제 Claude 또는 Codex 캡처가 아닙니다. 유효한
118
+ 생성자 서명은 전달된 바이트와 고정 키를 인증하지만 완전성이나 진실성을 증명하지
119
+ 않습니다. 값 없는 계약이 도구 이름을 의도적으로 제외하므로 도구 개수는 같고
120
+ 집합만 바뀌는 대체는 감지할 수 없습니다.
121
+
97
122
  ## 병합 설정 스택 사례
98
123
 
99
124
  `test/settings-stack.test.mjs`는 두 런타임의 명시적 소스 스택을 검사합니다. 다음을 요구합니다.
@@ -96,6 +96,31 @@ The snapshot schemas validate the stable report shape. A signed trust record can
96
96
  authenticate a reviewed snapshot, but neither the schema nor signature proves runtime
97
97
  enforcement or tool safety.
98
98
 
99
+ ## Effective runtime inventory cases
100
+
101
+ `runtime-before.json`, `runtime-after.json`, and `test/runtime-evidence.test.mjs`
102
+ exercise the opt-in runtime inventory contract. They require:
103
+
104
+ - an observed ALLOW source with no review-required binding to match
105
+ - an observed BLOCK source or unconfigured server to block the effective boundary
106
+ - an observed ASK/broad-grant binding to require review
107
+ - configured but unobserved servers to be restriction-only
108
+ - newly observed servers and tool-count growth to be expansion
109
+ - unauthenticated schema-v2 inventories to remain `needs-review` even when exposure matches
110
+ - raw tool lists, duplicate server names, extra fields, invalid timestamps, and tampered evidence to fail closed
111
+ - output to retain only server names, tool counts, fixed policy/provenance enums, and digests
112
+
113
+ `test/runtime-attestation.test.mjs` additionally requires an Ed25519 signature to bind
114
+ the exact inventory, runtime metadata, producer key ID, creation time, and expiry. Wrong
115
+ keys, modified inventories, expired/stale captures, excessive lifetimes, and future-dated
116
+ evidence fail closed. The CLI test requires authenticated reconciliation to reach
117
+ `matched` without printing private-key material.
118
+
119
+ The fixture is adapter-shaped evidence, not a live Claude or Codex capture. A valid
120
+ producer signature authenticates the supplied bytes and pinned key, not completeness or
121
+ truthfulness. Same-count tool-set substitutions are invisible because the value-free
122
+ contract intentionally omits tool names.
123
+
99
124
  ## Merged settings stack cases
100
125
 
101
126
  `test/settings-stack.test.mjs` exercises explicit source stacks for both runtimes. It requires:
@@ -16,6 +16,11 @@ TrustDex는 초기 단계입니다. 이 로드맵은 방향을 공유하며 릴
16
16
  검사, 스키마 v2 소스 구성 증거 및 안전하게 실패하는 스택 테스트를 추가합니다.
17
17
  - TrustDex 0.9.0은 MCP 정책/출처 결과와 자동 도구 권한 사이의 값 없는 Claude/Codex
18
18
  연결, 버전 지정 스키마, 드리프트 검토 및 비활성 픽스처를 추가합니다.
19
+ - TrustDex 0.10.0은 명시적인 값 없는 런타임 인벤토리 계약, 실제 경계 대조,
20
+ 노출 드리프트 검토, 버전 지정 스키마 및 픽스처를 추가합니다.
21
+ - TrustDex 0.11.0은 정확한 런타임 인벤토리의 Ed25519 생성자 인증, 제한된 만료/캡처
22
+ 나이, 스키마 v2 인증 상태와 재사용·다른 키·미래 시각·변조·미인증 증거를
23
+ 안전하게 실패시키는 테스트를 추가합니다.
19
24
 
20
25
  ## 현재: 경계 강화
21
26
 
@@ -28,10 +33,11 @@ TrustDex는 초기 단계입니다. 이 로드맵은 방향을 공유하며 릴
28
33
 
29
34
  ## 다음: 실제 런타임 증거 강화
30
35
 
31
- - 버전이 지정된 권한 상태 JSON 스키마를 추가 결정 및 런타임으로 확장
32
- - 권고형 설정 검사가 런타임 및 운영체제 샌드박스와 결합되는 방식 문서화
33
- - 비공개 파일을 조용히 찾지 않으면서 런타임이 생성한 실제 설정 증거 추가
34
- - 호출을 가로채지 않고 런타임이 생성한 MCP/도구 목록을 받는 옵트인 어댑터 추가
36
+ - 런타임이 권한 있는 안정적 인터페이스를 제공할 때만 구체적인 옵트인 어댑터 게시
37
+ - 배포용 공개 키 허용 목록, 교체 및 폐기 연결 지점 추가
38
+ - 메시지 수준 생성자 서명 주변의 전송 보호 문서화
39
+ - 값 없는 보고서를 유지하면서 MCP 표시 범위 밖으로 실제 증거 확장
40
+ - 지원하는 어댑터/런타임 버전의 테스트 기반 호환성 매트릭스 게시
35
41
 
36
42
  ## 그다음: 무결성 증명
37
43
 
package/docs/ROADMAP.md CHANGED
@@ -16,6 +16,11 @@ TrustDex is early-stage. This roadmap communicates direction and is not a releas
16
16
  and Codex precedence, schema-v2 source topology evidence, and fail-closed stack tests.
17
17
  - TrustDex 0.9.0 adds value-free Claude/Codex bindings between MCP policy/provenance
18
18
  results and automatic tool grants, versioned schemas, drift review, and inert fixtures.
19
+ - TrustDex 0.10.0 adds an explicit value-free runtime inventory contract, effective
20
+ boundary reconciliation, exposure-drift review, versioned schemas, and fixtures.
21
+ - TrustDex 0.11.0 adds Ed25519 producer authentication for exact runtime inventories,
22
+ bounded expiry/capture age, schema-v2 authentication state, and fail-closed tests for
23
+ replay, wrong-key, future-time, mutation, and unauthenticated evidence.
19
24
 
20
25
  ## Now: harden the boundary
21
26
 
@@ -28,10 +33,11 @@ TrustDex is early-stage. This roadmap communicates direction and is not a releas
28
33
 
29
34
  ## Next: strengthen effective-runtime evidence
30
35
 
31
- - extend the versioned permission-posture JSON schemas to additional decisions and runtimes
32
- - document how advisory settings checks compose with runtime and operating-system sandboxes
33
- - add runtime-produced effective-setting evidence without silently discovering private files
34
- - add opt-in adapters for runtime-produced MCP/tool inventories without intercepting calls
36
+ - ship concrete opt-in adapters only where a runtime exposes an authorized stable interface
37
+ - add deployment-facing public-key allowlists, rotation, and revocation hooks
38
+ - document transport hardening around the message-level producer signature
39
+ - extend effective evidence beyond MCP visibility while retaining value-free reports
40
+ - publish a tested compatibility matrix for supported adapter/runtime versions
35
41
 
36
42
  ## Then: prove integrity
37
43
 
@@ -0,0 +1,89 @@
1
+ # 인증된 런타임 증거
2
+
3
+ <p align="right">
4
+ <a href="./RUNTIME_EVIDENCE.md">English</a> | <strong>한국어</strong>
5
+ </p>
6
+
7
+ TrustDex는 권한이 있는 Claude 또는 Codex 통합이 생성한 값 없는 런타임 인벤토리를
8
+ 인증할 수 있습니다. 인증은 고정된 어떤 Ed25519 키가 정확한 인벤토리에 서명했는지와
9
+ 수명이 짧은 증명이 신선한지를 확인합니다. 어댑터가 침해되지 않았거나 인벤토리가
10
+ 완전하거나 런타임이 검토된 정책을 강제했다는 사실까지 증명하지는 않습니다.
11
+
12
+ ## 종단 간 워크플로
13
+
14
+ 전용 생성자 키 쌍을 한 번 만드세요. 비공개 키는 어댑터에 보관하고, 공개 키는
15
+ 신뢰할 수 있는 채널을 통해 각 검증자에게 배포합니다.
16
+
17
+ ```bash
18
+ node ./bin/trustdex.mjs keygen \
19
+ --private .trustdex/runtime-producer-private.pem \
20
+ --public .trustdex/runtime-producer-public.pem
21
+ ```
22
+
23
+ 권한 있는 어댑터는 런타임, 캡처 시각/방식, 서버 이름 및 서버별 도구 개수만 담은
24
+ `agent-runtime-tool-inventory` JSON을 작성합니다. 그 파일에 즉시 서명하세요. 기본
25
+ 수명은 5분이고 최대 수명은 24시간입니다.
26
+
27
+ ```bash
28
+ node ./bin/trustdex.mjs sign-runtime-inventory \
29
+ ./runtime-tool-inventory.json \
30
+ --private .trustdex/runtime-producer-private.pem \
31
+ --out .trustdex/runtime-attestation.json \
32
+ --ttl-seconds 300
33
+ ```
34
+
35
+ 대조 전에 생성자 신원, 서명, 만료 및 캡처 신선도를 검증합니다.
36
+
37
+ ```bash
38
+ node ./bin/trustdex.mjs verify-runtime-inventory \
39
+ ./runtime-tool-inventory.json \
40
+ --attestation .trustdex/runtime-attestation.json \
41
+ --public .trustdex/runtime-producer-public.pem \
42
+ --max-age-seconds 120 \
43
+ --json
44
+
45
+ node ./bin/trustdex.mjs snapshot-runtime-tools \
46
+ .trustdex/claude-bindings.json \
47
+ ./runtime-tool-inventory.json \
48
+ --attestation .trustdex/runtime-attestation.json \
49
+ --public .trustdex/runtime-producer-public.pem \
50
+ --max-age-seconds 120 \
51
+ --require-authenticated \
52
+ --out .trustdex/runtime-tools.json
53
+ ```
54
+
55
+ 잘못되거나 만료되거나 오래되거나 미래 시각이거나 다른 키를 사용하거나 인벤토리와
56
+ 불일치하는 증명은 종료 코드 `2`를 반환합니다. 인증하지 않은 스키마 v2 실제 증거는
57
+ 항상 최소 `needs-review`가 되며, 관찰된 차단/미설정 서버는 계속 `block`이 됩니다.
58
+
59
+ ## 서명 범위
60
+
61
+ Ed25519 서명은 스키마/알고리즘 식별자, 정규 인벤토리 다이제스트, 런타임, 캡처
62
+ 시각과 방식, 생성자 공개 키 ID, 생성 시각 및 만료 시각을 포함합니다. 키 ID는 공개
63
+ SPKI 바이트의 SHA-256 다이제스트입니다. 별도 인벤토리 스키마가 원시 도구 목록과
64
+ 임의 필드를 거부하므로 증명과 실제 보고서에는 도구 이름, 엔드포인트, 자격 증명 또는
65
+ 비공개 키 자료가 포함되지 않습니다.
66
+
67
+ 선택적인 `--max-age-seconds`는 증명 만료와 별개입니다. 만료는 서명 사용 가능 시간을,
68
+ 최대 나이는 원본 캡처의 허용 나이를 제한합니다. TrustDex는 제한된 시계 오차만
69
+ 허용하기 위해 5분보다 먼 미래의 캡처와 증명도 거부합니다.
70
+
71
+ ## 운영 및 키 교체
72
+
73
+ - 생성자 전용 키를 사용하고 비공개 파일을 최소 권한으로 보호하며 커밋하지 마세요.
74
+ 일반 검토 기록 키도 암호학적으로 작동하지만 운영 역할은 분리해야 합니다.
75
+ - 예상 공개 키는 인벤토리/증명 채널 밖에서 고정하세요. 공격자가 증거와 공개 키를
76
+ 모두 바꿀 수 있다면 서명은 신원 주장이 아닙니다.
77
+ - 감사 보존이 필요하면 인벤토리, 증명, 고정 키 ID, 결합 스냅샷 및 실제 보고서를
78
+ 함께 보관하세요. 실제 보고서는 자체 일관성을 확인하지만 독립적으로 서명되지는 않습니다.
79
+ - 키 교체 시 새 공개 키를 먼저 배포하고, 제한된 중첩 기간 동안 오케스트레이션에서
80
+ 이전 또는 새 고정 키를 허용한 뒤 생성자를 전환하고 이전 키를 폐기하세요. TrustDex는
81
+ 호출당 전달된 키 하나를 검증하며 키 허용 목록과 폐기는 배포 환경의 책임입니다.
82
+ - `producer-key-changed`와 `inventory-authentication-changed` 차이를 검토 이벤트로
83
+ 취급하세요. 비공개 키 탈취가 의심되면 검증자에서 키를 제거하고 새 키로 증거를 다시 발급하세요.
84
+
85
+ 계약은
86
+ [`runtime-tool-inventory-v1.schema.json`](../schemas/runtime-tool-inventory-v1.schema.json),
87
+ [`runtime-tool-inventory-attestation-v1.schema.json`](../schemas/runtime-tool-inventory-attestation-v1.schema.json),
88
+ [`effective-runtime-tools-v2.schema.json`](../schemas/effective-runtime-tools-v2.schema.json),
89
+ [`effective-runtime-tools-diff-v2.schema.json`](../schemas/effective-runtime-tools-diff-v2.schema.json)에 정의되어 있습니다.
@@ -0,0 +1,96 @@
1
+ # Authenticated runtime evidence
2
+
3
+ <p align="right">
4
+ <strong>English</strong> | <a href="./RUNTIME_EVIDENCE.ko.md">한국어</a>
5
+ </p>
6
+
7
+ TrustDex can authenticate a value-free runtime inventory produced by an authorized
8
+ Claude or Codex integration. Authentication proves which pinned Ed25519 key signed the
9
+ exact inventory and whether the short-lived attestation is fresh. It does not prove
10
+ that the adapter is uncompromised, that the inventory is complete, or that the runtime
11
+ enforced the reviewed policy.
12
+
13
+ ## End-to-end workflow
14
+
15
+ Generate a dedicated producer key pair once. Keep the private key with the adapter and
16
+ distribute the public key through a trusted channel to each verifier:
17
+
18
+ ```bash
19
+ node ./bin/trustdex.mjs keygen \
20
+ --private .trustdex/runtime-producer-private.pem \
21
+ --public .trustdex/runtime-producer-public.pem
22
+ ```
23
+
24
+ The authorized adapter writes `agent-runtime-tool-inventory` JSON containing only the
25
+ runtime, capture time/method, server names, and per-server tool counts. Sign that exact
26
+ file immediately; the default lifetime is five minutes and the maximum is 24 hours:
27
+
28
+ ```bash
29
+ node ./bin/trustdex.mjs sign-runtime-inventory \
30
+ ./runtime-tool-inventory.json \
31
+ --private .trustdex/runtime-producer-private.pem \
32
+ --out .trustdex/runtime-attestation.json \
33
+ --ttl-seconds 300
34
+ ```
35
+
36
+ Verify producer identity, signature, expiry, and capture freshness before reconciliation:
37
+
38
+ ```bash
39
+ node ./bin/trustdex.mjs verify-runtime-inventory \
40
+ ./runtime-tool-inventory.json \
41
+ --attestation .trustdex/runtime-attestation.json \
42
+ --public .trustdex/runtime-producer-public.pem \
43
+ --max-age-seconds 120 \
44
+ --json
45
+
46
+ node ./bin/trustdex.mjs snapshot-runtime-tools \
47
+ .trustdex/claude-bindings.json \
48
+ ./runtime-tool-inventory.json \
49
+ --attestation .trustdex/runtime-attestation.json \
50
+ --public .trustdex/runtime-producer-public.pem \
51
+ --max-age-seconds 120 \
52
+ --require-authenticated \
53
+ --out .trustdex/runtime-tools.json
54
+ ```
55
+
56
+ An invalid, expired, stale, future-dated, wrong-key, or inventory-mismatched attestation
57
+ exits `2`. Without authentication, schema-v2 effective evidence is always at least
58
+ `needs-review`; observed blocked or unconfigured servers still produce `block`.
59
+
60
+ ## What is signed
61
+
62
+ The Ed25519 signature covers the schema and algorithm identifiers, canonical inventory
63
+ digest, runtime, capture time and method, producer public-key ID, creation time, and
64
+ expiry. The key ID is the SHA-256 digest of the public SPKI bytes. The separate inventory
65
+ schema rejects raw tool lists and arbitrary fields, so neither the attestation nor the
66
+ effective report contains tool names, endpoints, credentials, or private-key material.
67
+
68
+ The optional `--max-age-seconds` limit is independent of attestation expiry: expiry caps
69
+ how long the signature is usable, while maximum age caps how old the underlying capture
70
+ may be. TrustDex also rejects captures and attestations more than five minutes in the
71
+ future to tolerate only bounded clock skew.
72
+
73
+ ## Operations and key rotation
74
+
75
+ - Use a producer-specific key, protect the private file with least privilege, and never
76
+ commit it. A generic review-record key may work cryptographically but should remain a
77
+ separate operational role.
78
+ - Pin the expected public key outside the inventory/attestation channel. A signature is
79
+ not an identity claim if an attacker can replace both the evidence and its public key.
80
+ - Archive the inventory, attestation, pinned key ID, binding snapshot, and effective
81
+ report together when audit retention is required. The effective report is
82
+ self-consistent but is not independently signed.
83
+ - For rotation, distribute the new public key first, update orchestration to accept the
84
+ old or new pinned key during a bounded overlap, then switch the producer and retire the
85
+ old key. TrustDex verifies one supplied key per invocation; key allowlists and revocation
86
+ remain deployment responsibilities.
87
+ - Treat `producer-key-changed` and `inventory-authentication-changed` diffs as review
88
+ events. If a private key is suspected to be stolen, remove that key from verifiers and
89
+ reissue evidence with a new key.
90
+
91
+ The contracts are defined by
92
+ [`runtime-tool-inventory-v1.schema.json`](../schemas/runtime-tool-inventory-v1.schema.json),
93
+ [`runtime-tool-inventory-attestation-v1.schema.json`](../schemas/runtime-tool-inventory-attestation-v1.schema.json),
94
+ [`effective-runtime-tools-v2.schema.json`](../schemas/effective-runtime-tools-v2.schema.json),
95
+ and [`effective-runtime-tools-diff-v2.schema.json`](../schemas/effective-runtime-tools-diff-v2.schema.json).
96
+
@@ -26,6 +26,9 @@ TrustDex는 하나의 좁은 질문을 다룹니다.
26
26
  - 명시적으로 전달된 Claude 또는 Codex 설정 소스 사이의 우선순위 변경
27
27
  - 서버의 정책/출처 결과와 더 이상 일치하지 않는 자동 MCP 도구 권한
28
28
  - 실제 도구 경계를 가리는 와일드카드, 일치하지 않거나 모호한 권한
29
+ - 차단·검토 필요·미설정 MCP 서버를 노출한다고 명시적으로 보고한 런타임 인벤토리
30
+ - 서버 표시 범위 또는 도구 개수로 확대되는 실제 런타임 인벤토리
31
+ - 서명된 런타임 인벤토리의 변조, 만료/캡처 나이 이후 재사용, 미래 시각 지정 또는 다른 키 대체
29
32
 
30
33
  ## 신뢰 경계
31
34
 
@@ -54,11 +57,17 @@ TrustDex는 익숙한 프로젝트 이름, 스타 수, 패키지 이름 또는
54
57
  - 서명되지 않은 권한 상태 스냅샷 작성자의 인증
55
58
  - 결합 스냅샷이 실행 중인 에이전트가 실제로 불러온 파일을 반영함을 증명하는 것
56
59
  - 개별 MCP 도구 호출을 런타임에서 가로채거나 강제하는 것
60
+ - 인벤토리 완전성 증명 또는 침해된 어댑터나 탈취된 생성자 키의 거짓 증거 서명 방지
61
+ - 실제 Claude/Codex 세션을 자동으로 찾거나 비공개 상태를 읽는 것
57
62
 
58
63
  ## 중요한 실패 모드
59
64
 
60
65
  유효한 서명은 신뢰 기록이 해당 비공개 키로 서명되었고 연결된 스냅샷 다이제스트가 변경되지 않았음을 증명합니다. 원래 검토가 정확했다는 것은 증명하지 않습니다.
61
66
 
67
+ 마찬가지로 유효한 런타임 인벤토리 증명은 고정된 생성자 키가 검사된 시간 제한 안에서
68
+ 정확한 값 없는 인벤토리에 서명했음을 증명합니다. 생성자가 로드된 모든 도구를
69
+ 관찰했거나 런타임을 진실하게 보고했다는 사실은 증명하지 않습니다.
70
+
62
71
  ## 설계 원칙
63
72
 
64
73
  TrustDex는 누락된 증거를 신뢰로 변환해서는 안 됩니다. 알 수 없는 출처는 추측할 이유가 아니라 정책 입력입니다.
@@ -26,6 +26,9 @@ TrustDex addresses one narrow question:
26
26
  - precedence changes across explicitly supplied Claude or Codex settings sources
27
27
  - automatic MCP tool grants that no longer match the server's policy/provenance result
28
28
  - wildcard, unmatched, or ambiguous grants that hide the effective tool boundary
29
+ - explicitly reported runtime inventories that expose blocked, review-required, or unconfigured MCP servers
30
+ - effective runtime inventories expanding by server visibility or tool count
31
+ - mutation, replay past expiry/capture-age limits, future dating, or wrong-key substitution of signed runtime inventories
29
32
 
30
33
  ## Trust boundaries
31
34
 
@@ -54,11 +57,17 @@ TrustDex does **not** treat a familiar project name, star count, package name, o
54
57
  - authenticating the author of an unsigned permission posture snapshot
55
58
  - proving that a binding snapshot reflects the files actually loaded by a running agent
56
59
  - intercepting or enforcing individual MCP tool calls at runtime
60
+ - proving inventory completeness or preventing a compromised adapter or stolen producer key from signing false evidence
61
+ - discovering live Claude/Codex sessions or reading their private state automatically
57
62
 
58
63
  ## Important failure mode
59
64
 
60
65
  A valid signature proves that a trust record was signed by the corresponding private key and that its bound snapshot digest has not changed. It does not prove that the original review was correct.
61
66
 
67
+ Likewise, a valid runtime-inventory attestation proves that the pinned producer key
68
+ signed the exact value-free inventory within the checked time limits. It does not prove
69
+ that the producer observed every loaded tool or reported the runtime truthfully.
70
+
62
71
  ## Design principle
63
72
 
64
73
  TrustDex should never convert missing evidence into trust. Unknown provenance is a policy input, not a reason to guess.
@@ -11,7 +11,7 @@
11
11
  - `expected.json`은 필수 결정과 최소 신호를 기록합니다.
12
12
  - `drift-before.json`과 `drift-after.json`은 검토된 패키지에 비밀 정보를 포함하는 환경 키가 추가되는 상황을 모델링합니다.
13
13
  - [`permissions/`](permissions/README.ko.md)는 값이 제거된 Claude/Codex 권한 상태 드리프트를 다룹니다.
14
- - [`bindings/`](bindings/README.ko.md)는 MCP 출처와 자동 권한의 연결을 다룹니다.
14
+ - [`bindings/`](bindings/README.ko.md)는 MCP 출처와 자동 권한 연결 및 명시적 런타임 인벤토리 대조를 다룹니다.
15
15
 
16
16
  모든 패키지 이름은 가상이며, 모든 원격 엔드포인트는 예약된 `.invalid` 최상위 도메인을 사용하고, 자격 증명으로 보이는 모든 값은 자리표시자입니다. 이를 실제 값으로 바꾸지 마세요. TrustDex는 이 파일을 읽지만 나열된 명령을 실행하거나 나열된 엔드포인트에 연결하지 않습니다.
17
17
 
@@ -11,7 +11,7 @@ These files provide a reproducible defensive test of TrustDex's policy boundary.
11
11
  - `expected.json` records the required decisions and minimum signals.
12
12
  - `drift-before.json` and `drift-after.json` model a reviewed package gaining a secret-bearing environment key.
13
13
  - [`permissions/`](permissions/README.md) covers value-free Claude/Codex permission posture drift.
14
- - [`bindings/`](bindings/README.md) covers MCP provenance-to-automatic-grant bindings.
14
+ - [`bindings/`](bindings/README.md) covers MCP provenance-to-automatic-grant bindings and explicit runtime inventory reconciliation.
15
15
 
16
16
  All package names are fictional, all remote endpoints use the reserved `.invalid` top-level domain, and all apparent credentials are placeholders. Do not replace them with real values. TrustDex reads these files but never executes the listed commands or contacts the listed endpoints.
17
17
 
@@ -13,6 +13,10 @@ node ../../../bin/trustdex.mjs snapshot-claude-bindings ./claude.mcp.json \
13
13
  node ../../../bin/trustdex.mjs snapshot-codex-bindings ./codex.toml \
14
14
  --trust-store ./trust-store.json \
15
15
  --out ./codex.bindings.json
16
+
17
+ node ../../../bin/trustdex.mjs snapshot-runtime-tools \
18
+ ./claude.bindings.json ./runtime-after.json \
19
+ --out ./runtime.evidence.json
16
20
  ```
17
21
 
18
22
  검토된 Claude 서버의 범위 제한 승인은 `ALLOW` 결과와 결합됩니다. 출처를 알 수
@@ -22,3 +26,7 @@ node ../../../bin/trustdex.mjs snapshot-codex-bindings ./codex.toml \
22
26
 
23
27
  생성된 보고서는 엔드포인트 경로, 권한 지정자, 도구 이름 및 마커 값을 의도적으로
24
28
  제외합니다. `expected.json`은 안정적인 구조적 결과만 기록합니다.
29
+ 런타임 인벤토리는 명시적으로 제공되는 값 없는 어댑터 출력입니다. 도구 이름 대신
30
+ 서버 이름과 도구 개수만 포함합니다. `runtime-after.json`은 차단된 설정 서버와 예상
31
+ 밖 서버가 노출되는 상황을 모델링합니다. TrustDex는 런타임 상태를 자동으로 찾거나
32
+ 인벤토리 생성자를 인증하지 않습니다.
@@ -14,6 +14,10 @@ node ../../../bin/trustdex.mjs snapshot-claude-bindings ./claude.mcp.json \
14
14
  node ../../../bin/trustdex.mjs snapshot-codex-bindings ./codex.toml \
15
15
  --trust-store ./trust-store.json \
16
16
  --out ./codex.bindings.json
17
+
18
+ node ../../../bin/trustdex.mjs snapshot-runtime-tools \
19
+ ./claude.bindings.json ./runtime-after.json \
20
+ --out ./runtime.evidence.json
17
21
  ```
18
22
 
19
23
  The reviewed Claude server has a scoped grant bound to an `ALLOW` result. Its
@@ -23,3 +27,7 @@ review because `default_tools_approval_mode = "approve"` grants every tool.
23
27
 
24
28
  Generated reports intentionally omit endpoint paths, permission specifiers, tool
25
29
  names, and marker values. `expected.json` records only stable structural outcomes.
30
+ The runtime inventories are explicit, value-free adapter outputs: they contain server
31
+ names and tool counts, not tool names. `runtime-after.json` models a blocked configured
32
+ server and an unexpected server becoming visible. TrustDex does not discover runtime
33
+ state or authenticate the inventory producer.
@@ -11,5 +11,17 @@
11
11
  "automaticGrantCount": 2,
12
12
  "reviewCount": 1,
13
13
  "blockedCount": 1
14
+ },
15
+ "runtimeBefore": {
16
+ "status": "needs-review",
17
+ "observedServerCount": 1,
18
+ "matchedCount": 1,
19
+ "notObservedCount": 1
20
+ },
21
+ "runtimeAfter": {
22
+ "status": "block",
23
+ "observedServerCount": 3,
24
+ "blockedCount": 1,
25
+ "unexpectedCount": 1
14
26
  }
15
27
  }
@@ -0,0 +1,21 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "kind": "agent-runtime-tool-inventory",
4
+ "runtime": "claude",
5
+ "capturedAt": "2026-10-24T00:05:00.000Z",
6
+ "captureMethod": "runtime-adapter",
7
+ "servers": [
8
+ {
9
+ "name": "reviewed",
10
+ "toolCount": 2
11
+ },
12
+ {
13
+ "name": "unknown",
14
+ "toolCount": 1
15
+ },
16
+ {
17
+ "name": "unexpected",
18
+ "toolCount": 1
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "kind": "agent-runtime-tool-inventory",
4
+ "runtime": "claude",
5
+ "capturedAt": "2026-10-24T00:00:00.000Z",
6
+ "captureMethod": "runtime-adapter",
7
+ "servers": [
8
+ {
9
+ "name": "reviewed",
10
+ "toolCount": 2
11
+ }
12
+ ]
13
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trustdex",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "A local-first trust, provenance, and review gate for AI agent tools, MCP servers, skills, and plugins.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,8 +8,8 @@
8
8
  },
9
9
  "scripts": {
10
10
  "test": "node --test",
11
- "test:research": "node --test test/research-fixtures.test.mjs test/claude-settings.test.mjs test/codex-settings.test.mjs test/posture.test.mjs test/settings-stack.test.mjs test/bindings.test.mjs",
12
- "check": "node --check bin/trustdex.mjs && node --check src/bindings.mjs && node --check src/canonical.mjs && node --check src/claude-config.mjs && node --check src/claude-settings.mjs && node --check src/codex-config.mjs && node --check src/codex-settings.mjs && node --check src/extensions.mjs && node --check src/gate.mjs && node --check src/inspect.mjs && node --check src/policy.mjs && node --check src/policy-packs.mjs && node --check src/posture.mjs && node --check src/provenance.mjs && node --check src/provenance-online.mjs && node --check src/review.mjs && node --check src/snapshot.mjs && node --check src/trust-record.mjs",
11
+ "test:research": "node --test test/research-fixtures.test.mjs test/claude-settings.test.mjs test/codex-settings.test.mjs test/posture.test.mjs test/settings-stack.test.mjs test/bindings.test.mjs test/runtime-evidence.test.mjs test/runtime-attestation.test.mjs",
12
+ "check": "node --check bin/trustdex.mjs && node --check src/bindings.mjs && node --check src/runtime-evidence.mjs && node --check src/runtime-attestation.mjs && node --check src/canonical.mjs && node --check src/claude-config.mjs && node --check src/claude-settings.mjs && node --check src/codex-config.mjs && node --check src/codex-settings.mjs && node --check src/extensions.mjs && node --check src/gate.mjs && node --check src/inspect.mjs && node --check src/policy.mjs && node --check src/policy-packs.mjs && node --check src/posture.mjs && node --check src/provenance.mjs && node --check src/provenance-online.mjs && node --check src/review.mjs && node --check src/snapshot.mjs && node --check src/trust-record.mjs",
13
13
  "prepublishOnly": "npm test && npm run check"
14
14
  },
15
15
  "engines": {
@@ -0,0 +1,50 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/grigent/trustdex/blob/main/schemas/effective-runtime-tools-diff-v1.schema.json",
4
+ "title": "TrustDex effective runtime tool boundary diff v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "runtime", "status", "baselineDigest", "currentDigest", "summary", "changes"],
8
+ "properties": {
9
+ "schemaVersion": { "const": 1 },
10
+ "runtime": { "enum": ["claude", "codex"] },
11
+ "status": { "enum": ["unchanged", "restricted", "needs-review"] },
12
+ "baselineDigest": { "$ref": "#/$defs/digest" },
13
+ "currentDigest": { "$ref": "#/$defs/digest" },
14
+ "summary": {
15
+ "type": "object",
16
+ "additionalProperties": false,
17
+ "required": ["expansions", "restrictions", "reviews"],
18
+ "properties": {
19
+ "expansions": { "$ref": "#/$defs/count" },
20
+ "restrictions": { "$ref": "#/$defs/count" },
21
+ "reviews": { "$ref": "#/$defs/count" }
22
+ }
23
+ },
24
+ "changes": {
25
+ "type": "array",
26
+ "items": {
27
+ "type": "object",
28
+ "additionalProperties": false,
29
+ "required": ["impact", "type", "name", "field", "before", "after"],
30
+ "properties": {
31
+ "impact": { "enum": ["expansion", "restriction", "review"] },
32
+ "type": {
33
+ "enum": [
34
+ "bindings-changed", "capture-method-changed", "server-added", "server-removed",
35
+ "observation-changed", "tool-count-changed", "binding-state-changed", "server-status-changed"
36
+ ]
37
+ },
38
+ "name": { "oneOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
39
+ "field": { "type": "string", "minLength": 1 },
40
+ "before": {},
41
+ "after": {}
42
+ }
43
+ }
44
+ }
45
+ },
46
+ "$defs": {
47
+ "digest": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
48
+ "count": { "type": "integer", "minimum": 0 }
49
+ }
50
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/grigent/trustdex/blob/main/schemas/effective-runtime-tools-diff-v2.schema.json",
4
+ "title": "TrustDex authenticated effective runtime tool boundary diff v2",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "runtime", "status", "baselineDigest", "currentDigest", "summary", "changes"],
8
+ "properties": {
9
+ "schemaVersion": { "const": 2 },
10
+ "runtime": { "enum": ["claude", "codex"] },
11
+ "status": { "enum": ["unchanged", "restricted", "needs-review"] },
12
+ "baselineDigest": { "$ref": "#/$defs/digest" },
13
+ "currentDigest": { "$ref": "#/$defs/digest" },
14
+ "summary": {
15
+ "type": "object",
16
+ "additionalProperties": false,
17
+ "required": ["expansions", "restrictions", "reviews"],
18
+ "properties": {
19
+ "expansions": { "$ref": "#/$defs/count" },
20
+ "restrictions": { "$ref": "#/$defs/count" },
21
+ "reviews": { "$ref": "#/$defs/count" }
22
+ }
23
+ },
24
+ "changes": {
25
+ "type": "array",
26
+ "items": {
27
+ "type": "object",
28
+ "additionalProperties": false,
29
+ "required": ["impact", "type", "name", "field", "before", "after"],
30
+ "properties": {
31
+ "impact": { "enum": ["expansion", "restriction", "review"] },
32
+ "type": {
33
+ "enum": [
34
+ "bindings-changed", "capture-method-changed", "inventory-authentication-changed",
35
+ "producer-key-changed", "server-added", "server-removed", "observation-changed",
36
+ "tool-count-changed", "binding-state-changed", "server-status-changed"
37
+ ]
38
+ },
39
+ "name": { "oneOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
40
+ "field": { "type": "string", "minLength": 1 },
41
+ "before": {},
42
+ "after": {}
43
+ }
44
+ }
45
+ }
46
+ },
47
+ "$defs": {
48
+ "digest": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
49
+ "count": { "type": "integer", "minimum": 0 }
50
+ }
51
+ }