Skip to content

feat(storage): add PKCS#11 KEK provider crate#917

Merged
gtema merged 1 commit into
mainfrom
claude/raft-pkcs11-tpm-support-tc29i2
Jul 6, 2026
Merged

feat(storage): add PKCS#11 KEK provider crate#917
gtema merged 1 commit into
mainfrom
claude/raft-pkcs11-tpm-support-tc29i2

Conversation

@gtema

@gtema gtema commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Step 3 of ADR 0016-v2 §2.5: storage-crypto-pkcs11, a
feature-isolated crate providing Pkcs11Kek, a KekProvider backed
by CKM_AES_GCM against a non-extractable AES-256 key on a PKCS#11
token. Wire format matches EnvKek exactly, so nothing downstream
of KekProvider changes. Built on cryptoki 0.12 (pure Rust, dlopen
at runtime) — no system PKCS#11 headers needed to build.

Slot selection by numeric id or token label. Key lookup by
CKA_LABEL, with opt-in auto_generate (explicit param, not
default). Adds PKCS11(String) to CryptoError; wrap/unwrap
failures still map to existing AesEncrypt/AesDecrypt so tag- and
ciphertext-tamper cases stay indistinguishable from other AEAD
failures.

Assisted-By: Claude Sonnet 5 noreply@anthropic.com
Signed-off-by: Artem Goncharov artem.goncharov@gmail.com

@gtema gtema force-pushed the claude/raft-pkcs11-tpm-support-tc29i2 branch from 7ec29d5 to 517dacc Compare July 6, 2026 13:14
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

🦢 Load Test Results

Goose Attack Report

Plan Overview

Action Started Stopped Elapsed Users
Increasing 26-07-06 14:11:29 26-07-06 14:11:45 00:00:16 0 → 30
Maintaining 26-07-06 14:11:45 26-07-06 14:12:15 00:00:30 30
Decreasing 26-07-06 14:12:15 26-07-06 14:12:43 00:00:28 0 ← 30

Request Metrics

Method Name # Requests # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
DELETE DELETE /v3/auth/tokens 325 0 100.83 10 123 10.83 0.00
DELETE DELETE /v3/projects/:id (teardown) 2 0 45.00 44 46 0.07 0.00
DELETE DELETE /v3/users/:id (teardown) 3 0 41.33 39 43 0.10 0.00
GET 4910 0 95.69 68 180 163.67 0.00
GET GET /v3/auth/tokens (validate new) 323 2 472.69 91 60001 10.77 0.07
GET GET /v3/projects/:id 768 0 77.94 67 105 25.60 0.00
GET GET /v3/projects/:id (catalog) 763 0 77.99 67 103 25.43 0.00
GET GET /v3/users/:id 1071 0 83.97 74 106 35.70 0.00
GET GET /v3/users/:id (catalog) 842 0 83.37 72 105 28.07 0.00
POST POST /v3/auth/tokens 320 0 76.78 68 97 10.67 0.00
Aggregated 9327 2 102.88 10 60001 310.90 0.07

Response Time Metrics

Method Name 50%ile (ms) 60%ile (ms) 70%ile (ms) 80%ile (ms) 90%ile (ms) 95%ile (ms) 99%ile (ms) 100%ile (ms)
DELETE DELETE /v3/auth/tokens 100 100 100 110 110 110 120 120
DELETE DELETE /v3/projects/:id (teardown) 44 44 44 46 46 46 46 46
DELETE DELETE /v3/users/:id (teardown) 42 42 42 42 43 43 43 43
GET 88 93 96 100 150 150 160 180
GET GET /v3/auth/tokens (validate new) 100 100 100 110 110 110 130 60,000
GET GET /v3/projects/:id 78 79 79 81 82 85 92 105
GET GET /v3/projects/:id (catalog) 78 78 80 81 83 85 92 100
GET GET /v3/users/:id 84 84 85 87 89 91 97 106
GET GET /v3/users/:id (catalog) 83 84 85 86 89 90 96 105
POST POST /v3/auth/tokens 77 78 79 80 81 83 89 97
Aggregated 83 86 92 97 110 150 150 60,000

Status Code Metrics

Method Name Status Codes
DELETE DELETE /v3/auth/tokens 325 [204]
DELETE DELETE /v3/projects/:id (teardown) 2 [204]
DELETE DELETE /v3/users/:id (teardown) 3 [204]
GET 4,910 [200]
GET GET /v3/auth/tokens (validate new) 321 [200], 2 [0]
GET GET /v3/projects/:id 768 [200]
GET GET /v3/projects/:id (catalog) 763 [200]
GET GET /v3/users/:id 1,071 [200]
GET GET /v3/users/:id (catalog) 842 [200]
POST POST /v3/auth/tokens 320 [200]
Aggregated 2 [0], 330 [204], 8,995 [200]

