feat(creds): surface plaintext/b64 secret on reuse findings

The CredentialReuse table only stores the sha256+kind hash of the
secret; the printable + b64 forms live on the underlying Credential
rows. The dashboard drawer was therefore showing only the hash, which
defeats most of the value of having a reuse view in the first place.

Repo helpers list_credential_reuses + get_credential_reuse_by_id now
issue one batched SELECT against credentials keyed on the sha256s in
the result page and graft secret_printable + secret_b64 onto each row
before returning. The drawer renders the same printable/b64 code-block
the credentials inspector uses.
This commit is contained in:
2026-04-26 04:34:19 -04:00
parent a455248dd9
commit 50870f2e7a
3 changed files with 77 additions and 0 deletions

View File

@@ -164,6 +164,29 @@ class TestEngineCorrelate:
assert before_total == after_total == 1
assert results2 == []
@pytest.mark.anyio
async def test_list_and_get_enrich_with_secret(self, repo) -> None:
"""``list_credential_reuses`` and ``get_credential_reuse_by_id``
must surface ``secret_printable`` + ``secret_b64`` from the
underlying ``Credential`` rows so the dashboard drawer can show
the actual secret instead of just its sha256.
"""
sha = _sha256("hunter2")
await _seed_credential(repo, secret_sha256=sha, decky_name="d1", service="ssh")
await _seed_credential(repo, secret_sha256=sha, decky_name="d2", service="ftp")
engine = CorrelationEngine()
await engine.correlate_credential_reuse(repo, min_targets=2)
_, rows = await repo.list_credential_reuses(min_target_count=2)
assert rows[0]["secret_printable"] == "hunter2"
assert rows[0]["secret_b64"] == "aHVudGVyMg=="
single = await repo.get_credential_reuse_by_id(rows[0]["id"])
assert single is not None
assert single["secret_printable"] == "hunter2"
assert single["secret_b64"] == "aHVudGVyMg=="
@pytest.mark.anyio
async def test_growth_emits_changed(self, repo) -> None:
"""Adding a third target after an initial reuse run yields a