trustdex 0.6.0 → 0.7.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.
@@ -19,6 +19,7 @@ TrustDex는 AI 에이전트가 서드파티 도구에 접근하기 전에 내리
19
19
  - 지원하지 않는 구문에서 안전하게 실패해야 하는 파서 동작
20
20
  - Claude Code 권한 설정의 자동 행동 권한
21
21
  - Codex 샌드박스, 승인, 네트워크, 쓰기 가능 루트, 웹 검색 및 서브에이전트 설정
22
+ - 구조적 권한 상태 드리프트 및 에이전트 자율성 확대 시 재검토
22
23
 
23
24
  의도한 결과물은 재현 가능한 픽스처, 회귀 테스트, 문서화된 제한 사항 및 에이전트 개발자와 운영자를 위한 실용적인 완화책입니다.
24
25
 
@@ -61,6 +62,7 @@ TrustDex 연구는 관련 없는 공개 시스템을 테스트할 권한을 부
61
62
  - [적대적 MCP 픽스처](../examples/adversarial/README.ko.md)
62
63
  - [Claude Code 권한 픽스처](../examples/claude.settings.json)
63
64
  - [Codex 권한 픽스처](../examples/codex.permissions.toml)
65
+ - [적대적 Claude 및 Codex 권한 상태 픽스처](../examples/adversarial/permissions/README.ko.md)
64
66
  - [평가 기록](EVALUATION.ko.md)
65
67
  - [방어적 AI 에이전트 보안 사용 사례](DEFENSIVE_USE_CASE.ko.md)
66
68
  - [위협 모델](THREAT_MODEL.ko.md)
@@ -19,6 +19,7 @@ The research asks whether observable configuration, provenance, integrity, and c
19
19
  - parser behavior that must fail closed on unsupported syntax
20
20
  - automatic action grants in Claude Code permission settings
21
21
  - Codex sandbox, approval, network, writable-root, web-search, and subagent settings
22
+ - structural permission posture drift and review when agent autonomy expands
22
23
 
23
24
  The intended outputs are reproducible fixtures, regression tests, documented limitations, and practical mitigations for agent developers and operators.
24
25
 
@@ -61,6 +62,7 @@ Public reports must remove credentials, private endpoints, proprietary prompts,
61
62
  - [Adversarial MCP fixtures](../examples/adversarial/README.md)
62
63
  - [Claude Code permission fixture](../examples/claude.settings.json)
63
64
  - [Codex permission fixture](../examples/codex.permissions.toml)
65
+ - [Adversarial Claude and Codex permission posture fixtures](../examples/adversarial/permissions/README.md)
64
66
  - [Evaluation record](EVALUATION.md)
65
67
  - [Defensive AI-agent security use case](DEFENSIVE_USE_CASE.md)
66
68
  - [Threat model](THREAT_MODEL.md)
@@ -22,6 +22,7 @@ TrustDex는 하나의 좁은 질문을 다룹니다.
22
22
  - 광범위한 셸, 파일 시스템, 네트워크, MCP 또는 서브에이전트 작업을 조용히 자동 승인하는 Claude Code 권한 규칙
23
23
  - 샌드박스를 제거하거나 승인을 생략하거나 네트워크 접근 또는 쓰기 가능 루트를 추가하는 Codex 설정
24
24
  - 명시적인 검토 없이 변경되는 행동 권한 설정
25
+ - 값이 제거된 구조적 기준 상태보다 확대되는 Claude 또는 Codex 권한 상태
25
26
 
26
27
  ## 신뢰 경계
27
28
 
@@ -46,6 +47,7 @@ TrustDex는 익숙한 프로젝트 이름, 스타 수, 패키지 이름 또는
46
47
  - 도난당한 서명 비공개 키로부터 보호
47
48
  - 모든 사용자, 프로젝트, 프로필, 관리형, 시스템, 환경 및 명령줄 소스를 병합한 실제 설정 계산
48
49
  - Claude Code 또는 Codex 행동 권한의 런타임 강제 적용
50
+ - 서명되지 않은 권한 상태 스냅샷 작성자의 인증
49
51
 
50
52
  ## 중요한 실패 모드
51
53
 
@@ -22,6 +22,7 @@ TrustDex addresses one narrow question:
22
22
  - Claude Code permission rules that silently auto-approve broad shell, filesystem, network, MCP, or subagent actions
23
23
  - Codex configurations that remove the sandbox, suppress approvals, enable network access, or add writable roots
24
24
  - action-permission settings changing without an explicit review
25
+ - Claude or Codex permission posture expanding relative to a value-free structural baseline
25
26
 
26
27
  ## Trust boundaries
27
28
 
@@ -46,6 +47,7 @@ TrustDex does **not** treat a familiar project name, star count, package name, o
46
47
  - protecting a stolen signing private key
