> For the complete documentation index, see [llms.txt](https://bsv.brc.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bsv.brc.dev/peer-to-peer/0202.md).

# Identity-Key Decentralized Identifiers

Ty Everett (<ty@projectbabbage.com>)

## Abstract

This specification defines a reversible `did:key` representation of a BRC identity key. It specifies identifier encoding, DID document construction, resolution, verification relationships, and the limits of key continuity. It provides an identifier foundation for BRC certificates and applications without replacing BRC-52 certificates, BRC-100 wallet operations, BRC-103 authentication, or user-selected trust.

## Motivation

A BRC application commonly identifies a party using a compressed secp256k1 identity public key. DID-aware applications need an unambiguous representation of that same key. A serial-number lookup, a domain manifest, and a human-readable name serve different purposes and must not become interchangeable identity identifiers.

This profile uses the identity key itself as the identifier basis. It adds no on-chain identity-registration requirement or mandatory external identity provider. An identifier that directly encodes a key necessarily changes when that key changes; this consequence is part of the profile rather than an undocumented recovery feature.

## Status and scope

This is a BRC profile. MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY have the meanings in RFC 2119 and RFC 8174. Specification and conformance sections are normative; motivation, examples, implementation observations, and migration planning are informative.

The baseline is [DID Core v1.0](https://www.w3.org/TR/2022/REC-did-core-20220719/), a W3C Recommendation. [DID v1.1](https://www.w3.org/TR/2026/CR-did-1.1-20260305/) is a Candidate Recommendation Snapshot and is not the baseline of this profile. The [`did:key` method](https://w3c-ccg.github.io/did-key-spec/) is a separate community specification, not a W3C Recommendation. Conformance to this BRC is not W3C certification or a claim that every DID method or credential suite supports secp256k1.

This specification defines the BRC identity-key subset of `did:key`. It does not define `did:bsv`, transfer control to a recovery service, equate keys with legal persons, or define a new certificate format. [BRC-189's identity integration](/wallet/0189.md) provides related application context and remains an independently reviewed proposal.

## Terminology

| Term                | Meaning in this profile                                                                                                            |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Identity key        | The valid 33-byte compressed secp256k1 public key used by a BRC wallet or peer as its identity key.                                |
| DID subject         | The entity represented by this identity key in the application context. The identifier alone does not identify a unique human.     |
| DID controller      | The entity able to exercise control of the corresponding private key. This method does not support changing the document in place. |
| Verification method | The public identity key represented inside the DID document with its own DID URL.                                                  |
| Certifier / issuer  | A party asserting certificate claims about a subject; it is identified separately from the subject.                                |
| Resolver            | Software that deterministically decodes the identifier and returns the specified document.                                         |

An application MUST distinguish the DID subject, its controller, a certificate issuer, a credential holder, and a verifier. The same party may perform multiple roles; that does not transfer one role's authority to another.

## Specification

### 1. Identity key acquisition and validation

A BRC-100 application obtains its user's identity key through `getPublicKey({ identityKey: true })`, subject to the wallet's applicable permissions. Peer identity keys may be obtained through BRC-103, or from separately validated certificates or contacts. Obtaining a key string does not prove current control of its private key.

The encoder MUST decode exactly 33 public-key bytes, require prefix `02` or `03`, and validate the point on secp256k1. It MUST reject malformed, out-of-range, off-curve, and infinity encodings. Private-key bytes MUST NOT appear in the identifier or DID document. A child key, a Bitcoin address, and a certificate serial MUST NOT be substituted for the identity key.

### 2. Identifier encoding

For a validated compressed identity key `P`:

```
multicodecBytes = e7 01 || P
M = "z" || base58btc(multicodecBytes)
D = "did:key:" || M
V = D || "#" || M
```

`e7 01` is the unsigned variable-length integer encoding of the multicodec value `0xe7` (`secp256k1-pub`). It is not Bitcoin CompactSize. `base58btc` uses the alphabet `123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`, with leading zero bytes represented by leading `1` characters; it adds no address version or checksum.

The profile identifier `D` has exactly three colon-separated components. The encoder MUST emit the unversioned, base58btc form above. It MUST NOT use a transaction ID, certificate type, serial, hostname, wallet vendor, or network name as the method-specific identifier.

This decoder supports only the secp256k1 subset defined here; rejection of a different multicodec is an unsupported key type in this subset and is not a claim that the other `did:key` is invalid under its own profile. The decoder MUST require the exact `did:key:z` prefix, decode base58btc canonically, require exactly 35 decoded bytes starting with `e7 01`, and validate the remaining 33 bytes as `P`. Re-encoding MUST reproduce the input exactly. Whitespace, percent-encoded substitutes, padding, appended paths, queries, and fragments are not valid inputs to identity-key decoding. DID URL dereferencing is a separate operation.

### 3. DID document

The resolver MUST construct the following document from `D`, `M`, and `V`. The notation below is a construction rule; replace the quoted placeholders with their exact values.

```json
{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/multikey/v1"
  ],
  "id": "D",
  "verificationMethod": [{
    "id": "V",
    "type": "Multikey",
    "controller": "D",
    "publicKeyMultibase": "M"
  }],
  "authentication": ["V"],
  "assertionMethod": ["V"],
  "capabilityInvocation": ["V"],
  "capabilityDelegation": ["V"]
}
```

These verification relationships follow this `did:key` expansion profile. They identify the key to use for the named cryptographic purpose; they do not make an issuer trustworthy, grant application privileges, or delegate spending permission. No `keyAgreement` relationship is added by this profile. BRC-42/BRC-100 encryption remains governed by its own key derivation and permission rules.

The document contains no certified name, email address, photographs, master keyring, private field values, service endpoint, trust score, or certificate serial. Implementations MUST NOT change its graph by inserting discovery attributes or wallet metadata. Such attributes belong in separately attributed certificates or application records.

### 4. Resolution and dereferencing

`resolve(D, options)` MUST validate and decode `D` and return `{ didResolutionMetadata: {}, didDocument: document, didDocumentMetadata: {} }`, with `document` constructed above. The empty metadata objects are deliberate: resolution is deterministic and supplies no chain history. Invalid inputs yield `didDocument: null` and `didResolutionMetadata.error: "invalidDid"`. Valid DIDs for methods outside the implementation's supported methods yield `methodNotSupported`, rather than a fabricated document. Implementations supporting other methods MAY dispatch to their separately specified resolvers.

This profile resolves without a network lookup. It MUST NOT accept a remote DID document that changes the decoded key, controller, relationships, or identifier. No creation time, update time, chain inclusion, status, or version history can be inferred from the key encoding; resolvers MUST NOT invent those metadata values.

For `resolveRepresentation`, the profile representation is UTF-8 JSON-LD with content type `application/did+ld+json`. Successful representation resolution MUST set `didResolutionMetadata.contentType` to `application/did+ld+json` and return the UTF-8 document stream separately from the metadata. Representation failures MUST return an error and no successful document stream. General DID representation requirements remain governed by DID Core.

The supported verification-method DID URL is exactly `V`. Dereferencing it MUST return the verification method constructed above. Unknown fragments, paths, and queries are unsupported and MUST NOT be silently treated as `V`. This BRC does not require dereferencing arbitrary external resources.

### 5. Key control, certificates, and trust

Encoding and resolving a DID prove the relationship between its string and public-key bytes. They do not prove that a presenting party controls the private key. An application requiring live control MUST separately complete a challenge-bound authentication protocol appropriate to the operation.

BRC-103 authentication proves control using BRC key-derivation and message semantics. It MUST NOT be presented as an ordinary signature by the root verification key over arbitrary W3C bytes. A consumer verifying a BRC-52 certificate MUST decode the issuer DID to the identity key and apply BRC-52's derived certificate-signature verification. It MUST NOT verify the certificate signature directly against the root key as though it were a JOSE or Data Integrity signature.

An identity-key DID used as `issuer` identifies the certifier key. A DID used for the certificate's subject identifies the `subject` key. A holder or an overlay host MUST NOT replace either identifier with its own DID. A field-schema registry publisher is not thereby an issuer or DID controller.

[BRC-68](/peer-to-peer/0068.md) domain manifests can help a user choose a trust anchor; [BRC-100](/wallet/0100.md) trust and permission mechanisms support local reliance decisions. Neither changes the deterministic DID, and discovery alone establishes no issuer authority. Trust in claims and permission to perform an operation remain separate decisions.

### 6. Continuity, compromise, and deactivation

This `did:key` profile has no in-place update, rotation, recovery, or deactivation operation. Implementations MUST report such operations as unsupported. A backup that preserves the identity private key preserves `D`; a new identity key produces a different DID.

A wallet MUST NOT equate two DIDs because their display names or social attributes match. A continuity process requires an independently specified and validated linkage, updated contacts, and reissuance where the certificate subject changes. Loss of the old private key does not create an implicit ability to sign a continuity assertion.

A certificate can be revoked without making its subject DID cease to resolve. A compromised identity key also continues to decode deterministically; applications must stop relying on it under their compromise policy. Applications that require a stable identifier with mutable controller keys need a separately specified method or continuity layer; they MUST NOT claim this immutable profile provides it.

## Examples and conformance

The public key below is the secp256k1 generator, a public test value with a known private scalar. It MUST NOT be used for a production identity.

```
P = 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
multicodecBytes = e7010279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
D = did:key:zQ3shVc2UkAfJCdc1TR8E66J85h48P43r93q8jGPkPpjF9Ef9
V = did:key:zQ3shVc2UkAfJCdc1TR8E66J85h48P43r93q8jGPkPpjF9Ef9#zQ3shVc2UkAfJCdc1TR8E66J85h48P43r93q8jGPkPpjF9Ef9
```

An implementation MUST declare whether it supports encoding, decoding, resolution, representation, or verification-method dereferencing. It MUST pass each applicable test:

| Test                                                                              | Required result                                                     |
| --------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| Encode and decode the vector                                                      | Exact `D`, exact `P`, no vendor/network variation.                  |
| Construct the document                                                            | Exact key and relationships from Section 3; no identity attributes. |
| Wrong multicodec, invalid point, wrong length, whitespace, or noncanonical base58 | Rejection without truncation or normalization.                      |
| Decode `V` as an identity DID                                                     | Reject; dereferencing `V` separately succeeds.                      |
| Resolve a substituted document containing another public key                      | Reject, regardless of TLS or remote host reputation.                |
| Change the private identity key                                                   | A different DID; no implicit continuity.                            |
| Supply only a successfully resolved DID for live authentication                   | Insufficient evidence of current key control.                       |
| Revoke a subject's BRC certificate                                                | Certificate reliance changes; subject DID still resolves.           |
| Receive an unsupported method or relationship                                     | Explicit unsupported result, no fallback identity fabrication.      |

A test report MUST identify the implementation revision, supported roles, and exact method/profile. Passing these tests alone does not establish conformance to an external credential suite or every requirement of DID Core.

## Compatibility and implementation work

The intended semantics above are normative independently of any particular library. They are additive to identity-key BRC interfaces: applications can convert `D` back to `P` before calling existing wallet methods. Applications MUST retain original certificate signatures and MUST NOT pass DIDs into wallet parameters that require compressed hexadecimal public keys.

Public [TS Stack `@bsv/did`](https://github.com/bsv-blockchain/ts-stack/tree/8ce780e1c740490f8bf2910f7f37775bf14c713f/packages/helpers/did) already contains `did:key` secp256k1 encoding and document construction. This is implementation evidence for those operations, not a complete conformance report.

The [legacy DID client](https://github.com/bsv-blockchain/ts-stack/blob/8ce780e1c740490f8bf2910f7f37775bf14c713f/packages/helpers/did-client/README.md) explicitly documents that its `tm_did` v1 serial token does not encode issuer or subject. That serial lookup is not this profile's resolution mechanism. Its migration requires authenticated out-of-band bindings; historical lookup results MUST NOT be converted into asserted subject identities by guessing.

TS Stack also contains a [separate `did:bsv` resolver proxy](https://github.com/bsv-blockchain/ts-stack/blob/8ce780e1c740490f8bf2910f7f37775bf14c713f/packages/helpers/simple/src/server/did-resolver.ts). Its source documents reliance on configured remote providers without cryptographic transaction, inclusion, or freshness evidence. This BRC neither endorses that method nor changes its semantics. Future work should separate that code path from this deterministic profile, test explicit wallet/DID conversions and control proofs, and retain supported legacy behavior under separately named compatibility profiles.

No implementation changes or deployment are part of this specification. A future specification for stable mutable identity, if desired, requires an explicit design decision and independent security review.

## Privacy and security considerations

The same identity key always produces the same DID. Reusing it links contexts; changing its spelling does not add privacy. Wallets SHOULD let users choose identity contexts and SHOULD explain cross-application linkage before disclosure. A derived key substituted for the identity key changes the identity being represented and needs a separate binding protocol.

Private keys remain inside the user's selected custody boundary. Generic DID libraries must not require exporting a BRC wallet's root private key to use this profile. BRC-100 mediated signatures need the precise requested protocol, derivation, permissions, and verifier; arbitrary direct root signing is not implied.

DID documents identify cryptographic mechanisms rather than certify human facts. A resolver, a registry, and a display component MUST NOT collapse resolution, current control, certifier trust, and authorization into one green checkmark. Applications must retain provenance and show failure or uncertainty when the evidence does not establish the fact they need.

## References

* [DID Core v1.0, Recommendation, 19 July 2022](https://www.w3.org/TR/2022/REC-did-core-20220719/).
* [`did:key` community method specification](https://w3c-ccg.github.io/did-key-spec/), especially identifier syntax, method operations, and privacy limitations.
* [Multicodec table](https://github.com/multiformats/multicodec/blob/master/table.csv), `secp256k1-pub` code `0xe7`.
* [BRC-42](/key-derivation/0042.md), [BRC-52](/peer-to-peer/0052.md), [BRC-68](/peer-to-peer/0068.md), [BRC-100](/wallet/0100.md), [BRC-103](/peer-to-peer/0103.md), [BRC-104](/peer-to-peer/0104.md), and [BRC-184](/wallet/0184.md).
* [BRC-189](/wallet/0189.md), related identity, discovery, and personal trust concepts.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://bsv.brc.dev/peer-to-peer/0202.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