Transaction Metrics

Transaction # Times Run # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
ReadHeavy
0.0 1 0 32.00 32 32 0.03 0.00
0.1 832 0 95.03 85 125 27.73 0.00
0.2 834 0 78.76 68 103 27.80 0.00
0.3 831 0 78.21 69 101 27.70 0.00
TokenLifecycle
1.0 0 0 0.00 0 0 0.00 0.00
1.1 325 0 649.06 241 60084 10.83 0.00
ValidateToken
2.0 0 0 0.00 0 0 0.00 0.00
2.1 813 0 147.98 96 180 27.10 0.00
UserCRUD
3.0 0 0 0.00 0 0 0.00 0.00
3.1 0 0 0.00 0 0 0.00 0.00
3.2 1071 0 84.01 74 106 35.70 0.00
3.3 3 0 41.33 39 43 0.10 0.00
ProjectCRUD
4.0 0 0 0.00 0 0 0.00 0.00
4.1 0 0 0.00 0 0 0.00 0.00
4.2 768 0 77.99 67 105 25.60 0.00
4.3 2 0 45.00 44 46 0.07 0.00
UserRead
5.0 0 0 0.00 0 0 0.00 0.00
5.1 839 0 95.01 85 128 27.97 0.00
5.2 842 0 83.41 72 105 28.07 0.00
ProjectRead
6.0 0 0 0.00 0 0 0.00 0.00
6.1 761 0 79.21 68 101 25.37 0.00
6.2 763 0 78.04 67 104 25.43 0.00
Aggregated 8685 0 110.49 32 60084 289.50 0.00

Scenario Metrics

Transaction # Users # Times Run Average (ms) Min (ms) Max (ms) Scenarios/s Iterations
ReadHeavy 7 829 253.00 232 291 27.63 118.43
TokenLifecycle 3 320 281.25 261 319 10.67 106.67
ValidateToken 4 809 148.03 134 180 26.97 202.25
UserCRUD 3 1068 84.02 74 107 35.60 356.00
ProjectCRUD 2 766 77.99 67 105 25.53 383.00
UserRead 5 838 178.91 164 212 27.93 167.60
ProjectRead 4 760 157.76 145 186 25.33 190.00
Aggregated 28 5390 155.62 67 319 179.67 1523.95

Error Metrics

Method Name # Error
GET GET /v3/auth/tokens (validate new) 2 error sending request GET /v3/auth/tokens (validate new): operation timed out

View full report

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

🐰 Bencher Report

Branchclaude/raft-pkcs11-tpm-support-tc29i2
Testbedubuntu-latest

🚨 3 Alerts

BenchmarkMeasure
Units
ViewBenchmark Result
(Result Δ%)
Upper Boundary
(Limit %)
Command_Serde/apply/removeLatency
milliseconds (ms)
📈 plot
🚷 threshold
🚨 alert (🔔)
3.72 ms
(+1,198.18%)Baseline: 0.29 ms
1.67 ms
(222.46%)

Raft_1Node_Latency/remove/1nodeLatency
milliseconds (ms)
📈 plot
🚷 threshold
🚨 alert (🔔)
4.48 ms
(+689.46%)Baseline: 0.57 ms
2.31 ms
(194.04%)

Raft_1Node_Latency/write/1nodeLatency
milliseconds (ms)
📈 plot
🚷 threshold
🚨 alert (🔔)
2.24 ms
(+284.78%)Baseline: 0.58 ms
2.10 ms
(106.72%)

Click to view all benchmark results
BenchmarkLatencyBenchmark Result
nanoseconds (ns)
(Result Δ%)
Upper Boundary
nanoseconds (ns)
(Limit %)
Command_Serde/apply/remove📈 view plot
🚷 view threshold
🚨 view alert (🔔)
3,717,400.00 ns
(+1,198.18%)Baseline: 286,354.47 ns
1,671,037.21 ns
(222.46%)