47
48
  - calculating the effective configuration after every user, project, profile, managed, system, environment, and command-line source is merged
48
49
  - enforcing Claude Code or Codex action permissions at runtime
50
+ - authenticating the author of an unsigned permission posture snapshot
49
51
 
50
52
  ## Important failure mode
51
53
 
@@ -0,0 +1,15 @@
1
+ # 적대적 권한 상태 픽스처
2
+
3
+ 이 픽스처는 Claude Code와 Codex의 제한적인 기준 상태와 이후의 자율성 확대를
4
+ 모델링합니다. 모든 자격 증명, 명령 인수, 경로 및 호스트명은 비활성 테스트
5
+ 데이터입니다. `.invalid` 호스트명은 공개 인터넷에서 해석될 수 없습니다.
6
+
7
+ 평가는 다음을 검증합니다.
8
+
9
+ - 제한적 설정도 안전 인증으로 표현하지 않고 검토 가능한 상태로 유지
10
+ - 자동 셸, 네트워크, 파일 시스템 및 서브에이전트 권한 확대 감지
11
+ - 권한 상태 비교가 `needs-review`를 반환
12
+ - 검사, 스냅샷 또는 차이 출력에 설정 값과 경로 값이 나타나지 않음
13
+
14
+ 이 픽스처는 외부 시스템에 대한 보안 테스트를 허가하지 않으며 실제 사용자
15
+ 설정을 재현하지 않습니다.
@@ -0,0 +1,15 @@
1
+ # Adversarial permission posture fixtures
2
+
3
+ These fixtures model a restrictive baseline and a later autonomy expansion for
4
+ Claude Code and Codex. Every credential, command argument, path, and hostname is
5
+ inert test data. The `.invalid` hostname cannot resolve on the public Internet.
6
+
7
+ The evaluation asserts that:
8
+
9
+ - restrictive settings remain reviewable without being described as certified safe
10
+ - automatic shell, network, filesystem, and subagent expansion is detected
11
+ - permission posture comparison returns `needs-review`
12
+ - settings values and path values never appear in inspection, snapshot, or diff output
13
+
14
+ The fixtures do not authorize security testing against any external system and do
15
+ not reproduce a real user configuration.
@@ -0,0 +1,30 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(reviewer --token INERT_CLAUDE_PERMISSION_SECRET)",
5
+ "WebFetch(domain:research.invalid)",
6
+ "Agent(Explore)",
7
+ "mcp__reviewed__*"
8
+ ],
9
+ "defaultMode": "auto",
10
+ "additionalDirectories": [
11
+ "../INERT_CLAUDE_PERMISSION_PATH"
12
+ ],
13
+ "blockReadsOutsideWorkingDirectories": false
14
+ },
15
+ "env": {
16
+ "API_TOKEN": "INERT_CLAUDE_PERMISSION_SECRET"
17
+ },
18
+ "hooks": {
19
+ "PreToolUse": [
20
+ {
21
+ "hooks": [
22
+ {
23
+ "type": "command",
24
+ "command": "printf INERT_CLAUDE_HOOK_SECRET"
25
+ }
26
+ ]
27
+ }
28
+ ]
29
+ }
30
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "permissions": {
3
+ "ask": [
4
+ "Bash(git status)",
5
+ "Agent(Explore)"
6
+ ],
7
+ "deny": [
8
+ "WebFetch",
9
+ "mcp__unreviewed__*"
10
+ ],
11
+ "defaultMode": "plan",
12
+ "disableBypassPermissionsMode": "disable",
13
+ "disableAutoMode": "disable",
14
+ "blockReadsOutsideWorkingDirectories": true
15
+ }
16
+ }
@@ -0,0 +1,13 @@
1
+ approval_policy = "never"
2
+ approvals_reviewer = "auto_review"
3
+ sandbox_mode = "danger-full-access"
4
+ web_search = "live"
5
+
6
+ [sandbox_workspace_write]
7
+ network_access = true
8
+ writable_roots = ["../INERT_CODEX_PERMISSION_PATH"]
9
+ exclude_slash_tmp = false
10
+ exclude_tmpdir_env_var = false
11
+
12
+ [agents]
13
+ enabled = true
@@ -0,0 +1,13 @@
1
+ approval_policy = "on-request"
2
+ approvals_reviewer = "user"
3
+ sandbox_mode = "read-only"
4
+ web_search = "disabled"
5
+
6
+ [sandbox_workspace_write]
7
+ network_access = false
8
+ writable_roots = []
9
+ exclude_slash_tmp = true
10
+ exclude_tmpdir_env_var = true
11
+
12
+ [agents]
13
+ enabled = false
@@ -0,0 +1,18 @@
1
+ {
2
+ "claude": {
3
+ "restrictiveAction": "ask",
4
+ "expandedAction": "block",
5
+ "diffStatus": "needs-review"
6
+ },
7
+ "codex": {
8
+ "restrictiveAction": "ask",
9
+ "expandedAction": "block",
10
+ "diffStatus": "needs-review"
11
+ },
12
+ "forbiddenOutputMarkers": [
13
+ "INERT_CLAUDE_PERMISSION_SECRET",
14
+ "INERT_CLAUDE_PERMISSION_PATH",
15
+ "INERT_CLAUDE_HOOK_SECRET",
16
+ "INERT_CODEX_PERMISSION_PATH"
17
+ ]
18
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trustdex",
3
- "version": "0.6.0",
3
+ "version": "0.7.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",
12
- "check": "node --check bin/trustdex.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/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",
12
+ "check": "node --check bin/trustdex.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": {
@@ -39,6 +39,7 @@
39
39
  "src",
40
40
  "docs",
41
41
  "examples",
42
+ "schemas",
42
43
  "README.md",
43
44
  "SECURITY.md",
44
45
  "LICENSE"
@@ -0,0 +1,78 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/grigent/trustdex/blob/main/schemas/permission-posture-diff-v1.schema.json",
4
+ "title": "TrustDex permission posture diff v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "runtime",
10
+ "status",
11
+ "baselineDigest",
12
+ "currentDigest",
13
+ "summary",
14
+ "changes"
15
+ ],
16
+ "properties": {
17
+ "schemaVersion": { "const": 1 },
18
+ "runtime": { "enum": ["claude", "codex"] },
19
+ "status": { "enum": ["unchanged", "restricted", "needs-review"] },
20
+ "baselineDigest": { "$ref": "#/$defs/digest" },
21
+ "currentDigest": { "$ref": "#/$defs/digest" },
22
+ "summary": {
23
+ "type": "object",
24
+ "additionalProperties": false,
25
+ "required": ["expansions", "restrictions", "reviews"],
26
+ "properties": {
27
+ "expansions": { "$ref": "#/$defs/count" },
28
+ "restrictions": { "$ref": "#/$defs/count" },
29
+ "reviews": { "$ref": "#/$defs/count" }
30
+ }
31
+ },
32
+ "changes": {
33
+ "type": "array",
34
+ "items": { "$ref": "#/$defs/change" }
35
+ }
36
+ },
37
+ "$defs": {
38
+ "digest": {
39
+ "type": "string",
40
+ "pattern": "^[a-f0-9]{64}$"
41
+ },
42
+ "count": {
43
+ "type": "integer",
44
+ "minimum": 0
45
+ },
46
+ "scalar": {
47
+ "type": ["string", "number", "boolean", "null"]
48
+ },
49
+ "change": {
50
+ "type": "object",
51
+ "additionalProperties": false,
52
+ "required": ["impact", "type", "field"],
53
+ "properties": {
54
+ "impact": { "enum": ["expansion", "restriction", "review"] },
55
+ "type": {
56
+ "enum": [
57
+ "policy-changed",
58
+ "items-added",
59
+ "items-removed",
60
+ "decision-changed",
61
+ "count-changed",
62
+ "boolean-changed",
63
+ "value-changed"
64
+ ]
65
+ },
66
+ "field": { "type": "string" },
67
+ "before": { "$ref": "#/$defs/scalar" },
68
+ "after": { "$ref": "#/$defs/scalar" },
69
+ "items": {
70
+ "type": "array",
71
+ "minItems": 1,
72
+ "uniqueItems": true,
73
+ "items": { "type": "string" }
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
@@ -0,0 +1,162 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/grigent/trustdex/blob/main/schemas/permission-posture-v1.schema.json",
4
+ "title": "TrustDex permission posture snapshot v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "kind",
10
+ "createdAt",
11
+ "runtime",
12
+ "policyDigest",
13
+ "posture",
14
+ "digest"
15
+ ],
16
+ "properties": {
17
+ "schemaVersion": { "const": 1 },
18
+ "kind": { "const": "agent-permission-posture" },
19
+ "createdAt": { "type": "string", "format": "date-time" },
20
+ "runtime": { "enum": ["claude", "codex"] },
21
+ "policyDigest": { "$ref": "#/$defs/digest" },
22
+ "digest": { "$ref": "#/$defs/digest" },
23
+ "posture": {
24
+ "type": "object",
25
+ "additionalProperties": false,
26
+ "required": ["action", "signals", "metadata"],
27
+ "properties": {
28
+ "action": { "enum": ["allow", "ask", "block"] },
29
+ "signals": {
30
+ "type": "array",
31
+ "uniqueItems": true,
32
+ "items": { "type": "string" }
33
+ },
34
+ "metadata": { "type": "object" }
35
+ }
36
+ }
37
+ },
38
+ "allOf": [
39
+ {
40
+ "if": { "properties": { "runtime": { "const": "claude" } } },
41
+ "then": {
42
+ "properties": {
43
+ "posture": {
44
+ "properties": {
45
+ "metadata": { "$ref": "#/$defs/claudeMetadata" }
46
+ }
47
+ }
48
+ }
49
+ }
50
+ },
51
+ {
52
+ "if": { "properties": { "runtime": { "const": "codex" } } },
53
+ "then": {
54
+ "properties": {
55
+ "posture": {
56
+ "properties": {
57
+ "metadata": { "$ref": "#/$defs/codexMetadata" }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ ],
64
+ "$defs": {
65
+ "digest": {
66
+ "type": "string",
67
+ "pattern": "^[a-f0-9]{64}$"
68
+ },
69
+ "count": {
70
+ "type": "integer",
71
+ "minimum": 0
72
+ },
73
+ "claudeMetadata": {
74
+ "type": "object",
75
+ "additionalProperties": false,
76
+ "required": [
77
+ "defaultMode",
78
+ "allowRuleCount",
79
+ "askRuleCount",
80
+ "denyRuleCount",
81
+ "allowCategories",
82
+ "additionalDirectoryCount",
83
+ "bypassDisabled",
84
+ "autoModeDisabled",
85
+ "outsideReadsBlocked",
86
+ "uninspectedRootKeyCount"
87
+ ],
88
+ "properties": {
89
+ "defaultMode": {
90
+ "type": ["string", "null"],
91
+ "enum": [null, "default", "manual", "acceptEdits", "plan", "dontAsk", "bypassPermissions", "auto"]
92
+ },
93
+ "allowRuleCount": { "$ref": "#/$defs/count" },
94
+ "askRuleCount": { "$ref": "#/$defs/count" },
95
+ "denyRuleCount": { "$ref": "#/$defs/count" },
96
+ "allowCategories": {
97
+ "type": "array",
98
+ "uniqueItems": true,
99
+ "items": { "enum": ["filesystem", "mcp", "network", "other", "shell", "subagent"] }
100
+ },
101
+ "additionalDirectoryCount": { "$ref": "#/$defs/count" },
102
+ "bypassDisabled": { "type": "boolean" },
103
+ "autoModeDisabled": { "type": "boolean" },
104
+ "outsideReadsBlocked": { "type": "boolean" },
105
+ "uninspectedRootKeyCount": { "$ref": "#/$defs/count" }
106
+ }
107
+ },
108
+ "codexMetadata": {
109
+ "type": "object",
110
+ "additionalProperties": false,
111
+ "required": [
112
+ "approvalPolicy",
113
+ "granularPromptCategories",
114
+ "approvalsReviewer",
115
+ "sandboxMode",
116
+ "defaultPermissionsKind",
117
+ "webSearch",
118
+ "networkAccess",
119
+ "additionalWritableRootCount",
120
+ "tempRootsExcluded",
121
+ "subagentsEnabled",
122
+ "uninspectedAgentKeyCount",
123
+ "uninspectedRootKeyCount",
124
+ "uninspectedSectionKindCount"
125
+ ],
126
+ "properties": {
127
+ "approvalPolicy": {
128
+ "type": ["string", "null"],
129
+ "enum": [null, "on-request", "never", "granular"]
130
+ },
131
+ "granularPromptCategories": {
132
+ "type": "array",
133
+ "uniqueItems": true,
134
+ "items": { "enum": ["mcp_elicitations", "request_permissions", "rules", "sandbox_approval", "skill_approval"] }
135
+ },
136
+ "approvalsReviewer": {
137
+ "type": ["string", "null"],
138
+ "enum": [null, "user", "auto_review"]
139
+ },
140
+ "sandboxMode": {
141
+ "type": ["string", "null"],
142
+ "enum": [null, "read-only", "workspace-write", "danger-full-access"]
143
+ },
144
+ "defaultPermissionsKind": {
145
+ "type": ["string", "null"],
146
+ "enum": [null, ":read-only", ":workspace", ":danger-full-access", "custom"]
147
+ },
148
+ "webSearch": {
149
+ "type": ["string", "null"],
150
+ "enum": [null, "disabled", "cached", "indexed", "live"]
151
+ },
152
+ "networkAccess": { "type": "boolean" },
153
+ "additionalWritableRootCount": { "$ref": "#/$defs/count" },
154
+ "tempRootsExcluded": { "type": "boolean" },
155
+ "subagentsEnabled": { "type": "boolean" },
156
+ "uninspectedAgentKeyCount": { "$ref": "#/$defs/count" },
157
+ "uninspectedRootKeyCount": { "$ref": "#/$defs/count" },
158
+ "uninspectedSectionKindCount": { "$ref": "#/$defs/count" }
159
+ }
160
+ }
161
+ }
162
+ }