Skip to content

Commit 58f831a

Browse files
committed
Test the certificate path against real issuers, and fix what that found
The stub in tests/ is fast and can be made to misbehave, but it only knows what we told it — and two of the defects found in review were invisible for exactly as long as it was the only witness. tests/vault_server.py runs the suite against a real HashiCorp Vault and a real OpenBao, reading requests back out of the server's own audit device, so the payload under assertion is the one the server received. Every behaviour the stub models is now pinned against both. Three defects came out of it: - Every login left a copy of the credential in freed memory. login_payload used serde_json::to_string, whose String grows as it is written and frees each smaller buffer without wiping it; Zeroizing only ever wipes the buffer that survives to the end. Size decides whether it shows: measured with a 4 KiB credential, which is what a Kubernetes service account token or a signed AWS header set actually is. Now serialized into a buffer reserved up front. - The certificate's key ID was never checked against the one requested. A certificate carrying a 64 KiB key ID authenticated normally. The target's sshd logs that field verbatim, and "the target's own log names the person" is the claim this path exists to deliver, so an issuer returning a different one breaks attribution silently. - The reason an authentication failed never reached the person connecting. ConnectionError::Authentication carried no detail; the reason went to the server log and the user got a fixed string. For a certificate refused because it is outside its validity window — the documented clock-skew hazard — that sends whoever is debugging it to check credentials that are fine. The variant now carries its reason and the certificate arm names the window. Also documented: OpenBao refuses to enable an audit device over the API, and its config stanza needs type, path and an options block — a top-level file_path is accepted with a warning and then ignored, which looks exactly like a working audit device that writes nothing. Tests: 16 contract tests across Vault and OpenBao (five versions under WARPGATE_VAULT_MATRIX=full), 8 for certificates a real issuer would never emit, 6 property tests over the validators, and 3 that watch the allocator to check the zeroization claim rather than trusting it.
1 parent bea50d4 commit 58f831a

13 files changed

Lines changed: 1237 additions & 17 deletions

File tree

Cargo.lock

Lines changed: 79 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/stub_vault.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ def _sign(self, stub, role, body):
298298
principals=(
299299
stub.principals if stub.principals is not None else body["valid_principals"]
300300
),
301-
key_id=body.get("key_id", ""),
301+
key_id=stub.sign_key_id if stub.sign_key_id is not None else body.get("key_id", ""),
302302
)
303303
self._reply(200, {"data": {"signed_key": certificate}})
304304

@@ -357,6 +357,7 @@ def reset(self):
357357
self.validity = "-30s:+2m"
358358
self.cert_type = "user"
359359
self.sign_options = []
360+
self.sign_key_id = None
360361
self.logins.clear()
361362
self.signs.clear()
362363
self.requests.clear()

0 commit comments

Comments
 (0)