Command_Serde/apply/set📈 view plot
🚷 view threshold
833,710.00 ns
(+253.11%)Baseline: 236,101.89 ns
930,130.79 ns
(89.63%)
Command_Serde/pack/delete📈 view plot
🚷 view threshold
72.27 ns
(-40.74%)Baseline: 121.94 ns
145.59 ns
(49.64%)
Command_Serde/pack/delete_index📈 view plot
🚷 view threshold
66.07 ns
(-40.08%)Baseline: 110.27 ns
130.99 ns
(50.44%)
Command_Serde/pack/set📈 view plot
🚷 view threshold
119.74 ns
(-38.97%)Baseline: 196.20 ns
238.02 ns
(50.31%)
Command_Serde/pack/set_index📈 view plot
🚷 view threshold
65.07 ns
(-40.95%)Baseline: 110.19 ns
130.63 ns
(49.81%)
Command_Serde/unpack/delete📈 view plot
🚷 view threshold
106.93 ns
(-44.26%)Baseline: 191.84 ns
235.42 ns
(45.42%)
Command_Serde/unpack/delete_index📈 view plot
🚷 view threshold
93.25 ns
(-41.65%)Baseline: 159.82 ns
199.22 ns
(46.81%)
Command_Serde/unpack/set📈 view plot
🚷 view threshold
143.37 ns
(-46.85%)Baseline: 269.73 ns
332.25 ns
(43.15%)
Command_Serde/unpack/set_index📈 view plot
🚷 view threshold
89.39 ns
(-43.71%)Baseline: 158.81 ns
196.79 ns
(45.42%)
Payload_encryption/pack/remove_cmd📈 view plot
🚷 view threshold
64.13 ns
(-44.95%)Baseline: 116.50 ns
141.49 ns
(45.33%)
Payload_encryption/pack/set_cmd📈 view plot
🚷 view threshold
123.98 ns
(-39.46%)Baseline: 204.77 ns
268.58 ns
(46.16%)
Payload_encryption/unpack/remove_cmd📈 view plot
🚷 view threshold
113.11 ns
(-44.74%)Baseline: 204.69 ns
256.48 ns
(44.10%)
Payload_encryption/unpack/set_cmd📈 view plot
🚷 view threshold
152.77 ns
(-45.90%)Baseline: 282.41 ns
352.50 ns
(43.34%)
Raft_1Node_Latency/prefix/1node📈 view plot
🚷 view threshold
214,490.00 ns
(-92.17%)Baseline: 2,739,551.25 ns
6,172,649.98 ns
(3.47%)
Raft_1Node_Latency/read/1node📈 view plot
🚷 view threshold
22,880.00 ns
(+5.52%)Baseline: 21,683.73 ns
70,319.78 ns
(32.54%)
Raft_1Node_Latency/remove/1node📈 view plot
🚷 view threshold
🚨 view alert (🔔)
4,475,400.00 ns
(+689.46%)Baseline: 566,896.25 ns
2,306,480.28 ns
(194.04%)

Raft_1Node_Latency/write/1node📈 view plot
🚷 view threshold
🚨 view alert (🔔)
2,238,400.00 ns
(+284.78%)Baseline: 581,730.16 ns
2,097,403.07 ns
(106.72%)

build_snapshot/default📈 view plot
🚷 view threshold
101,230.00 ns
(-7.29%)Baseline: 109,186.53 ns
145,345.63 ns
(69.65%)
fernet token/project📈 view plot
🚷 view threshold
914.01 ns
(-34.05%)Baseline: 1,385.93 ns
1,628.50 ns
(56.13%)
get_data_keyspace📈 view plot
🚷 view threshold
0.24 ns
(-24.81%)Baseline: 0.31 ns
0.36 ns
(64.91%)
get_db📈 view plot
🚷 view threshold
0.24 ns
(-24.86%)Baseline: 0.31 ns
0.36 ns
(64.90%)
get_fernet_token_timestamp/project📈 view plot
🚷 view threshold
87.81 ns
(-39.01%)Baseline: 143.98 ns
180.72 ns
(48.59%)
get_keyspace📈 view plot
🚷 view threshold
9.97 ns
(+99.50%)Baseline: 5.00 ns
10.66 ns
(93.54%)
🐰 View full continuous benchmarking report in Bencher

Step 3 of ADR 0016-v2 §2.5: storage-crypto-pkcs11, a
feature-isolated crate providing Pkcs11Kek, a KekProvider backed
by CKM_AES_GCM against a non-extractable AES-256 key on a PKCS#11
token. Wire format matches EnvKek exactly, so nothing downstream
of KekProvider changes. Built on cryptoki 0.12 (pure Rust, dlopen
at runtime) — no system PKCS#11 headers needed to build.

Slot selection by numeric id or token label. Key lookup by
CKA_LABEL, with opt-in auto_generate (explicit param, not
default). Adds PKCS11(String) to CryptoError; wrap/unwrap
failures still map to existing AesEncrypt/AesDecrypt so tag- and
ciphertext-tamper cases stay indistinguishable from other AEAD
failures.

Assisted-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
@gtema gtema force-pushed the claude/raft-pkcs11-tpm-support-tc29i2 branch from 517dacc to 4ee1c8a Compare July 6, 2026 13:56
@gtema gtema merged commit 3963df6 into main Jul 6, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant