Skip to content

A key_id leaks its label — federation-level moderation must address the key fingerprint #555

Description

@emooreatx

Federation-scoped moderation and de-admission actions currently name a key_id. A key_id is not opaque.

The leak

ciris-verify-core fedcode.rs::derive_key_id:

/// Derive a collision-free, verifiable `key_id` = "<label>-<fingerprint>".
/// `label` is lowercased and reduced to [a-z0-9-] (cosmetic). `fingerprint`
/// is the first KEY_ID_FINGERPRINT_LEN base32 chars of sha256(ed25519_pubkey).

The label is the keystore alias, in cleartext. ciris-agent-bootstrap-mplbdbzbed is benign; real deployments will carry frank-laptop or acme-node-3. So an action that names a key_id publishes who it acted on to everyone it replicates to — no directory body required.

That is the wrong default for a federation-wide action against a person.

Address the fingerprint instead

Use the full sha256(ed25519_pubkey) — already the primitive derive_key_id computes, already public in truncated form, and carrying no label.

  • Stable for the life of the key, not the life of a record. A node holding the identity recomputes and enforces; a node that does not can still relay the action without learning who it names.
  • Do not use the record's content hash. It changes on re-scrub or supersede (adopt_scrub_upgrade does exactly that), so a ban would lapse the moment the subject re-mints their record.
  • Evasion costs a new key — a different identity that abandons every attestation and all standing it had. That is the correct price, and content-hash addressing would have made it free.

What this does and does not buy

It hides the label, not the identity. Anyone holding the directory body can still join fingerprint → key_id. The guarantee is narrower and worth stating exactly: the action itself carries nothing, and joining requires already holding the record — which under hash-first retention (#552) most of the federation will not.

Overselling this as anonymity would be wrong, and would invite someone to rely on it for more than it does.

Cross-repo

Persist owns the admission and moderation gates, so the addressing change likely needs a companion there — filed as CIRISPersist#784.

Related: #552 · CIRISPersist#784

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions