Skip to content

fix: String() on signers must not leak private keys - #48

Open
bajtos wants to merge 1 commit into
mainfrom
multikey-safe-toString
Open

fix: String() on signers must not leak private keys#48
bajtos wants to merge 1 commit into
mainfrom
multikey-safe-toString

Conversation

@bajtos

@bajtos bajtos commented Aug 12, 2026

Copy link
Copy Markdown
Member

multikey signers are []byte holding private key material, so passing one to fmt.* with %s or %v printed the raw key.

Declare String() string on ucan.Signer and implement it on both multikey signers to return the key DID instead, which fixes every call site in dependents at once.

Related:

`multikey` signers are `[]byte` holding private key material, so passing
one to `fmt.*` with `%s` or `%v` printed the raw key. Declare
`String() string` on `ucan.Signer` and implement it on both multikey
signers to return the key DID instead, which fixes every call site in
dependents at once.

Signed-off-by: Miroslav Bajto拧 <oss@bajtos.net>
Assisted-by: Claude:claude-opus-5[1m]

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR prevents accidental private-key leakage when multikey signers (which are []byte holding key material) are passed to fmt.* by adding a String() string method to ucan.Signer and implementing it for the ed25519 and secp256k1 multikey signers to return the key DID instead of raw bytes.

Changes:

  • Extend ucan.Signer with a String() string contract that must not include private key material.
  • Implement String() for ed25519 and secp256k1 multikey signers to return KeyDID().String().
  • Add tests asserting fmt.Sprint(signer) matches the signer鈥檚 key DID for both algorithms.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
ucan/ucan.go Adds String() to the ucan.Signer interface with explicit non-leak guidance.
multikey/secp256k1/signer.go Implements Signer.String() intended to avoid exposing raw private key bytes.
multikey/secp256k1/signer_test.go Adds coverage ensuring formatting uses the DID string.
multikey/ed25519/signer.go Implements Signer.String() intended to avoid exposing raw private key bytes.
multikey/ed25519/signer_test.go Adds coverage ensuring formatting uses the DID string.

馃挕 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +105 to +109
// String returns the signer's key DID. It deliberately never exposes the
// private key bytes, so that passing a Signer to fmt.* cannot leak them.
func (s Signer) String() string {
return s.KeyDID().String()
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frrist thoughts?

Comment on lines +100 to +104
// String returns the signer's key DID. It deliberately never exposes the
// private key bytes, so that passing a Signer to fmt.* cannot leak them.
func (s Signer) String() string {
return s.KeyDID().String()
}
@bajtos
bajtos requested a review from frrist August 12, 2026 11:57
@frrist
frrist requested review from alanshaw and removed request for frrist August 14, 2026 03:06
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.

2 participants