tibet-keychain 0.1.0__tar.gz

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.
@@ -0,0 +1 @@
1
+ MIT License — Copyright (c) 2026 Humotica, Jasper van de Meent, Root AI, Codex
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.4
2
+ Name: tibet-keychain
3
+ Version: 0.1.0
4
+ Summary: Causal-aware secret custody — where secrets live, how they moved, who touched them. Part of the TIBET vault family (tibet-vault = WHEN, tibet-keychain = WHERE/HOW, tibet-sam = WHY, tibet-gateway = where ACT is performed).
5
+ Author-email: Jasper van de Meent <info@humotica.com>, Root AI <root_idd@humotica.nl>, Codex <codex@humotica.nl>
6
+ License: MIT
7
+ Project-URL: Homepage, https://humotica.com
8
+ Project-URL: Repository, https://github.com/jaspertvdm/tibet-keychain
9
+ Keywords: tibet,keychain,secret-custody,vault,credential,causal,audit,rotation,exposure,cbom
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Information Technology
13
+ Classifier: Intended Audience :: System Administrators
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Security :: Cryptography
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: cryptography>=42.0
27
+ Provides-Extra: sealed
28
+ Requires-Dist: tibet-drop>=0.3.0; extra == "sealed"
29
+ Provides-Extra: cbom
30
+ Requires-Dist: tibet-cbom>=0.1.1; extra == "cbom"
31
+ Provides-Extra: full
32
+ Requires-Dist: tibet-drop>=0.3.0; extra == "full"
33
+ Requires-Dist: tibet-cbom>=0.1.1; extra == "full"
34
+ Dynamic: license-file
35
+
36
+ # tibet-keychain
37
+
38
+ > **Causal-aware secret custody — where secrets live, how they moved, who touched them.**
39
+
40
+ `tibet-keychain` is part of the **TIBET vault family** — four primitives
41
+ that answer four different questions about secrets, keys, tokens, and
42
+ credentials:
43
+
44
+ ```
45
+ ═══════════════════════════════════════════════════════════════
46
+ THE VAULT FAMILY
47
+ ═══════════════════════════════════════════════════════════════
48
+
49
+ tibet-vault WHEN temporal trigger
50
+ "release on date / dead-man-switch"
51
+
52
+ tibet-keychain WHERE/HOW custody + timeline ← this package
53
+ "where this secret lives, how it moved"
54
+
55
+ tibet-sam WHY intent + scope authorization
56
+ "why this one specific act is allowed"
57
+
58
+ tibet-gateway WHERE-EXEC execution boundary
59
+ "where the act is safely performed"
60
+ ═══════════════════════════════════════════════════════════════
61
+ ```
62
+
63
+ ## Why a separate keychain primitive?
64
+
65
+ Traditional secret stores answer:
66
+
67
+ - where is the key
68
+ - can this caller read it
69
+
70
+ `tibet-keychain` answers:
71
+
72
+ - where is the key (still)
73
+ - **how did it get here** (= causal history)
74
+ - **who touched it** (= custody timeline)
75
+ - **was it exposed** (= rotation triggers)
76
+ - **how does the chain walk back** (= CBOM-compatible)
77
+
78
+ That makes `tibet-keychain` the natural foundation for any system
79
+ that has to prove not only "I have the key" but "I know exactly
80
+ how this key entered my custody, who touched it on the way, and
81
+ under which authority each transition happened".
82
+
83
+ ## Core idea
84
+
85
+ Each secret is stored as a sealed `.tza` continuity object with:
86
+
87
+ - encrypted secret payload (= the actual material)
88
+ - vault-metadata (issuer / scope / created_at / expires_at)
89
+ - custody-transition (owner ↔ custodian ↔ active-operator)
90
+ - exposure_state + rotation_required flag
91
+ - timeline of all `secret-*` events
92
+
93
+ The secret material itself is encrypted and tightly scoped. The
94
+ surrounding continuity metadata remains auditable.
95
+
96
+ ## Secret types
97
+
98
+ ```
99
+ api_key oauth_token signing_key
100
+ service_account_cred pypi_token crates_token
101
+ github_pat ssh_key root_password
102
+ smart_contract_signer tls_cert webhook_signer
103
+ ```
104
+
105
+ ## Timeline events
106
+
107
+ ```
108
+ secret-created secret-imported secret-sealed
109
+ secret-unsealed secret-proxied secret-delegated
110
+ secret-exposed secret-rotated secret-revoked
111
+ secret-archived
112
+ ```
113
+
114
+ Each event carries:
115
+
116
+ - actor identity (= who)
117
+ - action_id + parent_action_id (= chain link)
118
+ - timestamp
119
+ - actor class (= human / machine / external / mcp-server / gateway / system)
120
+ - relevant policy decisions (= scope / authority-shift)
121
+
122
+ ## Coupling with the rest of the family
123
+
124
+ ```
125
+ tibet-keychain
126
+ (custody, timeline)
127
+
128
+ ↓ secret-proxied event
129
+
130
+ ┌───────────────────────┴───────────────────────┐
131
+ ▼ ▼
132
+ tibet-sam tibet-gateway
133
+ (why this act is OK) (where it happens)
134
+ ↓ ↑
135
+ intent + scope break-seal,
136
+ constraint sealed execute,
137
+ in one-shot .tza destroy-session
138
+ ↓ ↑
139
+ └─────────── handed to ──────────────────────────┘
140
+
141
+ tibet-continuityd
142
+ audit JSONL
143
+
144
+ tibet-cbom
145
+ timeline walk
146
+ ```
147
+
148
+ ## Why this beats traditional secret stores
149
+
150
+ | Property | HashiCorp Vault | tibet-keychain |
151
+ |--------------------------------|-----------------|----------------|
152
+ | Encrypted at rest | ✓ | ✓ |
153
+ | ACL / policy controlled | ✓ | ✓ |
154
+ | Causal history of secret | ✗ | ✓ |
155
+ | Custody-transition chain | ✗ | ✓ |
156
+ | Exposure events recorded | partial | ✓ |
157
+ | Audit walkable cross-bundle | ✗ | ✓ |
158
+ | Identity-bound rotation chain | ✗ | ✓ |
159
+ | Regulator-auditable timeline | partial | ✓ |
160
+
161
+ ## Use cases
162
+
163
+ **Infrastructure**: SSH keys, database credentials, root access —
164
+ all stored with custody chain, rotated through signed transitions.
165
+
166
+ **Agent workflows**: PyPI tokens, crates.io tokens, GitHub PATs —
167
+ agents never see them; they request a SAM capsule that the gateway
168
+ executes against, the keychain logs the request.
169
+
170
+ **Smart contracts**: signing keys with explicit "who can request a
171
+ signing capsule for which contract address" policy, every signing
172
+ event in the timeline.
173
+
174
+ **Compliance evidence**: regulator asks "who could have signed this?
175
+ who actually did?" — the keychain timeline answers both.
176
+
177
+ ## Install
178
+
179
+ ```bash
180
+ pip install tibet-keychain[full]
181
+ ```
182
+
183
+ This pulls `tibet-drop` (= sealed envelope substrate) and `tibet-cbom`
184
+ (= timeline renderer) as soft dependencies.
185
+
186
+ ## Status
187
+
188
+ **v0.1.0** — package skeleton + spec. Implementation track for full
189
+ secret storage + sealed-bundle integration follows; designed to land
190
+ in time for IETF spec referencing and Marco van Hurne / W3C demos.
191
+
192
+ Spec source: `/srv/jtel-stack/hersenspinsels/tibet-vault-key-custody-and-sealed-secret-timeline-2026-05-12.md`
193
+
194
+ ## License
195
+
196
+ MIT — Humotica + Root AI + Codex (2026)
@@ -0,0 +1,161 @@
1
+ # tibet-keychain
2
+
3
+ > **Causal-aware secret custody — where secrets live, how they moved, who touched them.**
4
+
5
+ `tibet-keychain` is part of the **TIBET vault family** — four primitives
6
+ that answer four different questions about secrets, keys, tokens, and
7
+ credentials:
8
+
9
+ ```
10
+ ═══════════════════════════════════════════════════════════════
11
+ THE VAULT FAMILY
12
+ ═══════════════════════════════════════════════════════════════
13
+
14
+ tibet-vault WHEN temporal trigger
15
+ "release on date / dead-man-switch"
16
+
17
+ tibet-keychain WHERE/HOW custody + timeline ← this package
18
+ "where this secret lives, how it moved"
19
+
20
+ tibet-sam WHY intent + scope authorization
21
+ "why this one specific act is allowed"
22
+
23
+ tibet-gateway WHERE-EXEC execution boundary
24
+ "where the act is safely performed"
25
+ ═══════════════════════════════════════════════════════════════
26
+ ```
27
+
28
+ ## Why a separate keychain primitive?
29
+
30
+ Traditional secret stores answer:
31
+
32
+ - where is the key
33
+ - can this caller read it
34
+
35
+ `tibet-keychain` answers:
36
+
37
+ - where is the key (still)
38
+ - **how did it get here** (= causal history)
39
+ - **who touched it** (= custody timeline)
40
+ - **was it exposed** (= rotation triggers)
41
+ - **how does the chain walk back** (= CBOM-compatible)
42
+
43
+ That makes `tibet-keychain` the natural foundation for any system
44
+ that has to prove not only "I have the key" but "I know exactly
45
+ how this key entered my custody, who touched it on the way, and
46
+ under which authority each transition happened".
47
+
48
+ ## Core idea
49
+
50
+ Each secret is stored as a sealed `.tza` continuity object with:
51
+
52
+ - encrypted secret payload (= the actual material)
53
+ - vault-metadata (issuer / scope / created_at / expires_at)
54
+ - custody-transition (owner ↔ custodian ↔ active-operator)
55
+ - exposure_state + rotation_required flag
56
+ - timeline of all `secret-*` events
57
+
58
+ The secret material itself is encrypted and tightly scoped. The
59
+ surrounding continuity metadata remains auditable.
60
+
61
+ ## Secret types
62
+
63
+ ```
64
+ api_key oauth_token signing_key
65
+ service_account_cred pypi_token crates_token
66
+ github_pat ssh_key root_password
67
+ smart_contract_signer tls_cert webhook_signer
68
+ ```
69
+
70
+ ## Timeline events
71
+
72
+ ```
73
+ secret-created secret-imported secret-sealed
74
+ secret-unsealed secret-proxied secret-delegated
75
+ secret-exposed secret-rotated secret-revoked
76
+ secret-archived
77
+ ```
78
+
79
+ Each event carries:
80
+
81
+ - actor identity (= who)
82
+ - action_id + parent_action_id (= chain link)
83
+ - timestamp
84
+ - actor class (= human / machine / external / mcp-server / gateway / system)
85
+ - relevant policy decisions (= scope / authority-shift)
86
+
87
+ ## Coupling with the rest of the family
88
+
89
+ ```
90
+ tibet-keychain
91
+ (custody, timeline)
92
+
93
+ ↓ secret-proxied event
94
+
95
+ ┌───────────────────────┴───────────────────────┐
96
+ ▼ ▼
97
+ tibet-sam tibet-gateway
98
+ (why this act is OK) (where it happens)
99
+ ↓ ↑
100
+ intent + scope break-seal,
101
+ constraint sealed execute,
102
+ in one-shot .tza destroy-session
103
+ ↓ ↑
104
+ └─────────── handed to ──────────────────────────┘
105
+
106
+ tibet-continuityd
107
+ audit JSONL
108
+
109
+ tibet-cbom
110
+ timeline walk
111
+ ```
112
+
113
+ ## Why this beats traditional secret stores
114
+
115
+ | Property | HashiCorp Vault | tibet-keychain |
116
+ |--------------------------------|-----------------|----------------|
117
+ | Encrypted at rest | ✓ | ✓ |
118
+ | ACL / policy controlled | ✓ | ✓ |
119
+ | Causal history of secret | ✗ | ✓ |
120
+ | Custody-transition chain | ✗ | ✓ |
121
+ | Exposure events recorded | partial | ✓ |
122
+ | Audit walkable cross-bundle | ✗ | ✓ |
123
+ | Identity-bound rotation chain | ✗ | ✓ |
124
+ | Regulator-auditable timeline | partial | ✓ |
125
+
126
+ ## Use cases
127
+
128
+ **Infrastructure**: SSH keys, database credentials, root access —
129
+ all stored with custody chain, rotated through signed transitions.
130
+
131
+ **Agent workflows**: PyPI tokens, crates.io tokens, GitHub PATs —
132
+ agents never see them; they request a SAM capsule that the gateway
133
+ executes against, the keychain logs the request.
134
+
135
+ **Smart contracts**: signing keys with explicit "who can request a
136
+ signing capsule for which contract address" policy, every signing
137
+ event in the timeline.
138
+
139
+ **Compliance evidence**: regulator asks "who could have signed this?
140
+ who actually did?" — the keychain timeline answers both.
141
+
142
+ ## Install
143
+
144
+ ```bash
145
+ pip install tibet-keychain[full]
146
+ ```
147
+
148
+ This pulls `tibet-drop` (= sealed envelope substrate) and `tibet-cbom`
149
+ (= timeline renderer) as soft dependencies.
150
+
151
+ ## Status
152
+
153
+ **v0.1.0** — package skeleton + spec. Implementation track for full
154
+ secret storage + sealed-bundle integration follows; designed to land
155
+ in time for IETF spec referencing and Marco van Hurne / W3C demos.
156
+
157
+ Spec source: `/srv/jtel-stack/hersenspinsels/tibet-vault-key-custody-and-sealed-secret-timeline-2026-05-12.md`
158
+
159
+ ## License
160
+
161
+ MIT — Humotica + Root AI + Codex (2026)
@@ -0,0 +1,61 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "tibet-keychain"
7
+ version = "0.1.0"
8
+ description = "Causal-aware secret custody — where secrets live, how they moved, who touched them. Part of the TIBET vault family (tibet-vault = WHEN, tibet-keychain = WHERE/HOW, tibet-sam = WHY, tibet-gateway = where ACT is performed)."
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ {name = "Jasper van de Meent", email = "info@humotica.com"},
14
+ {name = "Root AI", email = "root_idd@humotica.nl"},
15
+ {name = "Codex", email = "codex@humotica.nl"},
16
+ ]
17
+ keywords = [
18
+ "tibet", "keychain", "secret-custody", "vault", "credential",
19
+ "causal", "audit", "rotation", "exposure", "cbom",
20
+ ]
21
+ classifiers = [
22
+ "Development Status :: 4 - Beta",
23
+ "Intended Audience :: Developers",
24
+ "Intended Audience :: Information Technology",
25
+ "Intended Audience :: System Administrators",
26
+ "License :: OSI Approved :: MIT License",
27
+ "Operating System :: OS Independent",
28
+ "Programming Language :: Python :: 3",
29
+ "Programming Language :: Python :: 3.10",
30
+ "Programming Language :: Python :: 3.11",
31
+ "Programming Language :: Python :: 3.12",
32
+ "Programming Language :: Python :: 3.13",
33
+ "Topic :: Security :: Cryptography",
34
+ "Topic :: Software Development :: Libraries :: Python Modules",
35
+ ]
36
+ dependencies = [
37
+ "cryptography>=42.0",
38
+ ]
39
+
40
+ [project.optional-dependencies]
41
+ # Bridge to tibet-drop for sealed envelope storage
42
+ sealed = [
43
+ "tibet-drop>=0.3.0",
44
+ ]
45
+ # Bridge to tibet-cbom for timeline rendering
46
+ cbom = [
47
+ "tibet-cbom>=0.1.1",
48
+ ]
49
+ # Full stack
50
+ full = [
51
+ "tibet-drop>=0.3.0",
52
+ "tibet-cbom>=0.1.1",
53
+ ]
54
+
55
+ [project.scripts]
56
+ tibet-keychain = "tibet_keychain.cli:main"
57
+ tkc = "tibet_keychain.cli:main"
58
+
59
+ [project.urls]
60
+ Homepage = "https://humotica.com"
61
+ Repository = "https://github.com/jaspertvdm/tibet-keychain"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,43 @@
1
+ """
2
+ tibet-keychain — Causal-aware secret custody.
3
+
4
+ Part of the TIBET vault family:
5
+ tibet-vault WHEN temporal trigger
6
+ tibet-keychain WHERE/HOW custody + timeline ← this package
7
+ tibet-sam WHY intent + scope
8
+ tibet-gateway WHERE-EXEC execution boundary
9
+
10
+ Naming decision Jasper van de Meent 12 May 2026:
11
+ "tibet-vault = when
12
+ tibet-keychain = where/how secret lives
13
+ tibet-sam = why this one act is allowed
14
+ tibet-gateway = where the act is performed safely"
15
+
16
+ Spec source:
17
+ /srv/jtel-stack/hersenspinsels/tibet-vault-key-custody-and-sealed-secret-timeline-2026-05-12.md
18
+ """
19
+ from __future__ import annotations
20
+
21
+ from .types import (
22
+ SecretType,
23
+ SecretTimelineEvent,
24
+ ActorClass,
25
+ ExposureState,
26
+ SecretRecord,
27
+ CustodyTransition,
28
+ )
29
+
30
+
31
+ __version__ = "0.1.0"
32
+ __author__ = "Jasper van de Meent, Root AI, Codex"
33
+
34
+
35
+ __all__ = [
36
+ "__version__",
37
+ "SecretType",
38
+ "SecretTimelineEvent",
39
+ "ActorClass",
40
+ "ExposureState",
41
+ "SecretRecord",
42
+ "CustodyTransition",
43
+ ]
@@ -0,0 +1,88 @@
1
+ """
2
+ tibet-keychain CLI — list / show / events / explain.
3
+
4
+ This v0.1.0 CLI is type-only: it inspects records and prints
5
+ human-readable views. Storage backend, sealed-bundle integration,
6
+ and rotation flow follow in v0.2+ once design lands with tibet-sam
7
+ and tibet-gateway.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import json
13
+ import sys
14
+
15
+ from . import __version__, SecretType, SecretTimelineEvent, ActorClass
16
+
17
+
18
+ def _cmd_types(args):
19
+ """List the vocabulary."""
20
+ print(f"tibet-keychain {__version__}")
21
+ print()
22
+ print(f"Secret types ({len(list(SecretType))}):")
23
+ for t in SecretType:
24
+ print(f" {t.value}")
25
+ print()
26
+ print(f"Timeline events ({len(list(SecretTimelineEvent))}):")
27
+ for e in SecretTimelineEvent:
28
+ print(f" {e.value}")
29
+ print()
30
+ print(f"Actor classes ({len(list(ActorClass))}):")
31
+ for a in ActorClass:
32
+ print(f" {a.value}")
33
+ return 0
34
+
35
+
36
+ def _cmd_family(args):
37
+ """Print the vault family overview."""
38
+ print("""
39
+ ══════════════════════════════════════════════════════════════════
40
+ THE TIBET VAULT FAMILY
41
+ ══════════════════════════════════════════════════════════════════
42
+
43
+ tibet-vault WHEN temporal trigger
44
+ "release on date / dead-man-switch"
45
+
46
+ tibet-keychain WHERE/HOW custody + timeline ← you are here
47
+ "where this secret lives, how it moved"
48
+
49
+ tibet-sam WHY intent + scope authorization
50
+ "why this one specific act is allowed"
51
+
52
+ tibet-gateway WHERE-EXEC execution boundary
53
+ "where the act is safely performed"
54
+
55
+ ══════════════════════════════════════════════════════════════════
56
+ """)
57
+ return 0
58
+
59
+
60
+ def main(argv=None):
61
+ parser = argparse.ArgumentParser(
62
+ prog="tibet-keychain",
63
+ description=(
64
+ "Causal-aware secret custody. Part of the TIBET vault "
65
+ "family (vault / keychain / sam / gateway)."
66
+ ),
67
+ )
68
+ parser.add_argument(
69
+ "-V", "--version", action="version",
70
+ version=f"tibet-keychain {__version__}",
71
+ )
72
+ sub = parser.add_subparsers(dest="cmd")
73
+
74
+ p_types = sub.add_parser("types", help="List vocabulary (secret types, events, actor classes)")
75
+ p_types.set_defaults(func=_cmd_types)
76
+
77
+ p_family = sub.add_parser("family", help="Show the TIBET vault family overview")
78
+ p_family.set_defaults(func=_cmd_family)
79
+
80
+ args = parser.parse_args(argv)
81
+ if not args.cmd:
82
+ parser.print_help()
83
+ return 0
84
+ return args.func(args)
85
+
86
+
87
+ if __name__ == "__main__":
88
+ sys.exit(main())
@@ -0,0 +1,120 @@
1
+ """
2
+ Core types for tibet-keychain.
3
+
4
+ Defines the vocabulary used across the package: secret types, timeline
5
+ event types, actor classes, exposure states, and the two main records
6
+ (SecretRecord and CustodyTransition).
7
+ """
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass, field
11
+ from enum import Enum
12
+ from typing import Optional
13
+
14
+
15
+ class SecretType(str, Enum):
16
+ """Recognised secret-material classes.
17
+
18
+ The TIBET vault family does not invent new credential formats —
19
+ it provides a custody substrate around existing ones.
20
+ """
21
+ API_KEY = "api_key"
22
+ OAUTH_TOKEN = "oauth_token"
23
+ SIGNING_KEY = "signing_key"
24
+ SERVICE_ACCOUNT_CREDENTIAL = "service_account_credential"
25
+ PYPI_TOKEN = "pypi_token"
26
+ CRATES_TOKEN = "crates_token"
27
+ GITHUB_PAT = "github_pat"
28
+ SSH_KEY = "ssh_key"
29
+ ROOT_PASSWORD = "root_password"
30
+ SMART_CONTRACT_SIGNER = "smart_contract_signer"
31
+ TLS_CERT = "tls_cert"
32
+ WEBHOOK_SIGNER = "webhook_signer"
33
+
34
+
35
+ class SecretTimelineEvent(str, Enum):
36
+ """Every meaningful state change a secret can go through.
37
+
38
+ The keychain's value is precisely that every one of these events
39
+ is recorded with actor / authority / parent_action_id, making the
40
+ custody chain walkable from any point in time.
41
+ """
42
+ CREATED = "secret-created"
43
+ IMPORTED = "secret-imported"
44
+ SEALED = "secret-sealed"
45
+ UNSEALED = "secret-unsealed"
46
+ PROXIED = "secret-proxied"
47
+ DELEGATED = "secret-delegated"
48
+ EXPOSED = "secret-exposed"
49
+ ROTATED = "secret-rotated"
50
+ REVOKED = "secret-revoked"
51
+ ARCHIVED = "secret-archived"
52
+
53
+
54
+ class ActorClass(str, Enum):
55
+ """Who touched the secret. Not every actor is equal.
56
+
57
+ A timeline that records HUMAN unsealing has different policy
58
+ implications than one that records GATEWAY proxying.
59
+ """
60
+ HUMAN = "human"
61
+ MACHINE = "machine"
62
+ EXTERNAL = "external"
63
+ MCP_SERVER = "mcp-server"
64
+ GATEWAY = "gateway"
65
+ SYSTEM = "system"
66
+
67
+
68
+ class ExposureState(str, Enum):
69
+ """Current exposure assessment of the secret material."""
70
+ SEALED = "sealed"
71
+ IN_USE = "in-use"
72
+ CHAT_DISCLOSED = "chat-disclosed"
73
+ GIT_LEAKED = "git-leaked"
74
+ LOG_LEAKED = "log-leaked"
75
+ SUSPECTED = "suspected"
76
+ ROTATED = "rotated"
77
+
78
+
79
+ @dataclass
80
+ class SecretRecord:
81
+ """The metadata view of a secret in the keychain.
82
+
83
+ The actual secret material lives inside a sealed `.tza` payload
84
+ block; this record is the auditable metadata projection.
85
+ """
86
+ secret_id: str
87
+ secret_type: SecretType
88
+ issuer: str # who minted the underlying credential
89
+ scope: str # what it is allowed to authorise
90
+ created_at: str # RFC3339
91
+ expires_at: Optional[str] = None
92
+ owner_id: Optional[str] = None # JIS-DID of nominal owner
93
+ custodian_id: Optional[str] = None # who currently holds it
94
+ active_operator_id: Optional[str] = None # who is allowed to use it
95
+ last_access_action_id: Optional[str] = None
96
+ last_rotation_action_id: Optional[str] = None
97
+ exposure_state: ExposureState = ExposureState.SEALED
98
+ rotation_required: bool = False
99
+ notes: list[str] = field(default_factory=list)
100
+
101
+
102
+ @dataclass
103
+ class CustodyTransition:
104
+ """A single transition in a secret's custody timeline.
105
+
106
+ Mirrors the shape of tibet-cbom ownership-transition events so
107
+ that keychain transitions can be walked by `tcbom timeline`
108
+ when an audit-file is supplied.
109
+ """
110
+ action_id: str
111
+ parent_action_id: Optional[str]
112
+ secret_id: str
113
+ event: SecretTimelineEvent
114
+ actor_id: str
115
+ actor_class: ActorClass
116
+ timestamp: str # RFC3339
117
+ reason: str = ""
118
+ authority_mode: str = "system" # agent / admin / triage / shared / system
119
+ target_assignee: Optional[str] = None
120
+ policy_lane: Optional[str] = None
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.4
2
+ Name: tibet-keychain
3
+ Version: 0.1.0
4
+ Summary: Causal-aware secret custody — where secrets live, how they moved, who touched them. Part of the TIBET vault family (tibet-vault = WHEN, tibet-keychain = WHERE/HOW, tibet-sam = WHY, tibet-gateway = where ACT is performed).
5
+ Author-email: Jasper van de Meent <info@humotica.com>, Root AI <root_idd@humotica.nl>, Codex <codex@humotica.nl>
6
+ License: MIT
7
+ Project-URL: Homepage, https://humotica.com
8
+ Project-URL: Repository, https://github.com/jaspertvdm/tibet-keychain
9
+ Keywords: tibet,keychain,secret-custody,vault,credential,causal,audit,rotation,exposure,cbom
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Information Technology
13
+ Classifier: Intended Audience :: System Administrators
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Security :: Cryptography
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: cryptography>=42.0
27
+ Provides-Extra: sealed
28
+ Requires-Dist: tibet-drop>=0.3.0; extra == "sealed"
29
+ Provides-Extra: cbom
30
+ Requires-Dist: tibet-cbom>=0.1.1; extra == "cbom"
31
+ Provides-Extra: full
32
+ Requires-Dist: tibet-drop>=0.3.0; extra == "full"
33
+ Requires-Dist: tibet-cbom>=0.1.1; extra == "full"
34
+ Dynamic: license-file
35
+
36
+ # tibet-keychain
37
+
38
+ > **Causal-aware secret custody — where secrets live, how they moved, who touched them.**
39
+
40
+ `tibet-keychain` is part of the **TIBET vault family** — four primitives
41
+ that answer four different questions about secrets, keys, tokens, and
42
+ credentials:
43
+
44
+ ```
45
+ ═══════════════════════════════════════════════════════════════
46
+ THE VAULT FAMILY
47
+ ═══════════════════════════════════════════════════════════════
48
+
49
+ tibet-vault WHEN temporal trigger
50
+ "release on date / dead-man-switch"
51
+
52
+ tibet-keychain WHERE/HOW custody + timeline ← this package
53
+ "where this secret lives, how it moved"
54
+
55
+ tibet-sam WHY intent + scope authorization
56
+ "why this one specific act is allowed"
57
+
58
+ tibet-gateway WHERE-EXEC execution boundary
59
+ "where the act is safely performed"
60
+ ═══════════════════════════════════════════════════════════════
61
+ ```
62
+
63
+ ## Why a separate keychain primitive?
64
+
65
+ Traditional secret stores answer:
66
+
67
+ - where is the key
68
+ - can this caller read it
69
+
70
+ `tibet-keychain` answers:
71
+
72
+ - where is the key (still)
73
+ - **how did it get here** (= causal history)
74
+ - **who touched it** (= custody timeline)
75
+ - **was it exposed** (= rotation triggers)
76
+ - **how does the chain walk back** (= CBOM-compatible)
77
+
78
+ That makes `tibet-keychain` the natural foundation for any system
79
+ that has to prove not only "I have the key" but "I know exactly
80
+ how this key entered my custody, who touched it on the way, and
81
+ under which authority each transition happened".
82
+
83
+ ## Core idea
84
+
85
+ Each secret is stored as a sealed `.tza` continuity object with:
86
+
87
+ - encrypted secret payload (= the actual material)
88
+ - vault-metadata (issuer / scope / created_at / expires_at)
89
+ - custody-transition (owner ↔ custodian ↔ active-operator)
90
+ - exposure_state + rotation_required flag
91
+ - timeline of all `secret-*` events
92
+
93
+ The secret material itself is encrypted and tightly scoped. The
94
+ surrounding continuity metadata remains auditable.
95
+
96
+ ## Secret types
97
+
98
+ ```
99
+ api_key oauth_token signing_key
100
+ service_account_cred pypi_token crates_token
101
+ github_pat ssh_key root_password
102
+ smart_contract_signer tls_cert webhook_signer
103
+ ```
104
+
105
+ ## Timeline events
106
+
107
+ ```
108
+ secret-created secret-imported secret-sealed
109
+ secret-unsealed secret-proxied secret-delegated
110
+ secret-exposed secret-rotated secret-revoked
111
+ secret-archived
112
+ ```
113
+
114
+ Each event carries:
115
+
116
+ - actor identity (= who)
117
+ - action_id + parent_action_id (= chain link)
118
+ - timestamp
119
+ - actor class (= human / machine / external / mcp-server / gateway / system)
120
+ - relevant policy decisions (= scope / authority-shift)
121
+
122
+ ## Coupling with the rest of the family
123
+
124
+ ```
125
+ tibet-keychain
126
+ (custody, timeline)
127
+
128
+ ↓ secret-proxied event
129
+
130
+ ┌───────────────────────┴───────────────────────┐
131
+ ▼ ▼
132
+ tibet-sam tibet-gateway
133
+ (why this act is OK) (where it happens)
134
+ ↓ ↑
135
+ intent + scope break-seal,
136
+ constraint sealed execute,
137
+ in one-shot .tza destroy-session
138
+ ↓ ↑
139
+ └─────────── handed to ──────────────────────────┘
140
+
141
+ tibet-continuityd
142
+ audit JSONL
143
+
144
+ tibet-cbom
145
+ timeline walk
146
+ ```
147
+
148
+ ## Why this beats traditional secret stores
149
+
150
+ | Property | HashiCorp Vault | tibet-keychain |
151
+ |--------------------------------|-----------------|----------------|
152
+ | Encrypted at rest | ✓ | ✓ |
153
+ | ACL / policy controlled | ✓ | ✓ |
154
+ | Causal history of secret | ✗ | ✓ |
155
+ | Custody-transition chain | ✗ | ✓ |
156
+ | Exposure events recorded | partial | ✓ |
157
+ | Audit walkable cross-bundle | ✗ | ✓ |
158
+ | Identity-bound rotation chain | ✗ | ✓ |
159
+ | Regulator-auditable timeline | partial | ✓ |
160
+
161
+ ## Use cases
162
+
163
+ **Infrastructure**: SSH keys, database credentials, root access —
164
+ all stored with custody chain, rotated through signed transitions.
165
+
166
+ **Agent workflows**: PyPI tokens, crates.io tokens, GitHub PATs —
167
+ agents never see them; they request a SAM capsule that the gateway
168
+ executes against, the keychain logs the request.
169
+
170
+ **Smart contracts**: signing keys with explicit "who can request a
171
+ signing capsule for which contract address" policy, every signing
172
+ event in the timeline.
173
+
174
+ **Compliance evidence**: regulator asks "who could have signed this?
175
+ who actually did?" — the keychain timeline answers both.
176
+
177
+ ## Install
178
+
179
+ ```bash
180
+ pip install tibet-keychain[full]
181
+ ```
182
+
183
+ This pulls `tibet-drop` (= sealed envelope substrate) and `tibet-cbom`
184
+ (= timeline renderer) as soft dependencies.
185
+
186
+ ## Status
187
+
188
+ **v0.1.0** — package skeleton + spec. Implementation track for full
189
+ secret storage + sealed-bundle integration follows; designed to land
190
+ in time for IETF spec referencing and Marco van Hurne / W3C demos.
191
+
192
+ Spec source: `/srv/jtel-stack/hersenspinsels/tibet-vault-key-custody-and-sealed-secret-timeline-2026-05-12.md`
193
+
194
+ ## License
195
+
196
+ MIT — Humotica + Root AI + Codex (2026)
@@ -0,0 +1,12 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/tibet_keychain/__init__.py
5
+ src/tibet_keychain/cli.py
6
+ src/tibet_keychain/types.py
7
+ src/tibet_keychain.egg-info/PKG-INFO
8
+ src/tibet_keychain.egg-info/SOURCES.txt
9
+ src/tibet_keychain.egg-info/dependency_links.txt
10
+ src/tibet_keychain.egg-info/entry_points.txt
11
+ src/tibet_keychain.egg-info/requires.txt
12
+ src/tibet_keychain.egg-info/top_level.txt
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ tibet-keychain = tibet_keychain.cli:main
3
+ tkc = tibet_keychain.cli:main
@@ -0,0 +1,11 @@
1
+ cryptography>=42.0
2
+
3
+ [cbom]
4
+ tibet-cbom>=0.1.1
5
+
6
+ [full]
7
+ tibet-drop>=0.3.0
8
+ tibet-cbom>=0.1.1
9
+
10
+ [sealed]
11
+ tibet-drop>=0.3.0
@@ -0,0 +1 @@
1
+ tibet_keychain