trustdex 0.4.2 → 0.4.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/README.md +23 -4
- package/bin/trustdex.mjs +3 -1
- package/docs/CODEX.md +73 -0
- package/docs/EVALUATION.md +35 -0
- package/docs/RELEASING.md +18 -1
- package/docs/ROADMAP.md +2 -1
- package/docs/SECURITY_RESEARCH.md +60 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -75,8 +75,8 @@ Requires Node.js 20+.
|
|
|
75
75
|
Run directly from npm:
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
|
-
npx trustdex@0.4.
|
|
79
|
-
npx trustdex@0.4.
|
|
78
|
+
npx trustdex@0.4.4 --help
|
|
79
|
+
npx trustdex@0.4.4 inspect ./mcp.json --pack strict --policy ./trustdex.policy.json
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
Or work from a source checkout:
|
|
@@ -100,6 +100,23 @@ Exit codes for inspection:
|
|
|
100
100
|
- `1` - at least one entry needs review
|
|
101
101
|
- `2` - at least one entry is blocked, or the command failed
|
|
102
102
|
|
|
103
|
+
## Reproducible defensive research
|
|
104
|
+
|
|
105
|
+
TrustDex includes an inert adversarial benchmark for testing the policy boundary without contacting or executing third-party services. The fixtures use reserved `.invalid` domains, placeholder credentials, and configuration data only; TrustDex inspects them statically and never launches the listed servers.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npm run test:research
|
|
109
|
+
|
|
110
|
+
node ./bin/trustdex.mjs inspect \
|
|
111
|
+
./examples/adversarial/mcp-config.json \
|
|
112
|
+
--pack strict \
|
|
113
|
+
--policy ./examples/adversarial/policy.json
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The direct inspection intentionally exits with code `2`: the checked-in expectation is one `ALLOW`, one `ASK`, and five `BLOCK` decisions. The automated test also verifies that placeholder secret values do not appear in results and that a newly introduced secret-bearing environment variable invalidates the previous review state.
|
|
117
|
+
|
|
118
|
+
See the [defensive security research policy](docs/SECURITY_RESEARCH.md), [evaluation record](docs/EVALUATION.md), and [adversarial fixture guide](examples/adversarial/README.md).
|
|
119
|
+
|
|
103
120
|
## Built-in policy packs
|
|
104
121
|
|
|
105
122
|
```bash
|
|
@@ -147,6 +164,8 @@ node ./bin/trustdex.mjs gate-codex ./examples/codex.config.toml \
|
|
|
147
164
|
|
|
148
165
|
The gate removes non-approved MCP sections while preserving unrelated TOML sections. TrustDex intentionally parses only the MCP-related TOML constructs it needs; unsupported MCP syntax fails rather than being silently trusted.
|
|
149
166
|
|
|
167
|
+
See [Using TrustDex with Codex](docs/CODEX.md) for a step-by-step gating workflow and for how this project uses Codex in its own review process.
|
|
168
|
+
|
|
150
169
|
## Online provenance observations
|
|
151
170
|
|
|
152
171
|
Normal inspection remains local-only. These commands perform an explicit network lookup only when invoked:
|
|
@@ -292,7 +311,7 @@ The private key should never be committed.
|
|
|
292
311
|
```yaml
|
|
293
312
|
- uses: actions/checkout@v4
|
|
294
313
|
|
|
295
|
-
- uses: grigent/trustdex@v0.4.
|
|
314
|
+
- uses: grigent/trustdex@v0.4.4
|
|
296
315
|
with:
|
|
297
316
|
config: ./mcp.json
|
|
298
317
|
pack: official-first
|
|
@@ -320,7 +339,7 @@ The public roadmap is maintained in [docs/ROADMAP.md](docs/ROADMAP.md). Near-ter
|
|
|
320
339
|
|
|
321
340
|
TrustDex does **not** prove that third-party code is safe and does not replace sandboxing, dependency scanning, code review, or least-privilege credentials.
|
|
322
341
|
|
|
323
|
-
See [SECURITY.md](SECURITY.md), [docs/THREAT_MODEL.md](docs/THREAT_MODEL.md), and [docs/TRUST_STORE.md](docs/TRUST_STORE.md).
|
|
342
|
+
See [SECURITY.md](SECURITY.md), [docs/THREAT_MODEL.md](docs/THREAT_MODEL.md), [docs/SECURITY_RESEARCH.md](docs/SECURITY_RESEARCH.md), [docs/EVALUATION.md](docs/EVALUATION.md), and [docs/TRUST_STORE.md](docs/TRUST_STORE.md).
|
|
324
343
|
|
|
325
344
|
## Contributing
|
|
326
345
|
|
package/bin/trustdex.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
2
3
|
import fs from 'node:fs/promises';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
import process from 'node:process';
|
|
@@ -27,7 +28,8 @@ import {
|
|
|
27
28
|
verifyTrustRecord
|
|
28
29
|
} from '../src/trust-record.mjs';
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
// Read the version from the package manifest so --version cannot drift from releases.
|
|
32
|
+
const VERSION = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
|
|
31
33
|
|
|
32
34
|
function usage() {
|
|
33
35
|
console.log(`TrustDex v${VERSION}
|
package/docs/CODEX.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Using TrustDex with Codex
|
|
2
|
+
|
|
3
|
+
This guide covers two things: gating the MCP servers a Codex client may start, and how TrustDex itself is maintained with Codex.
|
|
4
|
+
|
|
5
|
+
TrustDex is an independent project. It is not affiliated with, endorsed by, or certified by OpenAI, and an ALLOW decision is not an OpenAI or TrustDex safety certification.
|
|
6
|
+
|
|
7
|
+
## Gate Codex MCP servers
|
|
8
|
+
|
|
9
|
+
Codex clients read MCP server definitions from `[mcp_servers.<name>]` tables in `config.toml` (by default under `~/.codex/`). Every entry there can start a local process or connect to a remote endpoint with the credentials you give it.
|
|
10
|
+
|
|
11
|
+
### 1. Inspect the current configuration
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx trustdex@0.4.4 inspect-codex ~/.codex/config.toml --pack strict
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This reads the file locally and makes no network request. The output lists each MCP server, its source type, trust signals, and an ALLOW / ASK / BLOCK decision. Environment variable names may appear; their values never do.
|
|
18
|
+
|
|
19
|
+
Use `--json` for machine-readable output and `--trust-store ./trust-store.json` to attach explicit publisher evidence (see [TRUST_STORE.md](TRUST_STORE.md)).
|
|
20
|
+
|
|
21
|
+
### 2. Write a gated copy
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx trustdex@0.4.4 gate-codex ~/.codex/config.toml \
|
|
25
|
+
--pack official-first \
|
|
26
|
+
--trust-store ./trust-store.json \
|
|
27
|
+
--out ./gated-config.toml
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The gated file keeps unrelated TOML sections (models, features, profiles) unchanged and removes every MCP section that is not ALLOW. `ASK` entries stay out unless you pass `--include-ask`, which should only be used when another approval layer exists.
|
|
31
|
+
|
|
32
|
+
Review the difference before using it:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
diff ~/.codex/config.toml ./gated-config.toml
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
TrustDex never edits `config.toml` in place. Replacing the original file, or pointing a Codex installation at the gated copy, is an explicit step you take after review.
|
|
39
|
+
|
|
40
|
+
### 3. Re-run after every change
|
|
41
|
+
|
|
42
|
+
MCP entries change when a package version is bumped, a launcher is swapped, or a new environment variable is passed. Re-run `inspect-codex` and `gate-codex` whenever `config.toml` changes; a CI job or a pre-commit hook in a dotfiles repository works well for this.
|
|
43
|
+
|
|
44
|
+
The signed `snapshot`, `approve`, and `recheck` drift workflow in the [README](../README.md#capability-and-provenance-drift) currently accepts MCP JSON only. Extending it to Codex `config.toml` is tracked in the [roadmap](ROADMAP.md).
|
|
45
|
+
|
|
46
|
+
### Fail-closed parsing
|
|
47
|
+
|
|
48
|
+
TrustDex parses only the TOML constructs used by Codex MCP sections. An unsupported MCP key, nested subsection, or syntax is reported as an error instead of being skipped, so a configuration TrustDex cannot fully read never silently becomes ALLOW.
|
|
49
|
+
|
|
50
|
+
### Skills and plugins
|
|
51
|
+
|
|
52
|
+
Agent skills and plugin manifests can be inspected the same way:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx trustdex@0.4.4 inspect-skill ./path/to/SKILL.md --pack strict
|
|
56
|
+
npx trustdex@0.4.4 inspect-plugin ./path/to/plugin.json --pack strict
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
These report observable signals such as piped shell installers, references to sensitive paths, network URLs, and wildcard tool scopes. They do not prove a skill or plugin is safe.
|
|
60
|
+
|
|
61
|
+
## Gate MCP configuration in CI
|
|
62
|
+
|
|
63
|
+
Repositories that ship an MCP configuration for agents can gate it on every pull request with the [TrustDex GitHub Action](../README.md#github-action). Pin the action to a reviewed commit SHA.
|
|
64
|
+
|
|
65
|
+
## How TrustDex is maintained with Codex
|
|
66
|
+
|
|
67
|
+
TrustDex uses Codex as a reviewer and maintainer assistant, with the same trust boundary it asks users to apply:
|
|
68
|
+
|
|
69
|
+
- [AGENTS.md](../AGENTS.md) holds the development rules and a **Review guidelines** section that Codex code review applies to TrustDex pull requests. The guidelines turn the project's security invariants (no silent ALLOW, no secret values in output, no provenance override of blocking signals, fail-closed parsing, pinned actions) into explicit review findings.
|
|
70
|
+
- Codex suggestions are treated like any other contribution: they go through a pull request, must pass the cross-platform CI matrix and CodeQL, and are merged only after maintainer review.
|
|
71
|
+
- Codex does not hold release credentials. npm publication uses Trusted Publisher OIDC with Sigstore provenance from `.github/workflows/publish.yml`, triggered by a maintainer.
|
|
72
|
+
|
|
73
|
+
If you contribute with Codex or another coding agent, the same AGENTS.md rules apply to your changes.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Defensive evaluation
|
|
2
|
+
|
|
3
|
+
This evaluation records the behavior enforced by the checked-in adversarial fixtures. Run `npm run test:research` to reproduce it. The test performs local static inspection only and does not execute or contact any configured server.
|
|
4
|
+
|
|
5
|
+
## MCP policy cases
|
|
6
|
+
|
|
7
|
+
The cases use the built-in `strict` policy with the small overlay in `examples/adversarial/policy.json`.
|
|
8
|
+
|
|
9
|
+
| Case | Required evidence | Expected decision | Reason |
|
|
10
|
+
| --- | --- | --- | --- |
|
|
11
|
+
| `trusted-pinned-package` | pinned package; explicitly trusted package name | `ALLOW` | the configured version is fixed and the policy contains an explicit package trust rule |
|
|
12
|
+
| `floating-version` | `install-on-run`, `unbounded-version` | `BLOCK` | a moving package version can change without review |
|
|
13
|
+
| `shell-launcher` | `shell-execution`, `filesystem-path` | `BLOCK` | shell execution is blocked by the strict policy |
|
|
14
|
+
| `credential-bearing-url` | `embedded-credentials`, `network-endpoint`, `url-query-parameters` | `BLOCK` | embedded credentials are blocking even when the host is allowlisted |
|
|
15
|
+
| `insecure-remote` | `insecure-transport`, `network-endpoint` | `BLOCK` | plaintext transport is blocking even when the host is allowlisted |
|
|
16
|
+
| `sensitive-local-env` | `filesystem-path`, `secret-env` | `ASK` | a local extension with a secret-like environment name requires review |
|
|
17
|
+
| `unknown-remote` | `network-endpoint` | `BLOCK` | the remote host has no explicit allowlist or provenance evidence |
|
|
18
|
+
|
|
19
|
+
Expected total: one `ALLOW`, one `ASK`, and five `BLOCK` decisions.
|
|
20
|
+
|
|
21
|
+
## Drift case
|
|
22
|
+
|
|
23
|
+
The drift fixture begins with the trusted pinned package and then introduces an `API_TOKEN` environment key. The regression test requires all of the following changes:
|
|
24
|
+
|
|
25
|
+
- `signals-added` for `secret-env`
|
|
26
|
+
- `decision-changed` from `ALLOW` to `ASK`
|
|
27
|
+
- `fingerprint-changed`
|
|
28
|
+
|
|
29
|
+
The placeholder value itself must not appear in either inspection result or snapshot.
|
|
30
|
+
|
|
31
|
+
## What this does not measure
|
|
32
|
+
|
|
33
|
+
This benchmark is intentionally narrow. It does not measure runtime behavior, sandbox escape, arbitrary malware, every form of prompt injection, publisher identity ownership, or vulnerabilities in transitive dependencies. In particular, tool descriptions returned dynamically by an already-running MCP server are outside the current static configuration boundary.
|
|
34
|
+
|
|
35
|
+
The small fixture set is a regression baseline, not a statistical claim about detection accuracy. False-positive and false-negative rates require a larger, independently reviewed corpus of redacted real-world configurations.
|
package/docs/RELEASING.md
CHANGED
|
@@ -30,12 +30,29 @@ Once trusted publishing works, remove the `NPM_TOKEN` repository secret and revo
|
|
|
30
30
|
|
|
31
31
|
Both release workflows run `npm pkg fix` and require a clean `package.json` diff before packing or publishing. This prevents npm from silently normalizing away critical metadata such as the CLI entrypoint.
|
|
32
32
|
|
|
33
|
-
## Provenance
|
|
33
|
+
## Provenance and release evidence
|
|
34
34
|
|
|
35
35
|
The repository is public and the package is public, so GitHub-hosted publishing can emit npm provenance. The workflow also passes `--provenance` explicitly.
|
|
36
36
|
|
|
37
37
|
Provenance links the published artifact to its source/build environment. It does not prove that the package contains no malicious behavior.
|
|
38
38
|
|
|
39
|
+
The GitHub release workflow also creates and uploads:
|
|
40
|
+
|
|
41
|
+
- the npm package tarball built from the release commit
|
|
42
|
+
- a CycloneDX JSON SBOM
|
|
43
|
+
- a `SHA256SUMS` file covering the tarball and SBOM
|
|
44
|
+
- a GitHub build-provenance attestation for the tarball
|
|
45
|
+
- a GitHub SBOM attestation binding the SBOM to the tarball
|
|
46
|
+
|
|
47
|
+
After downloading a release, verify its checksum and GitHub attestation before inspection or installation:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
shasum -a 256 -c SHA256SUMS
|
|
51
|
+
gh attestation verify trustdex-<version>.tgz --repo grigent/trustdex
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The npm provenance statement and GitHub attestations cover different publication paths. Neither is a malware analysis or a substitute for reviewing the release contents and the documented trust boundary.
|
|
55
|
+
|
|
39
56
|
## Version checklist
|
|
40
57
|
|
|
41
58
|
Before each release:
|
package/docs/ROADMAP.md
CHANGED
|
@@ -19,6 +19,7 @@ TrustDex is early-stage. This roadmap communicates direction and is not a releas
|
|
|
19
19
|
|
|
20
20
|
## Later: expand interoperability
|
|
21
21
|
|
|
22
|
+
- extend signed snapshot, approval, and recheck workflows to Codex `config.toml`
|
|
22
23
|
- add adapters for additional agent runtimes and registries
|
|
23
24
|
- publish a compatibility matrix backed by tests
|
|
24
25
|
- define machine-readable decision output for CI and policy tooling
|
|
@@ -30,4 +31,4 @@ The project is seeking pilot users willing to share non-sensitive feedback about
|
|
|
30
31
|
|
|
31
32
|
## How to help
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
If you ran TrustDex on a real configuration, the **Pilot feedback** issue form is the fastest way to report results. Otherwise, open a focused issue describing the use case and redacted configuration shape. For security-sensitive proposals, include the expected trust boundary and bypass cases.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Defensive security research
|
|
2
|
+
|
|
3
|
+
TrustDex is developed for legitimate defensive research into trust decisions made before AI agents receive access to third-party tools. This document defines the authorization, safety, and disclosure boundaries for that work.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
The research asks whether observable configuration, provenance, integrity, and capability evidence is sufficient to keep an extension unavailable until a human or policy explicitly trusts it. Current work focuses on:
|
|
8
|
+
|
|
9
|
+
- unpinned or substituted packages
|
|
10
|
+
- install-on-run and shell launchers
|
|
11
|
+
- embedded URL credentials and insecure remote transport
|
|
12
|
+
- secret-bearing environment variable names without retaining their values
|
|
13
|
+
- source, provenance, decision, fingerprint, and capability drift
|
|
14
|
+
- signed review records and re-review after trust-relevant change
|
|
15
|
+
- parser behavior that must fail closed on unsupported syntax
|
|
16
|
+
|
|
17
|
+
The intended outputs are reproducible fixtures, regression tests, documented limitations, and practical mitigations for agent developers and operators.
|
|
18
|
+
|
|
19
|
+
## Authorization boundary
|
|
20
|
+
|
|
21
|
+
Research is limited to:
|
|
22
|
+
|
|
23
|
+
- systems and accounts owned by the researcher; or
|
|
24
|
+
- systems for which the researcher has explicit authorization to test; and
|
|
25
|
+
- isolated local or purpose-built test environments using non-sensitive fixtures.
|
|
26
|
+
|
|
27
|
+
TrustDex research does not authorize testing unrelated public systems. It excludes credential theft, persistence, destructive actions, data exfiltration, mass exploitation, unauthorized access, malware deployment, and bypassing another party's safeguards.
|
|
28
|
+
|
|
29
|
+
## Safe test data
|
|
30
|
+
|
|
31
|
+
Checked-in adversarial fixtures are inert configuration documents. They use reserved `.invalid` domains, nonexistent package namespaces, and unmistakable placeholder values. TrustDex does not execute MCP servers during inspection.
|
|
32
|
+
|
|
33
|
+
Tests assert that secret-like values, URL credentials, query values, and private paths do not appear in inspection results. A fixture that requires a real credential, private endpoint, personal data, or production service is not acceptable for this repository.
|
|
34
|
+
|
|
35
|
+
## Method
|
|
36
|
+
|
|
37
|
+
Each research case should contain:
|
|
38
|
+
|
|
39
|
+
1. a minimal, reviewable input fixture
|
|
40
|
+
2. the expected trust-relevant signals
|
|
41
|
+
3. the expected `ALLOW`, `ASK`, or `BLOCK` decision under a named policy
|
|
42
|
+
4. an automated regression test
|
|
43
|
+
5. a documented limitation or plausible bypass condition
|
|
44
|
+
|
|
45
|
+
An `ALLOW` result means only that observed evidence matched the selected policy. It is never represented as proof that arbitrary code is safe.
|
|
46
|
+
|
|
47
|
+
## Handling findings
|
|
48
|
+
|
|
49
|
+
Potential TrustDex vulnerabilities that could put users at risk should follow [SECURITY.md](../SECURITY.md). Findings in another project should be disclosed through that project's authorized security channel and should not be published before a reasonable coordinated-disclosure process.
|
|
50
|
+
|
|
51
|
+
Public reports must remove credentials, private endpoints, proprietary prompts, personal data, and exploit details that would create unnecessary risk. Research notes should prefer the minimum evidence needed to reproduce and fix the issue.
|
|
52
|
+
|
|
53
|
+
## Current reproducible evidence
|
|
54
|
+
|
|
55
|
+
- [Adversarial MCP fixtures](../examples/adversarial/README.md)
|
|
56
|
+
- [Evaluation record](EVALUATION.md)
|
|
57
|
+
- [Threat model](THREAT_MODEL.md)
|
|
58
|
+
- [Security policy](../SECURITY.md)
|
|
59
|
+
|
|
60
|
+
The project welcomes verifiable pilot feedback, including false positives and false negatives, through the repository's Pilot feedback issue form. Popularity, branding, and unverifiable testimonials are not treated as security evidence.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trustdex",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
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,6 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"test": "node --test",
|
|
11
|
+
"test:research": "node --test test/research-fixtures.test.mjs",
|
|
11
12
|
"check": "node --check bin/trustdex.mjs && node --check src/canonical.mjs && node --check src/codex-config.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/provenance.mjs && node --check src/provenance-online.mjs && node --check src/review.mjs && node --check src/snapshot.mjs && node --check src/trust-record.mjs",
|
|
12
13
|
"prepublishOnly": "npm test && npm run check"
|
|
13
14
|
},
|