Skip to content

encrypted_pin: sealing to a partial recipient set leaves authorized readers unrecoverable #47

@beardthelion

Description

@beardthelion

Surfaced by CodeRabbit on #46 (the review spans the whole unmerged stack, so it lands on B1 code from #36 rather than #46's delta).

encrypted_pin::encrypt_and_pin resolves recipient DIDs with:

let keys: Vec<VerifyingKey> = dids.iter().filter_map(|d| did_to_key(d)).collect();
if keys.is_empty() {
    tracing::warn!(oid = %oid, "no resolvable recipient keys; skipping encrypted pin");
    continue;
}

filter_map silently drops any DID that fails resolution and seals to whatever remains, as long as at least one key resolves. The blob is then recorded as successfully encrypted and pinned. An authorized reader whose key could not be resolved at seal time is now permanently unable to recover that blob, with no signal that it happened. For a confidentiality/recovery system this is a correctness bug, not a soft-fail.

Treat any unresolved DID as a per-blob failure: resolve all DIDs, and if any fail, log with the oid and the unresolved set and continue rather than sealing to a partial set.

Secondary, same function: the read_object and pin_git_object failure arms collapse to _ => continue with no log, which hurts observability during partial outages. Worth adding warn logs while in here.

Owning PR: #36.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions