5.1: Generating Operational Keys
To date, we've used a single key to control your XID, the inception key. Sure, we've added keys for GitHub, for attestations, and for signing contracts, but that singular inception key was still what was used to control your XID itself. That means that it's all that lies between your XID and the loss of that identifier. Here's where we start to turn that around.
🧠 Related Concepts. After completing this tutorial, explore Key Management to understand the full key hierarchy model.
Objectives of this Section
After working through this section, a developer will be able to:
- Add operational keys with limited permissions
- Set up multiple devices safely
Supporting objectives include the ability to:
- Understand why single-key identity is risky for active work
Amira's Story: The Fragility of Single Keys
We've talked a number of times about maintaining hetergeneous keys. Having different keys for different purposes ensures that if a key is lost or compromised, the damage is limited.
That's doubly true for your inception key, which controls your entire XID. And that's especially important for Amira now that she's been accepted to work on SisterSpaces. If she were to lose her BRadvoc8 XID, she'd be back to square one.
So how does she protect the investment she's made in her pseudonmyous identity to this point? She follows the least and necessary design patterns, which means that she ensures that the keys that she uses every day have the least permissions necessary for the work she's doing.
That's a three-step process:
- Create operational keys (§5.1).
- Backup inception key separate from XID (§5.1).
- Remove inception key from XID (§5.1).
The main through-line of this chapter will continue to iterate this process with additional steps to improve security and resilience:
- Adjust operational permissions (§5.2).
- Improve resilience of backup (§5.3).
- Backup other keys (§5.4).
- Restore inception key to respond to operational compromise (§5.5).
The steps to do so will be the main through-line of this chapter.
The Power of Key Permissions
Besides supporting different keys, XIDs also support different key
permissions. xid key add --help displays instructions on how to add
keys, including information on how to give keys different permissions
(which we've just lightly touched upon before):
envelope xid key add --help
| Add a key to the XID document
|
| Usage: envelope xid key add [OPTIONS] [KEYS] [ENVELOPE]
|
| ...
|
| --allow <PRIVILEGE>
| Grant a specific permission to the key. May be repeated
|
| Possible values:
| - all: Allow all applicable XID operations
| - auth: Operational: Authenticate as the subject (e.g., log into services)
| - sign: Operational: Sign digital communications as the subject
| - encrypt: Operational: Encrypt messages from the subject
| - elide: Operational: Elide data under the subject's control
| - issue: Operational: Issue or revoke verifiable credentials on the subject's authority
| - access: Operational: Access resources under the subject's control
| - delegate: Management: Delegate priviledges to third parties
| - verify: Management: Verify (update) the XID document
| - update: Management: Update service endpoints
| - transfer: Management: Remove the inception key from the XID document
| - elect: Management: Add or remove other verifiers (rotate keys)
| - burn: Management: Transition to a new provenance mark chain
| - revoke: Management: Revoke the XID entirely
|
| [default: all]
As shown, key privileges are widely divided into two types. Operational permissions are what are needed for the use of your XID, while management permissions are what are needed to update your XID. The way to protect a XID is ultimately to store away management (especially inception) keys while using operational keys for your everyday usage.
Part 0: Verify Dependencies
Before you get started, you should (as usual) check your
envelope-cli version:
envelope --version
│ bc-envelope-cli 0.34.1
Then, reload your XID.
XID=$(cat envelopes/BRadvoc8-xid-s7-private-4-04.envelope)
XID_ID=$(envelope xid id $XID)
PASSWORD="your-password-from-previous-tutorials"
Part I: Understanding Key Permissions
Key permissions can be easily checked using the xid key commands.
Step 1: Listing Keys
To manage keys first requires understanding how to manipulate
them. The envelope command offers a number of ways to do so.
You can count the keys in a XID with envelope xid key count:
envelope xid key count $XID
| 3
You can list them with envelope xid key all:
envelope xid key all $XID
| ur:envelope/lrtpsotansgylftanshflfaohdcxhleosstafpwzesmsaychonvtpfbztyytcmhfmonefluylabzgtcmbbpseycnzcuytansgrhdcxmwaycebgqdrslksogrrnhygmhtdthtctaymkuroxueptgtehvwzosgeyfnlepkfgoycscstpsojziajljtjyjphsiajydpjeihkklfoycsfplftansfwlrhdghvdfmdrhpglmycecpasseyacpehpkticpclutcthnmsbztppmptkitshsotqdnnfzgalazclfjtpfsgjsieolpyvaglwdgaiakkfgstrnolyagmnekisftpbkuraarfrkolpmnsndjyswdlpfioldlersgtjkgazmdnztlflbgstprhcetehpnbgedyfrnshprsgdswaainlbrfmefloteopdfnvlfnwnjnaohddatansfphdcxpavacsswfllernaavopkhgbezcdkfyptldgemygtytdsfrjtpyeekkrplttkfpceoybwtpsotanshptansfwlrhdcxskehfypyjsrltdbgfpvwbwjnfygdqzrllamevtlulgfzprglehencyndwfftaabdgskorhchfzroyakbsfnbolcldsgddrkgghzmdkpfdikplareaxdecfbkbdbshflfaxtansgmgdgatngyzeplasbtjnbkwtylntimbbislroybstpsotansgmhdcxgugwrhwseycsdisbvdzewegrecoykensgrhpglfnfgnyimylchhtgewlaoeslkihoycsfncsfdcefxdems
| ur:envelope/lrtpsotansgylftanshflfaohdcxolmystmtwyhhgljscpamingewnkplnpssfmnsnlramdwclkpkswmkstbfgdngdtotansgrhdcxsoeymskoiyrseswelubkspfdhllpmyksrpmkcmwzaoplwdlrfhzoropslpnlcmadoycscstpsoisfwgmhsiekojliaetoycsfncsfglfoycsfplftansfwlrhdghztsoynoxlshsrpcfdlkggudpskttvypekpjnhljtpsspfsrneyplhhcwlgfmceiokktlrdltfhvyykaostfrdttbehlpwypkiewfwdpetlkgdngrnegeaemdmuqdrpfesbmehgasdwadrdftcnemueimaxisjeeeghksdwwygskirhcylasataytlymsdasfspgdmnoyiddirkmwhsesbgrysnbwmtdpnsgdhddatansfphdcxdtrortsrldkghddybyfdlrlelepmjsprtiaogykgmeoywlhdlysegywprhjtuessoybwtpsotanshptansfwlrhdcxgrbwfrrdbylgpkgovsuevldpmhonzmenbtmttytefsdplbmthlkgjsnlkewlwmcxgspkfsdrlsytismupmgrcagdfzgdmsgysoaxoxcswladrnrdtnrnbgiewduthflfaxtansgmgdiecxisgdrhrhmhvlmkrdgsjkrtlttortoybstpsotansgmhdcxrkkemtyldezmietdspmenscfcpbkfwykketirdolhpadbgylbeesykgufnjlhllfnbylurzm
| ur:envelope/lrtpsotansgylftanshflfaohdcxtyjeuyceehntqzmwtdhfoscmguplcyeoaarhcxghreynrlfleynefnbtiodyesattansgrhdcxntesveuelkhdbnwdutynettbaarnnbspgefsvemohtnezeldcncmueldtkjlfxhdoycscstpsojlhsjyjyihjkjyhsjyinjljtdpjeihkkoycsfncsfdlfoycsfplftansfwlrhdghsesfgliagewldimenlaebzcfpdlsqztsbsbbroeolfflpeckaegwytlkfdgyynlamnfmahbdtenssgfskpcywpluaefdcxcwidiopamupswpfsldolfssraebnswkipfpktnoxplzcrtdllbndcsseykdlosvatbtnattipegswkvlaaltsbpyoxnyahhkdrcagddtotlpbwvyluhywtenflihhyvtueprbkhddatansfphdcxwyjegooepakobtaxksjlhnfsfdbdhsteynbdvduoztpaoywnkendbzryhhwymstdoybwtpsotanshptansfwlrhdcxuyfxsoqzfxcfsshngopmpkjthndisnfyhysksagltltsnebaluidcxrtfxdibkeegsflldgwurdyjtvejljsfemtcegdmshssnrobdwltewmtptotestistiqzgshflfaxtansgmgdfsjlcxdskpbzswwzswgwfwtockjkynaaoybstpsotansgmhdcxhgatwkkepkgafysffruywegychtbidvejomkhhrlsbidmnftgapehdlbwybemkyttikosest
If you know what's where in a XID, you can retrieve a specific key
with envelope xid key at:
envelope xid key at 0 $XID
| ur:envelope/lrtpsotansgylftanshflfaohdcxhleosstafpwzesmsaychonvtpfbztyytcmhfmonefluylabzgtcmbbpseycnzcuytansgrhdcxmwaycebgqdrslksogrrnhygmhtdthtctaymkuroxueptgtehvwzosgeyfnlepkfgoycscstpsojziajljtjyjphsiajydpjeihkklfoycsfplftansfwlrhdghvdfmdrhpglmycecpasseyacpehpkticpclutcthnmsbztppmptkitshsotqdnnfzgalazclfjtpfsgjsieolpyvaglwdgaiakkfgstrnolyagmnekisftpbkuraarfrkolpmnsndjyswdlpfioldlersgtjkgazmdnztlflbgstprhcetehpnbgedyfrnshprsgdswaainlbrfmefloteopdfnvlfnwnjnaohddatansfphdcxpavacsswfllernaavopkhgbezcdkfyptldgemygtytdsfrjtpyeekkrplttkfpceoybwtpsotanshptansfwlrhdcxskehfypyjsrltdbgfpvwbwjnfygdqzrllamevtlulgfzprglehencyndwfftaabdgskorhchfzroyakbsfnbolcldsgddrkgghzmdkpfdikplareaxdecfbkbdbshflfaxtansgmgdgatngyzeplasbtjnbkwtylntimbbislroybstpsotansgmhdcxgugwrhwseycsdisbvdzewegrecoykensgrhpglfnfgnyimylchhtgewlaoeslkihoycsfncsfdcefxdems
But you'll usually need to find a key instead, which can be done with
the envelope xid key find command. You can always search for the
inception key:
envelope xid key find inception $XID
| ur:envelope/lrtpsotansgylftanshflfaohdcxolmystmtwyhhgljscpamingewnkplnpssfmnsnlramdwclkpkswmkstbfgdngdtotansgrhdcxsoeymskoiyrseswelubkspfdhllpmyksrpmkcmwzaoplwdlrfhzoropslpnlcmadoycscstpsoisfwgmhsiekojliaetoycsfncsfglfoycsfplftansfwlrhdghztsoynoxlshsrpcfdlkggudpskttvypekpjnhljtpsspfsrneyplhhcwlgfmceiokktlrdltfhvyykaostfrdttbehlpwypkiewfwdpetlkgdngrnegeaemdmuqdrpfesbmehgasdwadrdftcnemueimaxisjeeeghksdwwygskirhcylasataytlymsdasfspgdmnoyiddirkmwhsesbgrysnbwmtdpnsgdhddatansfphdcxdtrortsrldkghddybyfdlrlelepmjsprtiaogykgmeoywlhdlysegywprhjtuessoybwtpsotanshptansfwlrhdcxgrbwfrrdbylgpkgovsuevldpmhonzmenbtmttytefsdplbmthlkgjsnlkewlwmcxgspkfsdrlsytismupmgrcagdfzgdmsgysoaxoxcswladrnrdtnrnbgiewduthflfaxtansgmgdiecxisgdrhrhmhvlmkrdgsjkrtlttortoybstpsotansgmhdcxrkkemtyldezmietdspmenscfcpbkfwykketirdolhpadbgylbeesykgufnjlhllfnbylurzm
You can also look for a key with a specific name:
envelope xid key find name "attestation-key" $XID
| ur:envelope/lrtpsotansgylftanshflfaohdcxtyjeuyceehntqzmwtdhfoscmguplcyeoaarhcxghreynrlfleynefnbtiodyesattansgrhdcxntesveuelkhdbnwdutynettbaarnnbspgefsvemohtnezeldcncmueldtkjlfxhdoycscstpsojlhsjyjyihjkjyhsjyinjljtdpjeihkkoycsfncsfdlfoycsfplftansfwlrhdghsesfgliagewldimenlaebzcfpdlsqztsbsbbroeolfflpeckaegwytlkfdgyynlamnfmahbdtenssgfskpcywpluaefdcxcwidiopamupswpfsldolfssraebnswkipfpktnoxplzcrtdllbndcsseykdlosvatbtnattipegswkvlaaltsbpyoxnyahhkdrcagddtotlpbwvyluhywtenflihhyvtueprbkhddatansfphdcxwyjegooepakobtaxksjlhnfsfdbdhsteynbdvduoztpaoywnkendbzryhhwymstdoybwtpsotanshptansfwlrhdcxuyfxsoqzfxcfsshngopmpkjthndisnfyhysksagltltsnebaluidcxrtfxdibkeegsflldgwurdyjtvejljsfemtcegdmshssnrobdwltewmtptotestistiqzgshflfaxtansgmgdfsjlcxdskpbzswwzswgwfwtockjkynaaoybstpsotansgmhdcxhgatwkkepkgafysffruywegychtbidvejomkhhrlsbidmnftgapehdlbwybemkyttikosest
(And isn't that a lot easier than finding the assertion as we demonstrated in §4.3?)
These examples all reveal envelopes, and the keys are encrypted. Which
is great when you're doing elision of an envelope leaf and just need a
digest to do so. If you instead need to extract the private key, you
can do so by adding the --private flag and if the XID's private keys
are encrypted, also the --password flag.
envelope xid key find name --private --password "$PASSWORD" "attestation-key" $XID
| ur:crypto-prvkeys/lftansgolfaohdcxtbveutjzcehdgwhenbonmecedrmktkiojkrpbtmnrhbsttuozeeocfhlvybzvaoltansgehdcxgelkclzsfrmnfllgeoeonykoatdmdszcvwcxndfyaynemyhdlusklyeswtonhlnngmhnspnd
Step 2: Check Current Key Permissions
A simple for loop of the sort that we've used before can list
exactly what each key in a XID does:
read -a KEYLIST <<< $(envelope xid key all "$XID")
for i in "${KEYLIST[@]}"
do
envelope format $i
done
This reveals the three keys that we've added over the course of this tutorial: Amira's inception key and two signing keys, one for attestations and one for contracts:
PublicKeys(57f4126d, SigningPublicKey(e15ac4c2, Ed25519PublicKey(a4893d82)), EncapsulationPublicKey(49ad97ce, X25519PublicKey(49ad97ce))) [
{
'privateKey': ENCRYPTED [
'hasSecret': EncryptedKey(Argon2id)
]
} [
'salt': Salt
]
'allow': 'Sign'
'nickname': "contract-key"
]
PublicKeys(a9818011, SigningPublicKey(5f1c3d9e, Ed25519PublicKey(b2c16ea3)), EncapsulationPublicKey(96209c0f, X25519PublicKey(96209c0f))) [
{
'privateKey': ENCRYPTED [
'hasSecret': EncryptedKey(Argon2id)
]
} [
'salt': Salt
]
'allow': 'All'
'nickname': "BRadvoc8"
]
PublicKeys(6d94a1eb, SigningPublicKey(128ffa82, Ed25519PublicKey(363eab4e)), EncapsulationPublicKey(e46036f9, X25519PublicKey(e46036f9))) [
{
'privateKey': ENCRYPTED [
'hasSecret': EncryptedKey(Argon2id)
]
} [
'salt': Salt
]
'allow': 'Sign'
'nickname': "attestation-key"
]
Now we know what we're working with!
Part II: Adding Operational Keys
Two sorts of protection are required for keys. Obviously, they must be protected from loss. That's going to be the topic of §5.3: how to ensure that the inception key doesn't go missing. However, they also have to be protected from compromise: someone stealing them and using them without permission.
That's going to be the topic of this chapter, where we practice the least and necessary design patterns by creating new keys with limited permissions for everyday usage, so that if keys are stolen, they're these keys, rather than the ones that control the XID.
Step 3: Generate a Laptop XID Key
To start with, Amira is going to generate a new operational key for her XID for the laptop where she does all of her work for SisterSpaces.
LAPTOP_PRVKEYS=$(envelope generate prvkeys --signing ed25519)
LAPTOP_PUBKEYS=$(envelope generate pubkeys "$LAPTOP_PRVKEYS")
echo "✅ Generated laptop operational key"
│ ✅ Generated laptop operational key
Step 4: Add Key with Limited Permissions
The permissions aren't actually in the key, which is just a standard ed25519 key, but instead in the XID. As we've seen previously, when you add a key that's when you choose the permissions it'll have.
The following adds a key with an extensive list of operational permissions, but no management permissions:
XID_WITH_OPERATIONAL_KEY_1=$(envelope xid key add \
--verify inception \
--nickname "laptop-key" \
--allow auth \
--allow sign \
--allow encrypt \
--allow elide \
--allow issue \
--allow access \
--private encrypt \
--encrypt-password "$PASSWORD" \
"$LAPTOP_PRVKEYS" \
"$XID")
envelope format reveals a key with a much longer list of permissions
than the other keys to date (but less than the 'All' permissions of
the inception key):
envelope format $XID_WITH_OPERATIONAL_KEY_1
| ✅ Added operational (laptop) key to XID
|
| ...
|
| 'key': PublicKeys(c32d7426, SigningPublicKey(59e9ad4d, Ed25519PublicKey(425b8e15)), EncapsulationPublicKey(c2b3746b, X25519PublicKey(c2b3746b))) [
| {
| 'privateKey': ENCRYPTED [
| 'hasSecret': EncryptedKey(Argon2id)
| ]
| } [
| 'salt': Salt
| ]
| 'allow': 'Access'
| 'allow': 'Authorize'
| 'allow': 'Elide'
| 'allow': 'Encrypt'
| 'allow': 'Issue'
| 'allow': 'Sign'
| 'nickname': "laptop-key"
| ]
Step 5: Generate a Laptop GitHub Key
Best practice is also to have a different GitHub key for each device. Because Amira has only been doing SisterSpaces work on her laptop, the signing key she created in §3.1 is effectively her laptop SSH signing key.
She might want to adjust her labeling of the key now that she's thinking about keys on a per-device basis. More importantly, if she ever does SisterSpaces GitHub work on a different device, she should create another key for use exclusively on that device.
Step 6: Add a Portable Drive XID Key
At a later date, Amira goes on a trip during a time when she's likely to need to make some updates to SisterSpaces files using her BRadvoc8 identity. She doesn't want to bring either her inception key or her fully operational laptop key.
Before the trip, she archives everything, with the plan to only use a more limited key that she's going to keep on a bootable portable drive.
As usual, she creates the keys:
PORTABLE_PRVKEYS=$(envelope generate prvkeys --signing ed25519)
PORTABLE_PUBKEYS=$(envelope generate pubkeys "$LAPTOP_PRVKEYS")
Then she adds them to her XID with a different set of permissions. She
opts to remove the encrypt permission and the issue permission, so
that if her key goes stray when she's on the move, an attacker can't
decrypt her content nor create new credentials. This follows the
least/necessary pattern: she plans to be working on PRs for
SisterSpaces, not these other things
XID_WITH_OPERATIONAL_KEY_2=$(envelope xid key add \
--nickname "portable-key" \
--allow auth \
--allow sign \
--allow elide \
--allow access \
--private encrypt \
--encrypt-password "$PASSWORD" \
"$PORTABLE_PRVKEYS" \
"$XID_WITH_OPERATIONAL_KEY_1")
echo "✅ Generated portable operational key"
Here's a look at her full set of keys afterward:
envelope format $XID_WITH_OPERATIONAL_KEY_2
| XID(5f1c3d9e) [
|
| ...
|
| 'key': PublicKeys(57f4126d, SigningPublicKey(e15ac4c2, Ed25519PublicKey(a4893d82)), EncapsulationPublicKey(49ad97ce, X25519PublicKey(49ad97ce))) [
| {
| 'privateKey': ENCRYPTED [
| 'hasSecret': EncryptedKey(Argon2id)
| ]
| } [
| 'salt': Salt
| ]
| 'allow': 'Sign'
| 'nickname': "contract-key"
| ]
| 'key': PublicKeys(6d94a1eb, SigningPublicKey(128ffa82, Ed25519PublicKey(363eab4e)), EncapsulationPublicKey(e46036f9, X25519PublicKey(e46036f9))) [
| {
| 'privateKey': ENCRYPTED [
| 'hasSecret': EncryptedKey(Argon2id)
| ]
| } [
| 'salt': Salt
| ]
| 'allow': 'Sign'
| 'nickname': "attestation-key"
| ]
| 'key': PublicKeys(a9818011, SigningPublicKey(5f1c3d9e, Ed25519PublicKey(b2c16ea3)), EncapsulationPublicKey(96209c0f, X25519PublicKey(96209c0f))) [
| {
| 'privateKey': ENCRYPTED [
| 'hasSecret': EncryptedKey(Argon2id)
| ]
| } [
| 'salt': Salt
| ]
| 'allow': 'All'
| 'nickname': "BRadvoc8"
| ]
| 'key': PublicKeys(c32d7426, SigningPublicKey(59e9ad4d, Ed25519PublicKey(425b8e15)),| EncapsulationPublicKey(c2b3746b, X25519PublicKey(c2b3746b))) [
| {
| 'privateKey': ENCRYPTED [
| 'hasSecret': EncryptedKey(Argon2id)
| ]
| } [
| 'salt': Salt
| ]
| 'allow': 'Access'
| 'allow': 'Authorize'
| 'allow': 'Elide'
| 'allow': 'Encrypt'
| 'allow': 'Issue'
| 'allow': 'Sign'
| 'nickname': "laptop-key"
| ]
| 'key': PublicKeys(d930b267, SigningPublicKey(5f6630d7, Ed25519PublicKey(d72a49de)), EncapsulationPublicKey(ae36f917, X25519PublicKey(ae36f917))) [
| {
| 'privateKey': ENCRYPTED [
| 'hasSecret': EncryptedKey(Argon2id)
| ]
| } [
| 'salt': Salt
| ]
| 'allow': 'Access'
| 'allow': 'Authorize'
| 'allow': 'Elide'
| 'allow': 'Sign'
| 'nickname': "portable-key"
| ]
| ...
| ]
Step 7: Review and Store
You're now ready to create a new edition of your XID that announces your new operational keys.
As usual, first update your provenance mark:
XID_WITH_KEYS=$(envelope xid provenance next \
--password "$PASSWORD" \
--sign inception \
--private encrypt \
--generator encrypt \
--encrypt-password "$PASSWORD" \
"$XID_WITH_OPERATIONAL_KEY_2")
| echo "✅ Provenance advanced"
Then, make a public version:
PUBLIC_XID_WITH_KEYS=$(envelope xid export --private elide --generator elide "$XID_WITH_KEYS")
Finally, save everything away:
echo "$LAPTOP_PRVKEYS" > envelopes/key-laptop-private-5-01.ur
echo "$LAPTOP_PUBKEYS" > envelopes/key-laptop-public-5-01.ur
echo "$PORTABLE_PRVKEYS" > envelopes/key-portable-private-5-01.ur
echo "$PORTABLE_PUBKEYS" > envelopes/key-portable-public-5-01.ur
echo "$PUBLIC_XID_WITH_KEYS" > envelopes/BRadvoc8-xid-public-5-01.envelope
echo "$XID_WITH_KEYS" > envelopes/BRadvoc8-xid-private-5-01.envelope
Note that you haven't actually increased your security yet! Though you now have new, operational keys, the inception key is still there as well! We'll get to that ...
Key Type Comparison
At this point, Amira can review her set of six total keys (five of which are in her XID):
| Key Type | Purpose | Verified Against | Added In |
|---|---|---|---|
| 👤 XID inception key | Signs XID document updates | XID itself | §1.3 |
| 🗣️ Attestation key | Signs attestations | XID key list | §2.1 |
| 🖋️ SSH signing key | Signs Git commits | GitHub account | §3.1 |
| 📄️ Contract signing key | Signs contracts | XID key list | §4.1 |
| 💻 Laptop Key | Operational Key | XID key list | §5.1 |
| ⏏️ Portable Key | Limited Operational Key | XID key list | §5.1 |
Part III: Eliding Keys
In order for the use of an operational key to be meaningful, the inception key must not also be available. Obviously, you don't want to just delete it, or you can't modify your XID either, so you must undertake a two part process:
- Store your inception key.
- Elide your inception key.
Step 8: Store Your Inception Key
The easiest way to store your inception key is to store the full, current copy of your XID. Just place it in offline-storage and check it occasionally to make sure it's still there.
cp envelopes/BRadvoc8-xid-private-5-01.envelope <OFFLINE-STORAGE>
Only bring the full XID online when you need to make updates to it.
Alternatively, or in addition, you can choose to just store your inception key.
INCEPTION_PRVKEYS=$(envelope xid key find inception --private --password "$PASSWORD" $XID_WITH_KEYS)
echo $INCEPTION_PRVKEYS > <OFFLINE-STORAGE>/xid-inception-key.envelope
You generally want your backups to be more resilient than this for something as important as an inception key, and we'll talk about how to manage that in §5.3. But for now, the backup is a fine first step.
Step 9: Elide Your Inception Key
With a backup copy of your XID (or at least the inception key) made, you can now safely elide the key from your operational XID.
This is easily done with the new commands from this section that detailed how to find a specific key and the lessons learned from §4.3.
INCEPTION_PRVKEYS=$(envelope xid key find inception $XID_WITH_KEYS)
INCEPTION_DIGEST=$(envelope digest $INCEPTION_PRVKEYS)
OPERATIONAL_XID=$(envelope elide removing $INCEPTION_DIGEST $XID_WITH_KEYS)
Amira should now use the $OPERATIONAL_XID (really an Operational
View of her XID) on her laptop while keeping the original XID in an
offline storage. When she goes traveling, she would additionally elide
the laptop-key from her XID, so that only the less powerful
portable-key is available.
echo "$OPERATIONAL_XID" > envelopes/BRadvoc8-xid-operational-5-01.envelope
XID 📄 seq: 8 View Comparison
In this section, Amira produced a new seq 8 for her XID. She also
made a number of views, showing again the power of elision to make
appropriate views of a XID for different purposes.
| Description | Notes | Created In |
|---|---|---|
| 🔒 Private View | FulL XID | §5.1 |
| 👁️ Public View | Elided key material | §5.1 |
| 💻 Operational View | Removed inception key | §5.1 |
| ⏏️ Portable View | Removed two keys |
Key Protection Comparison
The following chart shows why using the Operational View of your XID is safer than using the full Private View.
| Scenario | Private View (Management XID) | Operational View (Operational XID) |
|---|---|---|
| Attacker signs things | Yes | Yes |
| Attacker adds their key | Yes | No |
| Attacker removes your keys | Yes | No |
| You can revoke attacker's access | Sort of (XIDs branch) | Yes (only you have inception key) |
| Identity recovery | Difficult | Straightforward |
Using the Opertional View limits the blast radius of a compromise.
The following concrete situation, where Amira's laptop is snatched from a café and the keys were visible, demonstrates the differential damage.
Private View. The thief extracts Amira's inception key, adds their
own key with 'All' permissions, then removes Amira's key. By the
time Amira realizes what happened, her identity belongs to someone
else. Her endorsements, her CLA signature, and her reputation are now
all controlled by a stranger. Sure, she could create her own copy of
the XID with a new inception key, but no one can now say which one is
the real one.
Operational View. The thief gets portable-key, which can only
engage in limited operational activities. They might sign some things
before Amira notices, but they cannot add their own keys or remove
hers. Amira uses her inception key (stored securely elsewhere) to
revoke laptop-key and add a new operational key. Her identity
remains intact. The damage is contained to a few potentially
fraudulent signatures that she can publicly disavow.
We'll return to this scenario in §5.5 and see how Amira recovers from the compromise of her Operational View XID.
Summary: Generating Operational Keys
You don't need to keep your inception key in your XID, and in fact doing so is a security risk. The XID keys system supports improved security by allowing you to create a key with lesser permissions, such as a key that only has operational permissions. You can then store copies of your full XID offline and remove the inception key from your in-use view.
Additional Files
Envelopes: The envelopes directory contains envelopes and keys created in this section, including the private, public, and operational views of Amira's updated XID.
Scripts: The
scripts
directory contains
05_1_Generating_Operational_Keys-SCRIPT.sh,
which runs through all the commands in this section. From the command
line, git clone
https://github.com/BlockchainCommons/XID-Quickstart.git, then cd
XID-Quickstart, then bash scripts/05_1_Generating_Operational_Keys-SCRIPT.sh
test it.
Exercises
- Create a new XID key and give it operational permissions.
- Create another XID key with even fewer permissions.
- Create an operational version of your XID.
What's Next
You've now successfully added and elided keys, but what if you want to change or rotate keys? That's the topic of §5.2.
Alternative, you may want to jump to §5.3, which discusses more resilient techniques for backing up your inception key.
Appendix I: Key Terminology
Inception Key - The original key created when the XID was established, typically with full management and operational permissions. Should be highly protected. Also called the "private key base" in technical documentation.
Management Key - Any XID key with management permissions, including the Inception Key.
Management XID - A XID with Management Keys such as the Inception Key.
Operational View - An elided view of a XID that removes any management keys.
Operational Key - A key with limited permissions (typically sign-only) used for daily work. Compromise is contained.
Operational XID - A XID without Management Keys, including the Inception Key. Really, an Operational View.
Permission Scope - The specific operations a key is allowed to perform (
sign,encrypt,elect,revoke, etc.).🧠 Learn more. The Key Management concept doc explains the full key hierarchy model and permission system.
Appendix II: Common Questions
Q: Can I have multiple inception keys?
A: No. Each XID should have exactly one key with full permissions (the inception key). Multiple "master" keys would create ambiguity about who controls the identity.
Q: What if I lose my inception key?
A: Without the inception key, you cannot add or remove keys from your XID. The identity becomes frozen: existing operational keys keep working, but you can't recover if they're compromised. This is why §5.3 focuses on more robust offline backup. Never keep your inception key only on a device that could be lost or stolen.
Q: How many operational keys is too many?
A: It depends on your threat model. More keys means more flexibility but also more to track. A typical setup might have 2-4 operational keys (primary device, backup device, maybe a hardware token). If you're managing more than 5-6 operational keys, consider whether you really need that many active signing contexts.