Introduction
Last week's post found that the practical answer to key compromise in did:btcr2 is structural. The answer has two parts: authorize more than one key, and keep the keys in different custody. That advice is easy to write and harder to do. It is especially hard for an organization, where "the key" must survive staff changes, laptop replacements, and occasional audits.
This post is about custody for a corporate DID, of the type in the supply chain and B2B post. Some parts of the problem have good answers. Some parts have workable answers. For some parts, the honest answer is that the tools are not ready yet.
Two Keys, Two Problems
First, understand that an organization with a btcr2 DID has two different custody problems. If a design treats them as one problem, the design is bad.
The document key signs the Data Integrity proof on a BTCR2 Signed Update. It is a secp256k1 key, and the capabilityInvocation relationship of the DID document refers to it. It makes a BIP340 Schnorr signature over a digest of the JCS-canonicalized payload. This key authorizes changes to your identity.
The beacon key signs the Bitcoin transaction that announces the update. It controls a UTXO, and its transaction pays a fee. In other respects, it is an ordinary Bitcoin key that spends funds.
These are two different jobs, and they do not need the same custody. But at the start, one key does both jobs. For a key-based (k) did:btcr2 identifier, the resolver builds the initial document deterministically from the key. That document puts the genesis key in capabilityInvocation. It also derives all three SingletonBeacon service endpoints (the P2PKH, P2WPKH, and P2TR addresses) from the same key. To separate the two roles, you must do one of these actions:
- Create an
xidentifier (based on a genesis document) whose document names a beacon that a different key controls. - Publish an update that adds such a beacon and rotates the document key.
After you separate the keys, the two compromise cases are not symmetric. An attacker with the beacon key cannot forge an update, but the damage is worse than lost fees. The attacker can broadcast a Beacon Signal whose 32 bytes point to update data that does not exist. The resolver must process each Beacon Signal from a beacon in the current document. If the update data for a signal is not available, the resolver raises MISSING_UPDATE_DATA, and that error is fatal. Thus one hostile spend can make the identifier permanently unresolvable.
A plain sweep of the UTXOs costs you only money. The spend with the OP_RETURN output does the permanent damage. An attacker with the document key can forge updates. But the attacker must also announce an update, and that step needs the beacon.
This asymmetry is useful, but the beacon key still needs strong protection. The spec RECOMMENDS that each Beacon Address needs appropriate approval to spend, so that no unapproved signal gets to the chain. A small balance on the address is acceptable, but a single key that any person with access to the host can use is not. Script multisig or an n-of-n Taproot address is one suitable option. The spec also RECOMMENDS at least one Singleton Beacon as a fallback, in case all aggregate beacons fail. An aggregate beacon puts the updates of many controllers into one signal.
Current Bitcoin custody practices usually apply directly to the beacon side. The document side is different, for reasons that the next section explains.
The Hardware Signer Gap
This part is uncomfortable. Check it before you commit to an architecture.
Many hardware wallets support Taproot, and a Taproot signature is a BIP340 Schnorr signature. Thus it is easy to conclude that a hardware wallet can hold your document key. In general, it cannot.
The problem is the type of data that these devices sign. A hardware wallet is designed to sign Bitcoin transactions. It parses a PSBT, shows the outputs and amounts to the user, and signs a transaction sighash. That constraint is the core of its security model. The device refuses to sign data that it cannot show to the user. If a device signs arbitrary bytes on request, an attacker can trick it into a signature on a transaction that empties the wallet.
A btcr2 document update is not a transaction. Its proof is a Schnorr signature over a 32-byte digest. The bip340-jcs-2025 cryptosuite makes this digest in three steps:
- Hash the canonical proof configuration with SHA-256.
- Hash the canonical document with SHA-256.
- Hash the concatenation of the two hashes (the proof configuration hash first) with SHA-256.
By design, a device that refuses to sign arbitrary data is a poor fit for exactly this signature.
Some devices have a message-signature feature, and some have generic signature paths. But support is not consistent across vendors, firmware versions, and derivation paths, and the behavior varies. Before you design around a specific device, test it. Make sure that it makes a BIP340 signature over an arbitrary 32-byte digest at your planned derivation path. Also make sure that a library you trust can verify the output. Use vendor documentation as a first step, not as the final answer.
The same caution applies to HSMs and cloud key services. In these products, secp256k1 support usually means ECDSA, which Bitcoin uses for output types older than Taproot. As of September 2026, two cloud key services show this:
- AWS KMS lists
ECDSA_SHA_256as the only signature algorithm for itsECC_SECG_P256K1key spec. - Google Cloud KMS offers
EC_SIGN_SECP256K1_SHA256, which is also ECDSA.
BIP340 Schnorr is a different signature scheme on the same curve. Do not assume that a product supports it. If your compliance rules require an HSM, ask the vendor to confirm BIP340 support. Get that confirmation for the specific product tier that you buy, not only for the product family.
For most organizations, the practical option today is a software key in a well-controlled environment. Examples are a dedicated signing host, an offline machine, or a secure enclave with a custom signer application. That position is weaker than "the key is in an HSM", and it is not honest to claim otherwise. But this model is common: many production systems put the controls around the host, not inside a secure chip.
Split Authority Across Keys
The simplest improvement that makes a real difference costs nothing and needs no special hardware. Put more than one key in capabilityInvocation. Keep each key in different custody.
{
"capabilityInvocation": ["#ops-key", "#offline-key"]
}
#ops-key is on the signing host that does routine updates. #offline-key is on an air-gapped machine or in a safe, and you almost never use it. For the protocol, the two keys have equal power. But their operational exposure is very different.
The relationship is disjunctive (or, not and), and this distinction is important: each key can authorize updates alone. The update algorithm requires only one condition: the verification method of the proof is a member of the capabilityInvocation set. Resolution checks the same single membership. This gives you the property from the rotation post. If an attacker compromises the routine key, you still have an authorized key that the attacker does not have. You can then publish an update that removes the compromised key.
This model does not give you two-person control, because each key alone is sufficient. The protocol does not provide real two-person control. If you need it, you must build it. The next section covers the option that people usually try first.
Where MuSig2 Fits, and Where It Does Not
Earlier posts in this series used MuSig2 as the mechanism for the coordination of aggregate beacons. Thus it is reasonable to ask whether MuSig2 can also give organizational control. It can, with one important constraint. That constraint decides whether MuSig2 fits your governance model.
BIP-327 specifies MuSig2 as an n-of-n scheme. Each participant must give a partial signature. MuSig2 has no threshold, so it cannot give a 3-of-5 arrangement.
For some organizational structures, that is acceptable or even an advantage. Suppose that two officers must both approve each change to the corporate identity. That rule maps directly to 2-of-2. The DID document contains one aggregate public key, and resolution and verification do not change. Nobody can see the multi-party structure in the document or in the signature. That last property is useful: verifiers do not need to know about your internal governance.
For other structures, the n-of-n constraint makes MuSig2 unsuitable. MuSig2 cannot express a policy such as "any three of the five board members". If you force such a policy into MuSig2, the failure mode is severe: in an n-of-n scheme, one unavailable participant means no signature. A key holder on vacation blocks all updates. If the aggregate key is the only authorized key, a key holder who leaves the company after a dispute blocks all updates permanently.
Threshold Schnorr signatures (FROST and related constructions) give t-of-n. The IRTF CFRG published FROST as RFC 9591 in June 2024, with Informational status. RFC 9591 is not a Bitcoin BIP, and its secp256k1 ciphersuite does not make BIP340 signatures. That ciphersuite uses a different challenge hash, and it does not use the x-only public keys of BIP340. A BIP340-compatible variant is in draft as BIP445. As of September 2026, that pull request is still open, and it lists only experimental implementations.
Thus the Bitcoin-side tools for FROST are less mature than the tools for MuSig2. If you need thresholds, FROST is the direction to follow. Plan the integration work for it, and do not assume that it is a simple addition.
Bitcoin script multisig does not work for the document key, although it seems plausible. A 2-of-3 multisig output protects a Bitcoin transaction. It has no effect on a signature over a DID document. The document signature is not a transaction, and Bitcoin script never evaluates it. Multisig is a good tool for the beacon key. It is not a tool for the document key.
Separation by Verification Relationship
Custody design is easier if you do not treat "the keys of the DID" as one thing. A DID document has different verification relationships, and each relationship needs different treatment.
capabilityInvocationauthorizes document updates. It has the highest value and the lowest frequency of use. Keep the keys for this relationship in the safe.assertionMethodsigns Verifiable Credentials. If you issue many credentials, the issuance service uses this key all the time, and the key must be online.authenticationproves control for login flows. Services use it often, once per session. If an attacker compromises it, the damage is limited to what those sessions can do.
An issuance service with an online assertionMethod key is a normal and necessary design. The important property: if an attacker compromises that key, the attacker cannot change the document, because the key is not in capabilityInvocation. The attacker can issue fraudulent credentials, which is bad. But you can rotate the assertion key with an update that the attacker cannot authorize. Any credential status mechanism that you operate also stays under your control.
If you make this separation correctly, an incident costs you a revocation event. If you do not, an incident can cost you the identifier.
Backup and Derivation
btcr2 document keys are ordinary secp256k1 keys. Thus your backup process can use the same practice as for Bitcoin keys.
One detail is important for tools. The bip340-jcs-2025 cryptosuite encodes its Multikey with the secp256k1-pub multicodec and a 33-byte SEC-compressed public key (varint prefix 0xe701). A native x-only bip340-pub codec exists in the multiformats table, but the cryptosuite does not use it. Both entries have draft status, so neither entry is more stable than the other. Do not read a difference in maturity into this choice.
The practical result is convenient: BIP32 hierarchical derivation produces 33-byte compressed public keys, which is exactly the format that the cryptosuite uses. Thus you can derive document keys from a seed phrase on a dedicated derivation path. You can back up that seed with the procedures that your organization already uses for Bitcoin seeds. You can also rebuild the keys on a replacement machine, without a new process.
Two cautions apply:
- Use a dedicated path, and record it. A key that you cannot find in the tree is a lost key.
- Do not derive document keys from the same seed as the beacon keys. You separate the two keys because they have different exposure. A shared seed joins them again at exactly the layer that you tried to separate.
An Honest Assessment
This is the status as of September 2026, in plain terms.
Solid:
- Multiple authorized keys in different custody.
- Separate keys for each verification relationship.
- BIP32-derived keys, with backups that use established seed practices.
- Beacon Addresses that need approval to spend. This is ordinary Bitcoin multisig custody.
- A watch on those addresses for unexpected signals. Remember that a watch detects a problem, but it does not prevent it.
Workable with effort:
- MuSig2 n-of-n for two-party control, if n-of-n matches your governance.
- Software document keys on a hardened dedicated host, if the controls around the host are real.
Not ready yet:
- Support in many hardware wallets for BIP340 signatures over arbitrary payloads.
- Reliable BIP340 support across commodity HSMs and cloud key services.
- Turnkey threshold signatures for BIP340 document payloads. RFC 9591 specifies FROST, but the BIP340-compatible variant (draft BIP445) is not final.
- Ready-made policy engines that enforce approval workflows before a key signs a document update.
The last category is not a reason to delay deployment. It is a reason to design so that you can fill the gaps later without a new architecture. To do this:
- Keep the signer behind an interface.
- Do not hard-code assumptions about where a key is.
- Keep
capabilityInvocationsmall, so that a change of the custody model needs two updates, not a project.
Conclusion
For organizational DIDs, custody is less about one secure vault. It is more about several keys under different controls, so that the compromise of one key cannot take the identifier from you. This applies to the beacon side as much as to the document side. An approval requirement on the Beacon Address is part of the custody design, not an operational afterthought. The protocol gives you the primitives: multiple authorized keys, separate verification relationships, and an update mechanism that can remove a key you no longer trust. It does not give you thresholds, approval workflows, or hardware signers that support BIP340 for payloads other than transactions.
Design for the tools that exist now. Expect the tools to improve. Keep the interfaces where you will need them later.
Next week: revocation. Credential issuance is the easy half. Each mechanism that cancels credentials has privacy properties, and it is important to understand them before you choose one.