snapkitty
cryptography
python
xml
SNAPKITTYWEST commited on
Commit
dfcd6e3
Β·
verified Β·
1 Parent(s): ecf9cb9

Sync with GitHub, license metadata from LICENSE files, commercial license notice

Browse files

metadata license: None -> other (snapkitty-tri-license)
README: License section appended
README: GitHub source link added

Files changed (1) hide show
  1. README.md +145 -123
README.md CHANGED
@@ -1,123 +1,145 @@
1
- # vault-live
2
-
3
- SAML 2.0 SP/IdP with a NAND-gated assertion validation pipeline.
4
-
5
- Every inbound SAML assertion passes through a boolean constraint tree before any attribute is trusted. The constraint tree is written in XML β€” the same language as SAML itself. The entropy of the attribute set is bounded at 0.20 nats. The Semantic Hash produced by the gate is the immutable anchor for the WORM audit chain.
6
-
7
- **Stack:** Python + `cryptography` library. No lxml, no xmlsec, no external SAML library.
8
- **Tests:** 31 passing β€” `pytest tests/`
9
-
10
- ---
11
-
12
- ## How it works
13
-
14
- ```
15
- IdP produces signed SAML Response
16
- β”‚
17
- β–Ό Base64 decode β†’ XML parse
18
- β”‚
19
- β–Ό Signature verification (RSA-SHA256, enveloped)
20
- β”‚ uses IdP signing certificate as verification root
21
- β”‚
22
- β–Ό Assertion validation
23
- β”‚ Conditions: NotBefore / NotOnOrAfter clock check
24
- β”‚ SubjectConfirmationData: Recipient + expiry
25
- β”‚ Audience restriction: must match SP EntityID
26
- β”‚
27
- β–Ό Replay protection
28
- β”‚ assertion ID stored with expiry; duplicate β†’ ReplayDetectedError
29
- β”‚
30
- β–Ό NAND gate ← constraints.xml is the program
31
- β”‚ evaluates attribute set through boolean constraint tree
32
- β”‚ computes Shannon entropy H(attr values) in nats
33
- β”‚ enforces H <= 0.20
34
- β”‚ produces Semantic Hash (SHA-256, deterministic)
35
- β”‚
36
- β–Ό WORM audit chain
37
- AuditRecord appended: semantic_hash, assertion_id, gate_result, H
38
- SHA-256 chain: entry_hash = SHA256(prev_hash + record_json)
39
- tamper any record β†’ chain verification fails
40
- ```
41
-
42
- ---
43
-
44
- ## The NAND gate
45
-
46
- The constraint program lives in `nand/constraints.xml`. It is XML evaluated against the assertion's attribute map.
47
-
48
- ```
49
- NAND(branch1, branch2) = NOT(branch1 AND branch2)
50
-
51
- branch1 (session-check): Role present AND SessionIndex present
52
- branch2 (privilege-escalation): Role == "SuperAdmin"
53
-
54
- VaultUser: NAND(True, False) = True β†’ TRUSTED
55
- SuperAdmin: NAND(True, True) = False β†’ BLOCKED
56
- ```
57
-
58
- The security property: an attacker with maximum privileges satisfies all branches simultaneously, causing NAND to output False. A legitimate user fails at least one "attacker" branch, keeping NAND True.
59
-
60
- Entropy constraint: an assertion with multiple distinct values per attribute raises H above 0.20 nats and is rejected regardless of the tree result.
61
-
62
- The Semantic Hash binds the assertion identity to the audit record:
63
-
64
- ```python
65
- semantic_hash = SHA256(
66
- assertion_id + "|" + issuer + "|" + issue_instant + "|"
67
- + str(int(tree_result)) + "|" + f"{entropy:.6f}" + "|"
68
- + json.dumps(sorted_attrs, sort_keys=True, separators=(',',':'))
69
- )
70
- ```
71
-
72
- ---
73
-
74
- ## Modules
75
-
76
- ```
77
- vault-live/
78
- β”œβ”€β”€ crypto/
79
- β”‚ β”œβ”€β”€ keys.py RSA key generation, self-signed X.509, PEM load/save
80
- β”‚ β”œβ”€β”€ xml_dsig.py XML-DSig: RSA-SHA256 sign/verify, Exclusive C14N
81
- β”‚ └── xml_encrypt.py XML Encryption: AES-256-GCM payload, RSA-OAEP key wrap
82
- β”‚
83
- β”œβ”€β”€ nand/
84
- β”‚ β”œβ”€β”€ constraints.xml Constraint DSL (vl: namespace) β€” the program IS XML
85
- β”‚ └── gate.py NANDGate: tree eval, entropy, semantic hash
86
- β”‚
87
- β”œβ”€β”€ saml/
88
- β”‚ β”œβ”€β”€ metadata.xml SP metadata (EntityID, ACS, signing cert)
89
- β”‚ β”œβ”€β”€ idp_metadata.xml IdP metadata (EntityID, SSO endpoint, signing cert)
90
- β”‚ β”œβ”€β”€ sp/
91
- β”‚ β”‚ β”œβ”€β”€ authn_request.py AuthnRequest builder + HTTP-Redirect encoding
92
- β”‚ β”‚ └── assertion_consumer.py ACS: full validation chain + NAND gate
93
- β”‚ └── idp/
94
- β”‚ └── response_builder.py Response + signed Assertion builder
95
- β”‚
96
- β”œβ”€β”€ audit/
97
- β”‚ β”œβ”€β”€ worm.py Append-only SHA-256 chain, verify_chain(), AuditRecord
98
- β”‚ └── replay.py ReplayStore: seen assertion IDs + expiry, file backend
99
- β”‚
100
- └── tests/
101
- β”œβ”€β”€ test_saml_flow.py End-to-end: authn request, full flow, replay, tamper
102
- β”œβ”€β”€ test_nand_gate.py Gate logic, entropy, semantic hash, constraint DSL
103
- └── test_audit.py WORM chain, tamper detection, replay store
104
- ```
105
-
106
- ---
107
-
108
- ## Running
109
-
110
- ```bash
111
- pip install cryptography pytest
112
- pytest tests/ -v
113
- ```
114
-
115
- ---
116
-
117
- ## Why XML as the constraint language
118
-
119
- SAML is XML. The assertions being validated are XML. The SP/IdP metadata is XML. Writing the constraint program in the same language (`vl:` namespace, `nand/constraints.xml`) means the trust policy is readable by the same tooling that reads the protocol β€” XPath queries, XML validators, schema checkers, diff tools. GitHub's language detector counts it as XML, which is accurate: the constraint tree is the program.
120
-
121
- ---
122
-
123
- Built by Ahmad Ali Parr Γ— SnapKitty.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: other
3
+ license_name: snapkitty-tri-license
4
+ license_link: https://huggingface.co/Snapkitty/vault-live/blob/main/LICENSE.tri
5
+ tags:
6
+ - snapkitty
7
+ ---
8
+
9
+ > Source: [github.com/SNAPKITTYWEST/vault-live](https://github.com/SNAPKITTYWEST/vault-live)
10
+
11
+ # vault-live
12
+
13
+ SAML 2.0 SP/IdP with a NAND-gated assertion validation pipeline.
14
+
15
+ Every inbound SAML assertion passes through a boolean constraint tree before any attribute is trusted. The constraint tree is written in XML β€” the same language as SAML itself. The entropy of the attribute set is bounded at 0.20 nats. The Semantic Hash produced by the gate is the immutable anchor for the WORM audit chain.
16
+
17
+ **Stack:** Python + `cryptography` library. No lxml, no xmlsec, no external SAML library.
18
+ **Tests:** 31 passing β€” `pytest tests/`
19
+
20
+ ---
21
+
22
+ ## How it works
23
+
24
+ ```
25
+ IdP produces signed SAML Response
26
+ β”‚
27
+ β–Ό Base64 decode β†’ XML parse
28
+ β”‚
29
+ β–Ό Signature verification (RSA-SHA256, enveloped)
30
+ β”‚ uses IdP signing certificate as verification root
31
+ β”‚
32
+ β–Ό Assertion validation
33
+ β”‚ Conditions: NotBefore / NotOnOrAfter clock check
34
+ β”‚ SubjectConfirmationData: Recipient + expiry
35
+ β”‚ Audience restriction: must match SP EntityID
36
+ β”‚
37
+ β–Ό Replay protection
38
+ β”‚ assertion ID stored with expiry; duplicate β†’ ReplayDetectedError
39
+ β”‚
40
+ β–Ό NAND gate ← constraints.xml is the program
41
+ β”‚ evaluates attribute set through boolean constraint tree
42
+ β”‚ computes Shannon entropy H(attr values) in nats
43
+ β”‚ enforces H <= 0.20
44
+ β”‚ produces Semantic Hash (SHA-256, deterministic)
45
+ β”‚
46
+ β–Ό WORM audit chain
47
+ AuditRecord appended: semantic_hash, assertion_id, gate_result, H
48
+ SHA-256 chain: entry_hash = SHA256(prev_hash + record_json)
49
+ tamper any record β†’ chain verification fails
50
+ ```
51
+
52
+ ---
53
+
54
+ ## The NAND gate
55
+
56
+ The constraint program lives in `nand/constraints.xml`. It is XML evaluated against the assertion's attribute map.
57
+
58
+ ```
59
+ NAND(branch1, branch2) = NOT(branch1 AND branch2)
60
+
61
+ branch1 (session-check): Role present AND SessionIndex present
62
+ branch2 (privilege-escalation): Role == "SuperAdmin"
63
+
64
+ VaultUser: NAND(True, False) = True β†’ TRUSTED
65
+ SuperAdmin: NAND(True, True) = False β†’ BLOCKED
66
+ ```
67
+
68
+ The security property: an attacker with maximum privileges satisfies all branches simultaneously, causing NAND to output False. A legitimate user fails at least one "attacker" branch, keeping NAND True.
69
+
70
+ Entropy constraint: an assertion with multiple distinct values per attribute raises H above 0.20 nats and is rejected regardless of the tree result.
71
+
72
+ The Semantic Hash binds the assertion identity to the audit record:
73
+
74
+ ```python
75
+ semantic_hash = SHA256(
76
+ assertion_id + "|" + issuer + "|" + issue_instant + "|"
77
+ + str(int(tree_result)) + "|" + f"{entropy:.6f}" + "|"
78
+ + json.dumps(sorted_attrs, sort_keys=True, separators=(',',':'))
79
+ )
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Modules
85
+
86
+ ```
87
+ vault-live/
88
+ β”œβ”€β”€ crypto/
89
+ β”‚ β”œβ”€β”€ keys.py RSA key generation, self-signed X.509, PEM load/save
90
+ β”‚ β”œβ”€β”€ xml_dsig.py XML-DSig: RSA-SHA256 sign/verify, Exclusive C14N
91
+ β”‚ └── xml_encrypt.py XML Encryption: AES-256-GCM payload, RSA-OAEP key wrap
92
+ β”‚
93
+ β”œβ”€β”€ nand/
94
+ β”‚ β”œβ”€β”€ constraints.xml Constraint DSL (vl: namespace) β€” the program IS XML
95
+ β”‚ └── gate.py NANDGate: tree eval, entropy, semantic hash
96
+ β”‚
97
+ β”œβ”€β”€ saml/
98
+ β”‚ β”œβ”€β”€ metadata.xml SP metadata (EntityID, ACS, signing cert)
99
+ β”‚ β”œβ”€β”€ idp_metadata.xml IdP metadata (EntityID, SSO endpoint, signing cert)
100
+ β”‚ β”œβ”€β”€ sp/
101
+ β”‚ β”‚ β”œβ”€β”€ authn_request.py AuthnRequest builder + HTTP-Redirect encoding
102
+ β”‚ β”‚ └── assertion_consumer.py ACS: full validation chain + NAND gate
103
+ β”‚ └── idp/
104
+ β”‚ └── response_builder.py Response + signed Assertion builder
105
+ β”‚
106
+ β”œβ”€β”€ audit/
107
+ β”‚ β”œβ”€β”€ worm.py Append-only SHA-256 chain, verify_chain(), AuditRecord
108
+ β”‚ └── replay.py ReplayStore: seen assertion IDs + expiry, file backend
109
+ β”‚
110
+ └── tests/
111
+ β”œβ”€β”€ test_saml_flow.py End-to-end: authn request, full flow, replay, tamper
112
+ β”œβ”€β”€ test_nand_gate.py Gate logic, entropy, semantic hash, constraint DSL
113
+ └── test_audit.py WORM chain, tamper detection, replay store
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Running
119
+
120
+ ```bash
121
+ pip install cryptography pytest
122
+ pytest tests/ -v
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Why XML as the constraint language
128
+
129
+ SAML is XML. The assertions being validated are XML. The SP/IdP metadata is XML. Writing the constraint program in the same language (`vl:` namespace, `nand/constraints.xml`) means the trust policy is readable by the same tooling that reads the protocol β€” XPath queries, XML validators, schema checkers, diff tools. GitHub's language detector counts it as XML, which is accurate: the constraint tree is the program.
130
+
131
+ ---
132
+
133
+ Built by Ahmad Ali Parr Γ— SnapKitty.
134
+
135
+ ---
136
+
137
+ ## License
138
+
139
+ Licensed under **SnapKitty Tri-License**. Full text: [LICENSE.tri](LICENSE.tri).
140
+
141
+ ### πŸ’Ό Commercial License
142
+
143
+ Snapkitty code is free and open under **AGPL-3.0** for open-source use. Building a commercial product or service? A **proprietary commercial license** from Snapkitty Collective LLC lets you ship this code without the AGPL's source-sharing and network-use obligations.
144
+
145
+ **[β†’ Get a commercial license](mailto:A.parr@belespritdaccord.uk?subject=Commercial%20license:%20vault-live)** Β· A.parr@belespritdaccord.uk