From bc795eb01e9bc025b7c1d1e484f6363de3f6ac45 Mon Sep 17 00:00:00 2001 From: "@ChristopherA" Date: Wed, 26 Nov 2025 16:14:12 -0800 Subject: [PATCH 1/4] Remove old tutorials for November 2025 rewrite - Archived old tutorials in development repo - Fresh start for pedagogically-redesigned tutorial series - Old content preserved at main:c8bb0a3 Signed-off-by: @ChristopherA --- tutorials/01-your-first-xid.md | 750 ---------------- tutorials/02-understanding-xid-structure.md | 607 ------------- tutorials/03-self-attestation-with-xids.md | 778 ----------------- tutorials/04-peer-endorsement-with-xids.md | 915 -------------------- tutorials/05-key-management-with-xids.md | 648 -------------- tutorials/README.md | 68 -- 6 files changed, 3766 deletions(-) delete mode 100644 tutorials/01-your-first-xid.md delete mode 100644 tutorials/02-understanding-xid-structure.md delete mode 100644 tutorials/03-self-attestation-with-xids.md delete mode 100644 tutorials/04-peer-endorsement-with-xids.md delete mode 100644 tutorials/05-key-management-with-xids.md delete mode 100644 tutorials/README.md diff --git a/tutorials/01-your-first-xid.md b/tutorials/01-your-first-xid.md deleted file mode 100644 index 0128c78..0000000 --- a/tutorials/01-your-first-xid.md +++ /dev/null @@ -1,750 +0,0 @@ -# Creating Your First XID - -This tutorial introduces Amira, a software developer with a -politically sensitive background who wants to contribute to social -impact projects without risking her professional position or revealing -her identity. By the end, you'll have created an XID (eXtensible -IDentifier) that enables pseudonymous contributions while building -trust progressively. - -**Time to complete: 15-20 minutes** - -> **Related Concepts**: Before or after completing this tutorial, you -may want to read about [XID Fundamentals](../concepts/xid.md) and -[Gordian Envelope Basics](../concepts/gordian-envelope.md) to -understand the theoretical foundations behind what you're -implementing. - -## Prerequisites - -- Basic terminal/command line familiarity -- The [Gordian Envelope-CLI](https://github.com/BlockchainCommons/bc-envelope-cli-rust) tool installed (release 13.1 or later). - -## What You'll Learn - -- How to create a minimal XID for pseudonymous contributions -- How to add and verifiable assertions to your XID and sign them -- How to create public versions of your XID redacting private data using elision -- How to maintain strong cryptographic integrity while sharing only what you choose -- How to organize and store XID files using secure naming conventions - -## Amira's Story: Why Pseudonymous Identity Matters - -Amira is a successful software developer working at a prestigious -multinational bank in Boston. With her expertise in distributed -systems security, she earns a comfortable living, but she wants more -purpose in her work. On the advice of her friend Charlene, Amira -discovers RISK, a network that connects developers with social impact -projects while protecting participants' privacy. - -Given Amira's background in a politically tense region, contributing -openly to certain social impact projects could risk her visa status, -professional position, or even the safety of family members back -home. Yet she's deeply motivated to use her skills to help oppressed -people globally. This tension between professional security and -meaningful contribution creates a specific need. - -However, Amira faces a dilemma: she can't contribute anonymously -because anonymous contributions lack credibility. Project maintainers -need confidence in the quality and provenance of code, especially for -socially important applications. She needs a solution that protects -her identity while allowing her to build a verifiable reputation for -her skills. - -Amira needs a technological solution that allows her to: - -1. Share her valuable security expertise without revealing her real identity -2. Build verifiable trust through the quality of her work, not her existing credentials -3. Establish a consistent "BRadvoc8" (aka Basic Rights Advocate) digital presence that can evolve and build reputation over time -4. Connect with project leaders like Ben from the women's services non-profit -5. Protect herself from adversaries who might target her for her contributions - -This is where XIDs come in: they enable pseudonymous identity with -progressive trust development, allowing Amira to safely collaborate on -projects aligned with her values while maintaining separation between -her pseudonymous contributions and her legal identity. - -## Why XIDs Matter - -XIDs provide significant advantages that go well beyond standard -cryptographic keys: - -1. **Stable identity** - XIDs maintain the same identifier even when -you rotate keys. -2. **Progressive trust** - XIDs let you selectively share different -information with different parties. -3. **Rich metadata** - XIDs can contain structured attestations, -endorsements, and claims. -4. **Peer validation** - XIDs enable others to make cryptographically -verifiable claims about your identity. -5. **Multi-key support** - XIDs can link multiple keys for different -devices while maintaining a single identity. -6. **Recovery mechanisms** - XIDs support recovery without losing your -reputation history. -7. **Cryptographic integrity** - XIDs preserve verifiability even when -portions are not included when sharing. - -This first tutorial is deliberately simple to get you started with the -basics. While we're using basic cryptographic primitives in this -tutorial, Gordian XIDs support many cryptographic key types, including -advanced formats for threshold signatures and post-quantum -cryptography. As we progress through subsequent tutorials, we'll -explore these more advanced capabilities in depth. - -## Step 1: Creating a Private XID - -Now that we understand why XIDs are valuable, let's help Amira create -her "BRadvoc8" identity. - -An XID is fundamentally a digital container built using cryptographic -key material. To create one, Amira will need to generate a private key -base specifically for her XID. This command creates the cryptographic -foundation for all her future operations. - -```sh -XID_PRVKEY_BASE=$(envelope generate prvkeys) -echo "Generated private key base for XID" -``` - -Now you can create a new XID using this private key base. This command -generates an XID container that incorporates the public key derived -from the private key base while also securely storing the private key -information within the structure: - -```sh -XID=$(envelope xid new "$XID_PRVKEY_BASE") -echo "Created new XID" -``` - -At this point, your XID contains the private key information. Let's -view it in a human-readable format to examine its structure: - -```sh -envelope format "$XID" -``` - -You should see output similar to: - -``` -XID(d5aad53e) [ - 'key': PublicKeys(6d165468) [ - { - 'privateKey': PrivateKeys(a7ba7576) - } [ - 'salt': Salt - ] - 'allow': 'All' - ] -] -``` - -The XID starts with a minimal structure: just a unique identifier -(`d5aad53e and cryptographic key material in the form of a public and -private key pair. Note that the `privateKey` section contains -sensitive information derived from your previously generated private -key base, thus this data should be protected with the same diligence -you would apply to SSH or other cryptographic keys. - -## Toward an Enhanced XID - -The basic XID provides a cryptographic foundation but its true power -comes from adding assertions and structure. In the next part of this -tutorial, we'll transform a simple XID into a rich digital identity. - -## Step 2: Creating a Basic Public XID - -To make her XID safely shareable, Amira needs to create a public copy -of her XID by removing the private key components. This process is -called elision, which selectively removes private information while -preserving the cryptographic integrity of the envelope. - -This process involves: - -1. Finding the private key component within the XID -2. Eliding (removing) it while maintaining the cryptographic integrity -3. Saving the resulting public XID for sharing - -We'll implement these steps as follows: - -To find the private key component that needs to be elided, Amira first -extracts the key assertion and locates the private key: - -```sh -KEY_ASSERTION=$(envelope xid key at 0 "$XID") -PRIVATE_KEY_ASSERTION=$(envelope assertion find predicate known privateKey "$KEY_ASSERTION") -PRIVATE_KEY_ASSERTION_DIGEST=$(envelope digest "$PRIVATE_KEY_ASSERTION") -``` - -Now that she has identified the private key assertion, she can elide -it from the XID to create a basic public version that's safe to share: - -```sh -BASIC_PUBLIC_XID=$(envelope elide removing "$PRIVATE_KEY_ASSERTION_DIGEST" "$XID") -echo "Created basic public XID" -``` - -Let's view the resulting basic public XID: - -```sh -envelope format "$BASIC_PUBLIC_XID" -``` - -``` -XID(d5aad53e) [ - 'key': PublicKeys(6d165468) [ - 'allow': 'All' - ELIDED - ] -] -``` - -Notice the `ELIDED` marker in the output, which indicates where the -private key information has been removed. This basic public XID -retains its cryptographic integrity but no longer contains the -sensitive private key material. - -## XID Version Types - -An important feature of XIDs is the ability to create different -versions for different purposes. Throughout this tutorial, Amira -creates three versions of her XID: - -1. A **private XID** (Step 1) that contains her private key material, -kept secure -2. A **basic public XID** (Step 2) with the private key elided, that -can be safely shared -3. An **enhanced public XID** (Step 3) with additional persona details -and signature, also safe to share - -The public versions are created through a process called elision, -which selectively removes private information while preserving the -cryptographic integrity of the envelope. - -## Proper File Organization - -For real-world usage, Amira will want to organize her files in a -dedicated directory with names that clearly indicate their security -level. She uses clear naming conventions: - -- Files with `-private` contain sensitive private keys that must be - kept secret -- Files with `-basic-public` contain a minimal public XID with private - keys elided -- Files with `-enhanced-public` contain a feature-rich public XID with - additional assertions -- Files with `.format` are human-readable versions of the - corresponding envelope files -- Files with `.xid` or `.envelope` contain the binary serialized versions - -All files are stored in a timestamp-based directory (e.g., -`xid-20250510123456`) to keep versions organized. - -These naming conventions help prevent accidentally sharing private key -material. - -Now that we understand the basic principles of XIDs and their -organization, let's put everything together to create a fully -functional, feature-rich XID that Amira can use for her pseudonymous -contributions. - -## Step 3: Creating an Enhanced XID with Persona Details - -Having created a basic public XID, Amira now wants to create an -enhanced version that provides more information about her persona and -resolution methods, while still keeping her private key information -secure. - -> **Quick Reference**: An "enhanced XID" goes beyond basic -identification by adding structure, context, and verifiable -assertions. The process below transforms a simple public XID (with -just a key) into a rich digital identity that includes persona -information, service details, and resolution methods - all while -maintaining cryptographic integrity. - -Amira will start with the basic public XID that she created -earlier. This is a basic XID with the private key components already -elided (removed while preserving cryptographic integrity) for safe -sharing. She assigns this to a new variable to begin her enhancements: - - -```sh -ENHANCED_XID="$BASIC_PUBLIC_XID" -``` - -``` -XID(d5aad53e) [ - 'key': PublicKeys(6d165468) [ - 'allow': 'All' - ELIDED - ] -] -``` - -Notice how the initial XID contains only a public key with elided -(removed) private components. Now Amira will transform this into a -rich, structured identifier. - -Let's compare where we're starting from and where we're heading: - -| **Basic Public XID (Starting Point)** | **Enhanced XID (Our Goal)** | -|----------------------------------|------------------------------| -| A minimal XID with just public keys | A rich XID with structure and assertions | -| No type declaration | Clear "Persona" type | -| No nickname | Human-readable "BRadvoc8" nickname | -| No service info | Contains GitHub account details | -| No resolution methods | Multiple resolution URIs | -| Not signed | Cryptographically signed | -| Flat structure | Hierarchical organization | - - -| **Sample Basic Public XID** | **Sample Enhanced XID** -|----------------------------------|------------------------------| -| XID(d5aad53e) [ | XID(d5aad53e) [ -| 'key': PublicKeys(...) [ | 'isA': "Persona" -| 'allow': 'All' | "nickname": "BRadvoc8" -| ELIDED | "service": "GitHub" [...] -| ] | "resolveVia": URI(...) -| ] | 'key': PublicKeys(...) -| | ] [ -| | 'signed': Signature -| | ] - -### Creating a Persona - -Amira begins the process by adding a type declaration to clearly -identify this as a persona XID. This helps systems understand what -kind of entity this XID represents. Note that `isA` is used as a -[known -value](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2023-002-known-value.md) -rather than a string. This makes the XID more semantically meaningful -to systems that understand these known values: - -> **Technical Note**: Known values (like `isA`, `dereferenceVia`, -etc.) are special values in the Gordian Envelope system that have -standard, well-defined meanings. Using known values instead of -strings enables better interoperability, validation, and semantic -understanding across different systems. - -```sh -ENHANCED_XID=$(envelope assertion add pred-obj known isA string "Persona" "$ENHANCED_XID") -``` - -Then she adds a nickname to provide a human-readable identifier, using -the XID_NAME variable: - -```sh -XID_NAME=BRadvoc8 -ENHANCED_XID=$(envelope assertion add pred-obj string "nickname" string "$XID_NAME" "$ENHANCED_XID") -``` - -Let's see how the XID looks after adding these basic identity -assertions: - -```sh -envelope format "$ENHANCED_XID" - -XID(d5aad53e) [ - 'isA': "Persona" - "nickname": "BRadvoc8" - 'key': PublicKeys(6d165468) [ - 'allow': 'All' - ELIDED - ] -] -``` - -Notice how `isA` appears with single quotes to indicate it's a known -value predicate, while "nickname" is in double quotes because it's a -string predicate. Known values are distinguished with single quotes, -while string predicates use double quotes in the formatted output. - -### Adding a Service - -Next, she wants to add detailed information about her GitHub -account. She'll create this as a nested structure to demonstrate the -hierarchical capabilities of Gordian Envelopes. - -> **Technical Note**: Using proper data types (instead of just strings) makes XIDs more powerful because: -> - **Date types** enable chronological operations and validation -> - **URI types** allow systems to recognize and validate web resources -> - **Structured data** enables machine readability and complex queries - -First, she creates an account information envelope with timestamps -using the proper date type and evidence using the URI type. Note how -she uses the XID_NAME variable consistently: - - -```sh -GITHUB_ACCOUNT=$(envelope subject type string "$XID_NAME") -GITHUB_ACCOUNT=$(envelope assertion add pred-obj string "created_at" date "2025-05-10T00:55:11Z" "$GITHUB_ACCOUNT") -GITHUB_ACCOUNT=$(envelope assertion add pred-obj string "updated_at" date "2025-05-10T00:55:28Z" "$GITHUB_ACCOUNT") -GITHUB_ACCOUNT=$(envelope assertion add pred-obj string "evidence" uri "https://api.github.com/users/$XID_NAME" "$GITHUB_ACCOUNT") -``` - -``` -"BRadvoc8" [ - "created_at": 2025-05-10T00:55:11Z - "evidence": URI(https://api.github.com/users/BRadvoc8) - "updated_at": 2025-05-10T00:55:28Z -] -``` - -Notice how the dates appear without quotes, showing they're not simple -strings, and that the evidence URL has the URI() wrapper, indicating -its special type. - -Now, Amira creates a service envelope that contains this account -information. She also adds a type classification for the service using -the `isA` known value. This nesting (service → account) and typing -creates a logical hierarchy that helps organize related information: - -```sh -GITHUB_SERVICE=$(envelope subject type string "GitHub") -# Add the type of service (using known isA predicate) -GITHUB_SERVICE=$(envelope assertion add pred-obj known isA string "SourceCodeRepository" "$GITHUB_SERVICE") -GITHUB_SERVICE=$(envelope assertion add pred-obj string "account" envelope "$GITHUB_ACCOUNT" "$GITHUB_SERVICE") -``` - -The result: - -``` -"GitHub" [ - 'isA': "SourceCodeRepository" - "account": "BRadvoc8" [ - "created_at": 2025-05-10T00:55:11Z - "evidence": URI(https://api.github.com/users/BRadvoc8) - "updated_at": 2025-05-10T00:55:28Z - ] -] -``` - -Finally, she adds this service information to her XID, demonstrating -how XIDs can contain complex, nested data structures while maintaining -cryptographic integrity: - -```sh -ENHANCED_XID=$(envelope assertion add pred-obj string "service" envelope "$GITHUB_SERVICE" "$ENHANCED_XID") -``` - -She views the result: - -``` -envelope format "$ENHANCED_XID" - -XID(d5aad53e) [ - 'isA': "Persona" - "nickname": "BRadvoc8" - "service": "GitHub" [ - 'isA': "SourceCodeRepository" - "account": "BRadvoc8" [ - "created_at": 2025-05-10T00:55:11Z - "evidence": URI(https://api.github.com/users/BRadvoc8) - "updated_at": 2025-05-10T00:55:28Z - ] - ] - 'key': PublicKeys(6d165468) [ - 'allow': 'All' - ELIDED - ] -] -``` - -### Adding Resolution Info - -To finish her XID, Amira will add resolution information to provide -ways for others to find this XID. This is crucial for discoverability -in decentralized systems where no central registry exists. - -She creates URI objects for both a GitHub repository and a DID -(Decentralized Identifier) reference. The following commands create -properly typed URI objects using the XID_NAME variable, which is -important for systems that need to properly interpret and validate -these URLs: - -```sh -GITHUB_REPO_URI=$(envelope subject type uri "https://github.com/$XID_NAME/$XID_NAME/$XID_NAME-public.envelope") -DID_URI=$(envelope subject type uri "did:repo:1ab31db40e48145c14f19bc735add0d279cdc62d/blob/main/$XID_NAME-public.envelope") -``` - -Each will be a properly typed URI envelope: - -``` -URI(https://github.com/BRadvoc8/BRadvoc8/BRadvoc8-public.envelope) -URI(did:repo:1ab31db40e48145c14f19bc735add0d279cdc62d/blob/main/BRadvoc8-public.envelope) -``` - -She adds these URIs to her XID as "resolveVia" assertions. By -providing multiple resolution methods, Amira ensures her XID can be -found through different channels, increasing resilience: - -```sh -ENHANCED_XID=$(envelope assertion add pred-obj string "resolveVia" envelope "$GITHUB_REPO_URI" "$ENHANCED_XID") -ENHANCED_XID=$(envelope assertion add pred-obj string "resolveVia" envelope "$DID_URI" "$ENHANCED_XID") -``` - -### Signing the XID - -Having completed the construction of her enhanced XID, Amira is now -ready to sign it. This will verify that she actually holds the private -key linked to the listed public key and also that she authenticates -the XID. - -Before signing, Amira wraps the XID using the specific "wrapped" -type. This critical step ensures the signature applies to the entire -envelope with all its assertions, not just the subject. Without proper -wrapping, the signature would not apply to the rest of the XID structure. - -```sh -WRAPPED_XID=$(envelope subject type wrapped "$ENHANCED_XID") -``` - -Finally, Amira signs the wrapped XID with her private key and displays -the result. This signature creates a cryptographic guarantee that this -XID and all its assertions were created by the holder of the private -key: - -```sh -SIGNED_ENHANCED_XID=$(envelope sign -s "$XID_PRVKEY_BASE" "$WRAPPED_XID") -``` - -We can now view the signed, enhanced XID: -```sh -envelope format "$SIGNED_ENHANCED_XID" -``` - -It should look something like: - - -``` -{ - XID(d5aad53e) [ - 'isA': "Persona" - "nickname": "BRadvoc8" - "resolveVia": URI(did:repo:1ab31db40e48145c14f19bc735add0d279cdc62d/blob/main/BRadvoc8-public.envelope) - "resolveVia": URI(https://github.com/BRadvoc8/BRadvoc8/BRadvoc8-public.envelope) - "service": "GitHub" [ - 'isA': "SourceCodeRepository" - "account": "BRadvoc8" [ - "created_at": 2025-05-10T00:55:11Z - "evidence": URI(https://api.github.com/users/BRadvoc8) - "updated_at": 2025-05-10T00:55:28Z - ] - ] - 'key': PublicKeys(6d165468) [ - 'allow': 'All' - ELIDED - ] - ] -} [ - 'signed': Signature -] -``` - -Note that the structure looks a little different since we wrapped the -original envelope. There are now curly braces `{}` surrounding the -XID (indicating it's wrapped) and square brackets `[]` surrounding the -'signed' assertion, showing that it applies to the wrapped element -above. - -This enhanced, signed XID provides several important elements: - -1. **Type Declaration** - The `isA: "Persona"` assertion clearly identifies this as a persona XID. -2. **Nickname** - The `nickname: "BRadvoc8"` provides a human-readable identifier. -3. **Multiple Resolution Methods** - Multiple `resolveVia` assertions provide different ways to find the XID. -4. **Service Information** - The `service` section contains detailed, structured information about BRadvoc8's GitHub account. -5. **Nested Structure** - The hierarchical structure allows for organizing related information (service → account → details). -6. **Proper Data Types** - Dates use the `date` type and URLs use the `uri` type for better semantic meaning. -7. **Proper Wrapping and Signing** - The XID is properly wrapped using the `wrapped` type before signing, creating a signature that covers the entire XID structure with all its assertions. - -Here's a visual representation of the XID's hierarchical structure: - -```mermaid -graph TD - A["{Signed Wrapper}"] --> B["XID(d5aad53e)"] - B --> C["'isA': Persona (known value)"] - B --> D[""nickname": BRadvoc8 (string predicate)"] - B --> E[""service": GitHub"] - B --> F[""resolveVia": GitHub URI"] - B --> G[""resolveVia": DID URI"] - B --> H["'key': PublicKeys"] - E --> I["'isA': SourceCodeRepository (known)"] - E --> J[""account": BRadvoc8"] - J --> K[""created_at": 2025-05-10"] - J --> L[""updated_at": 2025-05-10"] - J --> M[""evidence": URI(https://api.github.com/users/BRadvoc8)"] - H --> N["'allow': All"] - H --> O["ELIDED"] - A --> P["'signed': Signature"] -``` - -To verify the authenticity of the signed XID, others would need to -verify its signature. This requires a public key, which can be derived -from the private key base: - -```sh -PUBLIC_KEYS=$(envelope generate pubkeys "$XID_PRVKEY_BASE") -``` - -These public keys can be shared with others who need to verify attestations signed by this XID: - -``` -ur:crypto-pubkeys/hdcxtipscnhsondlbthsrfwzkefxttwttdgmkbvdtnlffsmsnsadwssyalrhlsrliaddlbehfcaflkfwelftbztk -``` - -> Note: The public keys output is in Uniform Resources (UR) format, -which provides a compact and reliable way to encode binary data using -text. - - -Now anyone with the pubic keys can verify the signature on the signed -XID. This verification process confirms that the XID was indeed signed -by the holder of the corresponding private key and hasn't been altered -since signing: - -```sh -if envelope verify -v "$PUBLIC_KEYS" "$SIGNED_ENHANCED_XID"; then - echo "✅ Signature verified! The enhanced XID is authentically from the XID holder." -else - echo "❌ Signature verification failed." -fi -``` - -The verification confirms that the signature is valid: - -``` -ur:envelope/lftpsplttpsotanshdhdcxwesssfcmmwzmhlmesguyeorhdyeepkstlgeeetaoheeysbmsjpurbdaeaohfgheooytpsoim... -✅ Signature verified! The enhanced XID is authentically from the XID holder. -``` - -### Enhanced XID Summary - -This signed, enhanced XID provides a complete digital representation -of Amira's persona that can be shared and verified by others, while -still protecting her private key material through elision. - -> **XID Evolution Summary**: -> -> | **Step 1: Private XID** | **Step 2: Basic Public XID** | **Step 3: Enhanced XID** | -> |-------------------------|------------------------------|--------------------------| -> | Contains private keys | Private keys elided | Private keys elided | -> | Not safe to share | Safe to share | Safe to share | -> | Just cryptographic info | Just cryptographic info | Rich structured identity | -> | No specific type | No specific type | Typed as "Persona" | -> | No human-readable ID | No human-readable ID | BRadvoc8 nickname | -> | No service information | No service information | GitHub account details | -> | No resolution methods | No resolution methods | Multiple resolution URIs | -> | Not signed | Not signed | Cryptographically signed | -> | Flat structure | Flat structure | Hierarchical organization| -> | For key operations only | For basic identification | Full machine-readable ID | - -## Understanding What Happened - -1. **Privacy-Preserving Identity**: Amira created a pseudonymous XID -that allows her to contribute without revealing her real identity. - -2. **Selective Disclosure**: She learned how to control exactly what -information she shares through elision, keeping sensitive information -private while sharing what's needed. - -3. **Cryptographic Integrity**: She verified that even when certain -parts of the XID are removed, its cryptographic integrity remains -intact, providing non-repudiation and verifiability. (Elision could -have even occurred after Amira signed, not just before!) - -4. **Verifiable Attestations**: She created and signed an attestation -that cryptographically links her XID to her GitHub account, allowing -her to build a verifiable online presence. - -5. **Secure File Organization**: She established clear naming -conventions for different security levels of her XID files, ensuring -proper protection of sensitive material. - -6. **Self-Sovereign Identity**: BRadvoc8's identity is fully under -Amira's control. No central authority issued this identifier, and she -maintains complete ownership of both the keys and the resulting XID -document. - - **Why this matters**: Unlike traditional identities (email accounts, -social profiles) that can be suspended or controlled by -providers, BRadvoc8's XID remains under Amira's control -regardless of any third party. - -7. **Pseudonymity vs. Anonymity**: This XID implements -**pseudonymity** rather than anonymity. The identity "BRadvoc8" can -build reputation and trust over time through verifiable contributions, -while still protecting Amira's real-world identity. - - **Real-World Analogy**: This is similar to how authors might use pen -names (like Mark Twain for Samuel Clemens). They can build -reputation under their pseudonym while keeping their personal -identity separate. - -## Next Steps - -In the next tutorial, we'll explore the structure of Amira's XID in -detail and understand how XIDs work under the hood with Gordian -Envelopes. - -## Example Script - -This tutorial has an accompanying script: - -**`../examples/01-basix-xid/create_basic_xid.sh`**: Implements all the -steps shown in this tutorial to create a pseudonymous XID. The -script automates the creation of private and public XIDs, including: - -1. Creating the private XID with full key material -2. Creating a basic public XID with private keys elided -3. Creating an enhanced public XID with persona details and cryptographic signature - -Running this script will produce the same outputs shown in this -tutorial and create all the necessary files in a timestamped output -directory (e.g., `xid-20250510123456`) for further experimentation. - -When you run the script, you'll see files created with the following structure: - -``` -xid-20250510123456/ -├── BRadvoc8-xid-basic-public.format # Human-readable basic public XID -├── BRadvoc8-xid-basic-public.envelope # Serialized basic public XID -├── BRadvoc8-xid-enhanced-public.envelope # Serialized enhanced XID -├── BRadvoc8-xid-enhanced-public.format # Human-readable enhanced XID -├── BRadvoc8-xid-private.crypto-prvkey-base # Private key material (SECRET!) -├── BRadvoc8-xid-private.format # Human-readable private XID -├── BRadvoc8-xid-private.xid # Serialized private XID -└── BRadvoc8-xid-public.crypto-pubkeys # Public keys for verification -``` - -## Key Terminology - -> **XID Terminology Reference**: -> -> - **XID** - eXtensible IDentifier; a digital container that includes cryptographic key material and can be extended with assertions. -> -> - **Assertion** - A claim made within an XID, consisting of a predicate (attribute name) and an object (attribute value). -> -> - **Elision** - The process of selectively removing private information from an XID while preserving its cryptographic integrity. -> -> - **Known Value** - A predicate with a standardized meaning in the Gordian Envelope system (e.g., `isA`, `dereferenceVia`). These appear with single quotes ('isA') in formatted output, distinguishing them from strings. The examples here are all known-value predicates, or "known predicates." -> -> - **Persona** - A pseudonymous identity represented by an XID, which can build reputation while protecting real-world identity. -> -> - **Resolution** - The process of finding and retrieving an XID through various methods, as specified in resolveVia assertions. - -> - **Signature** - A cryptographic proof that an XID was created by the holder of a specific private key. -> -> - **String Predicate** - A custom predicate represented as a string (e.g., "nickname", "service"). These appear with double quotes in formatted output. -> -> - **Wrapped Type** - A specific envelope type (`wrapped`) that correctly prepares an XID for signing. -> -> - **Wrapping** - Enclosing an entire XID structure in an envelope before signing, ensuring the signature covers all assertions. - -## Exercises - -1. Create your own XID with a pseudonym and additional assertions of your choice. - -2. Create and sign different types of attestations with your XID private key. - -3. Experiment with eliding different parts of your XID for different audiences. - -4. Try creating a more complex XID with nested assertions and verify that elision still preserves integrity. - -5. Create a minimal XID with just a name and public key, then gradually add more information as you would in a real trust-building scenario. \ No newline at end of file diff --git a/tutorials/02-understanding-xid-structure.md b/tutorials/02-understanding-xid-structure.md deleted file mode 100644 index a796101..0000000 --- a/tutorials/02-understanding-xid-structure.md +++ /dev/null @@ -1,607 +0,0 @@ -# Understanding XID Structure (Under the Hood) - -This tutorial explores how Amira's pseudonymous "BWHacker" XID is structured at a technical level, revealing how Gordian Envelopes provide the cryptographic foundation for XIDs. You'll learn how the data structures work under the hood to enable stable identity, verifiable claims, and selective disclosure. - -**Time to complete: 30-40 minutes** - -> **Related Concepts**: Before or after completing this tutorial, you may want to read about [Gordian Envelope Basics](../concepts/gordian-envelope-basics.md), [Data Minimization Principles](../concepts/data-minimization-principles.md), and [Elision Cryptography](../concepts/elision-cryptography.md) to understand the theoretical foundations behind XID structure and elision. - -## Prerequisites - -- Completed the "Creating Your First XID" tutorial -- The envelope CLI tool installed -- Basic understanding of public/private key cryptography -- Basic understanding of hash functions and cryptographic signatures -- BWHacker's XID from the previous tutorial (or you can create a new one) - -## What You'll Learn - -- How XIDs are structured as Gordian Envelopes under the hood -- How the CBOR encoding and cryptographic operations work -- The subject-assertion-object model that forms the core of XIDs -- How XIDs derive their stable identifiers cryptographically -- How elision preserves cryptographic integrity while removing information -- How verification chains are built between XIDs and external systems -- How signatures work to validate assertions - -## 1. Examining the XID's Technical Structure - -Let's begin by examining the XID created in the previous tutorial, but this time looking at its technical structure: - -👉 -```sh -XID_DOC=$(cat output/bwhacker-xid.envelope) -XID=$(envelope xid id "$XID_DOC") -echo "BWHacker's XID identifier: $XID" -``` - -🔍 -```console -BWHacker's XID identifier: 7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3 -``` - -Now, let's look at several different formats of this XID to understand how it works at a technical level: - -Let's view the CBOR diagnostic format (human-readable CBOR): - -👉 -```sh -echo "CBOR Diagnostic Format:" -envelope format --type diag "$XID_DOC" -``` - -🔍 -```console -CBOR Diagnostic Format: -{ - "BWHacker": { - "name": "BWHacker", - "publicKeys": 37([h'8854c2d39daafb1eee9c8bab32d41e97c775c286bfcabc4b7c3ff77f1eac268d', "ur:crypto-pubkeys/hdcxlkadjnghfejt..."]), - "gitHubUsername": "BWHacker", - "gitHubProfileURL": "https://github.com/BWHacker", - "sshKey": "ssh-ed25519 AAAAC3NzaC...", - "sshKeyFingerprint": "SHA256:dFbxBGrqMQNJKpZccInX7l/QE1xH/jNzDvUo/jICSHE", - "sshKeyVerificationURL": "https://api.github.com/users/BWHacker/ssh_signing_keys", - "domain": "Distributed Systems & Security", - "experienceLevel": "8 years professional practice" - } -} -``` - -Now let's view the CBOR binary encoding (lower-level representation). This shows the actual binary data of the envelope: - -👉 -```sh -echo "CBOR Binary Encoding (first 100 bytes):" -envelope format --type cbor "$XID_DOC" | head -c 100 -echo "..." -``` - -🔍 -```console -CBOR Binary Encoding (first 100 bytes): -d8c882d8c9d99c585820e5fca07970ff3f71b34bce2ef896bc809207638327089338a976a02508a0a083a10883d8c9d99c51... -``` - -Let's view the CBOR encoding in a more structured way: - -👉 -```sh -echo "CBOR Tags and Structure:" -envelope format --type cbor "$XID_DOC" -``` - -🔍 -```console -CBOR Tags and Structure: -a1 -- map(1) - 68 -- text(8) - 4257486163686572 -- "BWHacker" - a8 -- map(8) - 64 -- text(4) - 6e616d65 -- "name" - 68 -- text(8) - 4257486163686572 -- "BWHacker" - 69 -- text(9) - 7075626c69634b657973 -- "publicKeys" - d82525 -- tag(37) - 8854c2d39daafb1eee9c8bab32d41e97c775c286bfcabc4b7c3ff77f1eac268d -- bytes(32) - 78ed -- text(237) - ... - ... - -``` - -The CBOR format shows the hierarchical structure of tags, maps, text fields, and binary data that make up an XID. This is the actual data format that gets exchanged and verified. - -## 2. Understanding the Subject-Assertion-Object Model - -Gordian Envelopes, the technology underlying XIDs, use a subject-assertion-object model: - -### Basic Structure Breakdown: - -1. **Subject**: 'BWHacker' - The entity this envelope is about -2. **Assertions**: Each key-value pair in the map - - **Predicate**: The key (like 'name', 'sshKey') - - **Object**: The value (could be text, binary data, or nested structures) - -Let's examine this structure in the XID: - -Let's list all predicates (the keys of the assertions) in the XID. These predicates are the properties that describe BWHacker, like name, public keys, GitHub username, etc.: - -👉 -```sh -echo "Predicates in the XID:" -envelope format --type diag "$XID_DOC" | grep -o '"[^"]*":' | sort | uniq -``` - -🔍 -```console -Predicates in the XID: -"BWHacker": -"domain": -"experienceLevel": -"gitHubProfileURL": -"gitHubUsername": -"name": -"publicKeys": -"sshKey": -"sshKeyFingerprint": -"sshKeyVerificationURL": -``` - -## 3. How XIDs Derive Their Stable Identifiers - -XIDs derive their stable identifiers through a cryptographic process involving the initial public key. Let's understand this process: - -Let's extract just the public key from the XID and the XID identifier: - -👉 -```sh -PUBLIC_KEY=$(envelope format --type diag "$XID_DOC" | grep -o '"publicKeys": [^,]*' | sed 's/"publicKeys": //') -echo "Public key (in diagnostic format): $PUBLIC_KEY" - -XID=$(envelope xid id "$XID_DOC") -echo "XID identifier: $XID" -``` - -🔍 -```console -Public key (in diagnostic format): 37([h'8854c2d39daafb1eee9c8bab32d41e97c775c286bfcabc4b7c3ff77f1eac268d', "ur:crypto-pubkeys/hdcxlkadjnghfejtmyyloeadmyfqzswdaeayfnmddpjygtmyaeaelytsqdisaeaeaeae"]) -XID identifier: 7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3 -``` - -**Note:** The XID identifier is a SHA-256 hash derived from specific parts of the initial public key. - -This derivation process is what allows XIDs to maintain stability: the identifier is cryptographically derived from the initial key, creating a stable reference that persists even as the XID evolves. - -## 4. Adding a Device Key While Maintaining Stable Identity - -Now that we understand how XID identifiers work, let's see how adding a key preserves the stable identity: - -Now let's generate a key for a second device (tablet), add it to BWHacker's XID, and compare the identifiers to see if they remain the same: - -👉 -```sh -TABLET_PRIVATE_KEYS=$(envelope generate prvkeys) -echo "$TABLET_PRIVATE_KEYS" > output/tablet-key.private -TABLET_PUBLIC_KEYS=$(envelope generate pubkeys "$TABLET_PRIVATE_KEYS") -echo "$TABLET_PUBLIC_KEYS" > output/tablet-key.public - -UPDATED_XID=$(envelope xid key add --name "Tablet Key" "$TABLET_PUBLIC_KEYS" "$XID_DOC") -echo "$UPDATED_XID" > output/bwhacker-xid-with-tablet.envelope - -ORIGINAL_XID=$(envelope xid id "$XID_DOC") -UPDATED_XID_ID=$(envelope xid id "$UPDATED_XID") -echo "Original XID: $ORIGINAL_XID" -echo "Updated XID: $UPDATED_XID_ID" -``` - -🔍 -```console -Original XID: 7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3 -Updated XID: 7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3 -``` - -The identifier remains the same because it's derived from the initial public key, not subsequent keys. Let's look at how the new key is structured in the CBOR format: - -Let's examine the key structure in CBOR diagnostic format. When we look at the XID structure, we'll see the newly added tablet key represented as an array with three components: the raw binary key material, a human-readable name, and the permissions for this key: - -👉 -```sh -echo "Updated XID with tablet key structure:" -envelope format --type diag "$UPDATED_XID" | grep -A 3 "key" -``` - -🔍 -```console -"key": [ - h'8c8b76a4f9a97a92bffa8352d6a5e852d8facf38eb2adf3eba38e7f9a5f5e5a1', - "Tablet Key", - "sign" -], -``` - -This shows the key assertion is an array with: -1. The raw binary key material -2. A human-readable name ("Tablet Key") -3. Permissions for this key ("sign" - meaning it can sign content) - -## 5. The Cryptographic Verification Chain - -Let's examine how the SSH key creates a verification chain between the XID and GitHub: - -### Verification Chain Elements: - -1. **The XID contains an SSH key fingerprint:** - -The XID contains an SSH key fingerprint that looks like "SHA256:dFbxBGrqMQNJKpZccInX7l/QE1xH/jNzDvUo/jICSHE". This fingerprint uniquely identifies the SSH key. - -👉 -```sh -envelope format --type diag "$XID_DOC" | grep "sshKeyFingerprint" -``` - -2. **This fingerprint can be verified against GitHub's API:** - -The XID also contains a URL to verify the SSH key on GitHub, typically something like "https://api.github.com/users/BWHacker/ssh_signing_keys". This URL allows anyone to check that the SSH key belongs to the GitHub user. - -👉 -```sh -envelope format --type diag "$XID_DOC" | grep "sshKeyVerificationURL" -``` - -3. **Git commits signed with this SSH key can be verified as coming from BWHacker** - -4. **The XID can sign assertions that reference this SSH key, completing the chain** - -🔍 -```console -sshKeyFingerprint: SHA256:dFbxBGrqMQNJKpZccInX7l/QE1xH/jNzDvUo/jICSHE -``` - -🔍 -```console -sshKeyVerificationURL: https://api.github.com/users/BWHacker/ssh_signing_keys -``` - -This verification chain allows others to cryptographically verify that GitHub activity and XID attestations come from the same entity without revealing Amira's real identity. - -## 6. Understanding Signatures and Verification - -To understand how signatures work, let's create and examine a signed statement: - -First, it's important to understand a key property of Gordian Envelope signatures: **a signature only applies to the subject of an envelope, not to its assertions**. This is because the signature is itself an assertion about the subject. To sign an entire envelope with all its assertions, we need to wrap it first, making the original envelope the subject of a new envelope. - -Let's create a simple statement about a technical capability: - -👉 -```sh -STATEMENT=$(envelope subject type string "Technical Assertion") -STATEMENT=$(envelope assertion add pred-obj string "capability" string "Zero-knowledge proof systems" "$STATEMENT") -``` - -Next, let's wrap and sign the statement with the XID's private key: - -👉 -```sh -PRIVATE_KEYS=$(cat output/bwhacker-key.private) - -WRAPPED_STATEMENT=$(envelope subject type wrapped "$STATEMENT") - -SIGNED_STATEMENT=$(envelope sign -s "$PRIVATE_KEYS" "$WRAPPED_STATEMENT") -``` - -Now we'll save the signed statement and examine its structure. The wrapping step creates a new envelope with the original statement as its subject, and the signature applies to this wrapped structure: - -👉 -```sh -echo "$SIGNED_STATEMENT" > output/signed-tech-statement.envelope -echo "Signed statement structure:" -envelope format --type diag "$SIGNED_STATEMENT" -``` - -🔍 -```console -Signed statement structure: -{ - "WRAPPED": { - "subject": { - "Technical Assertion": { - "capability": "Zero-knowledge proof systems" - } - }, - "verifiedBy": h'ac6167d7732c11485856ef80597687be6a5fc9e06a3f77dfa3c8e2eb87ca148f6c2c70a4ef111c55db09c3cf81bf23b16b9b0edc2bf7ec28e6903c0f74d5b80d' - } -} -``` - -The signature is stored in the "verifiedBy" predicate as a binary value. Let's verify this signature: - -Now let's verify the signature using the public key: - -👉 -```sh -PUBLIC_KEYS=$(cat output/bwhacker-key.public) -if envelope verify -v "$PUBLIC_KEYS" "$SIGNED_STATEMENT"; then - echo "✅ Signature verified successfully" - else - echo "❌ Signature verification failed" - fi -``` - -🔍 -```console -✅ Signature verified successfully -``` - -This verification confirms: -1. The statement was signed by the holder of the private key corresponding to BWHacker's XID -2. The statement hasn't been modified since it was signed - -## 7. Elision: How Data Minimization Works Cryptographically - -A powerful feature of XIDs is elision - removing information while maintaining cryptographic verifiability. Let's see how it works: - -First, let's add some more information to make elision more interesting: - -👉 -```sh -ENHANCED_XID=$(envelope assertion add pred-obj string "potentialBias" string "Particular focus on solutions for privacy-preserving systems" "$UPDATED_XID") -ENHANCED_XID=$(envelope assertion add pred-obj string "methodologicalApproach" string "Security-first, user-focused development processes" "$ENHANCED_XID") -echo "$ENHANCED_XID" > output/enhanced-xid.envelope -``` - -Now we'll create an elided version by removing the potential bias information. Elision is a cryptographic process that allows removing specific fields while maintaining the integrity of the document: - -👉 -```sh -echo "Available digests:" -envelope extract digest "$ENHANCED_XID" - -BIAS_DIGEST=$(envelope extract digest "$ENHANCED_XID" | grep -i "potential" | head -1 | awk '{print $2}') - -if [ -n "$BIAS_DIGEST" ]; then - ELIDED_XID=$(envelope elide removing "$BIAS_DIGEST" "$ENHANCED_XID") - echo "Successfully elided potentialBias assertion" -else - echo "Could not find potentialBias digest to elide" - ELIDED_XID="$ENHANCED_XID" -fi - -echo "$ELIDED_XID" > output/elided-xid.envelope -``` - -Let's compare the sizes of the original and elided versions: - -👉 -```sh -ORIGINAL_SIZE=$(echo "$ENHANCED_XID" | wc -c) -ELIDED_SIZE=$(echo "$ELIDED_XID" | wc -c) -echo "Original XID size: $ORIGINAL_SIZE bytes" -echo "Elided XID size: $ELIDED_SIZE bytes" -``` - -🔍 -```console -Original XID size: 1237 bytes -Elided XID size: 1125 bytes -``` - -Now let's examine how elision affects the cryptographic properties: - -Now let's check if the XID identifiers remain the same after elision. One of the key properties of elision is that it preserves the cryptographic derivation path to the XID identifier, maintaining stability: - -👉 -```sh -ORIGINAL_ID=$(envelope xid id "$ENHANCED_XID") -ELIDED_ID=$(envelope xid id "$ELIDED_XID") -echo "Original XID identifier: $ORIGINAL_ID" -echo "Elided XID identifier: $ELIDED_ID" -``` - -🔍 -```console -Original XID identifier: 7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3 -Elided XID identifier: 7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3 -``` - -The identifiers remain the same! This is because elision preserves the cryptographic derivation path from the initial key to the XID identifier. - -Now let's see what happened at the CBOR level. In elided documents, you'll see special "elided" fields containing cryptographic hashes. These serve as proof that data was removed, while allowing verification that the envelope hasn't been tampered with: - -👉 -```sh -envelope format --type diag "$ELIDED_XID" | grep -A 1 elided -``` - -🔍 -```console - "elided": [ - h'8d7f117fa8511c9c8ef2092176596cca48a797c69e0a0e12a244faea715a8f82' - ], -``` - -### How Elision Works - -Elision isn't simply deleting data - it's a cryptographic operation that maintains integrity while enabling data minimization. When we elide the "potentialBias" assertion: - -1. The actual content is removed -2. It's replaced with a cryptographic hash: `h'8d7f117fa8511c9c8ef2092176596cca48a797c69e0a0e12a244faea715a8f82'` -3. This hash acts as a secure placeholder that: - - Cannot be reversed to reveal the original content - - Preserves the cryptographic structure of the document - - Maintains the validity of signatures - -Let's demonstrate how elision preserves signature validity. One of the most powerful properties of elision is that signatures made before elision remain valid afterward. This enables selective disclosure while maintaining verification: - -👉 -```sh -PRIVATE_KEYS=$(cat output/bwhacker-key.private) - -WRAPPED_ENHANCED_XID=$(envelope subject type wrapped "$ENHANCED_XID") - -SIGNED_ENHANCED_XID=$(envelope sign -s "$PRIVATE_KEYS" "$WRAPPED_ENHANCED_XID") - -echo "Available digests in signed document:" -envelope extract digest "$SIGNED_ENHANCED_XID" - -BIAS_DIGEST=$(envelope extract digest "$SIGNED_ENHANCED_XID" | grep -i "potential" | head -1 | awk '{print $2}') - -if [ -n "$BIAS_DIGEST" ]; then - SIGNED_ELIDED_XID=$(envelope elide removing "$BIAS_DIGEST" "$SIGNED_ENHANCED_XID") - echo "Successfully elided potentialBias assertion from signed document" -else - echo "Could not find potentialBias digest to elide from signed document" - SIGNED_ELIDED_XID="$SIGNED_ENHANCED_XID" -fi - -PUBLIC_KEYS=$(cat output/bwhacker-key.public) -if envelope verify -v "$PUBLIC_KEYS" "$SIGNED_ELIDED_XID"; then - echo "✅ Signature remains valid after elision" -else - echo "❌ Signature validation failed after elision" -fi -``` - -🔍 -```console -✅ Signature remains valid after elision -``` - -This demonstrates one of the most powerful properties of elision: **signatures made before elision remain valid after elision**. For a deeper understanding of the cryptographic mechanisms that make this possible, see the [Elision Cryptography](../concepts/elision-cryptography.md) concept document. - -### Practical Applications of Elision - -This data minimization capability enables important use cases: - -1. **Contextual Sharing**: BWHacker can share different subsets of her XID with different parties -2. **Progressive Trust**: She can reveal more information as trust develops without breaking verification chains -3. **Privacy Control**: She maintains control over what personal data is revealed in different contexts -4. **Verified Redactions**: She can sign a document and later redact sensitive parts while keeping the signature valid - -The cryptographic hashes in elided fields serve as proof that content was intentionally removed while preserving the document's integrity and signature validity. - -## 8. Creating an Advanced Verification Chain - -Let's demonstrate an end-to-end verification chain that links GitHub commits to XID-signed attestations. - -First, let's create a contribution attestation with GitHub references: - -👉 -```sh -CONTRIBUTION=$(envelope subject type string "Code Contribution") -CONTRIBUTION=$(envelope assertion add pred-obj string "repository" string "github.com/blockchain-commons/bc-envelope" "$CONTRIBUTION") -CONTRIBUTION=$(envelope assertion add pred-obj string "commit" string "a1b2c3d4e5f6" "$CONTRIBUTION") -CONTRIBUTION=$(envelope assertion add pred-obj string "description" string "Fixed performance issue in CBOR encoding" "$CONTRIBUTION") -``` - -Next, let's add a reference to the SSH key fingerprint to establish the verification chain: - -👉 -```sh -CONTRIBUTION=$(envelope assertion add pred-obj string "sshKeyFingerprint" string "SHA256:dFbxBGrqMQNJKpZccInX7l/QE1xH/jNzDvUo/jICSHE" "$CONTRIBUTION") -CONTRIBUTION=$(envelope assertion add pred-obj string "verificationMethod" string "Compare SSH key fingerprint with the one in the XID document" "$CONTRIBUTION") -``` - -Finally, let's wrap and sign the contribution and examine the result: - -👉 -```sh -WRAPPED_CONTRIBUTION=$(envelope subject type wrapped "$CONTRIBUTION") - -SIGNED_CONTRIBUTION=$(envelope sign -s "$PRIVATE_KEYS" "$WRAPPED_CONTRIBUTION") -echo "$SIGNED_CONTRIBUTION" > output/verified-contribution.envelope - -echo "Signed contribution with verification chain:" -envelope format --type tree "$SIGNED_CONTRIBUTION" -``` - -🔍 -```console -Signed contribution with verification chain: -WRAPPED [ - subject: "Code Contribution" [ - "repository": "github.com/blockchain-commons/bc-envelope" - "commit": "a1b2c3d4e5f6" - "description": "Fixed performance issue in CBOR encoding" - "sshKeyFingerprint": "SHA256:dFbxBGrqMQNJKpZccInX7l/QE1xH/jNzDvUo/jICSHE" - "verificationMethod": "Compare SSH key fingerprint with the one in the XID document" - ] - SIGNATURE -] -``` - -This creates a complete verification chain: - -1. The contribution is signed by the XID's private key -2. The signature can be verified with the XID's public key -3. The contribution references the SSH key fingerprint in the XID -4. GitHub commits signed with this SSH key can be verified via GitHub's API -5. The entire chain can be verified without revealing Amira's identity - -## Technical Concepts Summary - -After exploring XIDs at a technical level, we now understand: - -1. **CBOR Encoding**: XIDs use CBOR (Concise Binary Object Representation) for compact, secure encoding. - -2. **Subject-Assertion-Object Model**: XIDs are built on a semantic triple model where: - - The subject is the entity being described - - Assertions are statements about the subject - - Each assertion has a predicate (property) and object (value) - -3. **Cryptographic Derivation**: XID identifiers are derived from the initial public key, creating stability. - -4. **Key Management**: Additional keys can be added without changing the XID identifier. - -5. **Cryptographic Signatures**: Digital signatures prove that statements come from the XID holder. - -6. **Elision**: Cryptographic redaction allows removing information while preserving verification. - -7. **Verification Chains**: External systems like GitHub can be linked to XIDs through cryptographic references. - -### Theory to Practice: XID Structure and Privacy-Enhancing Cryptography - -The XID structure exploration you've just performed demonstrates key concepts in modern cryptographic identity systems: - -1. **Cryptographic Containers**: The different formats you viewed (CBOR, diagnostic notation, tree) represent the same underlying data structure - a cryptographic container called a Gordian Envelope. This implements the concept of **structured transparency**, where information is organized to support both human readability and machine verification. - > **Why this matters**: This structured approach allows both machines (using CBOR) and humans (using tree format) to work with the same identity data, enabling both automated verification and human inspection. - -2. **Separable Identity Attributes**: When you added the professional credentials and tablet device to BWHacker's XID, you implemented the concept of **modular identity composition**. Unlike traditional credentials where all attributes are bundled together, XIDs allow selective addition of attributes that can later be independently shared or elided. - > **Historical Context**: Traditional identity documents bundle all attributes together, forcing an all-or-nothing disclosure approach. The modular composition in XIDs builds on decades of privacy research to overcome this limitation. - -3. **Cryptographic Binding with Assertions**: The statement signing process demonstrates **verifiable claims architecture**. When BWHacker signed the technical statement, she created a cryptographic binding between her identity and that statement, allowing others to verify its authenticity without requiring a central authority. - -4. **Data Minimization Through Elision**: The elision operation you performed implements the principle **"share what you must, protect what you can."** Unlike traditional identity systems where credentials are all-or-nothing, elision allows BWHacker to share only the relevant portions of her identity while still maintaining cryptographic verifiability of the remaining portions. - > **ANTI-PATTERN**: Many systems force users to reveal all their personal data when only a fraction is actually needed. For example, showing a driver's license to verify age reveals address, full name, and other unnecessary information. - -5. **Hash-Based Integrity**: Throughout these operations, the cryptographic integrity of the XID is maintained through a Merkle tree-like structure. This allows selective disclosure without compromising the validity of signatures - a key feature that enables contextual information sharing. - -6. **Salt-Based Privacy**: Although not explicitly shown, the elision mechanism uses cryptographic salts to prevent correlation between different presentations of the same document, enhancing privacy protection. - -These structural elements enable XIDs to support sophisticated identity use cases while preserving privacy and user control over data disclosure. - -## Next Steps - -In the next tutorial, we'll explore how Amira can create a comprehensive self-attestation framework with verifiable evidence and proper context, building trust without revealing her identity. - -## Example Script - -This tutorial has an accompanying script in the `examples/02-xid-structure` directory: - -**`explore_structure.sh`**: Implements all the XID structure exploration and elision operations shown in this tutorial. The script demonstrates how to examine XIDs in different formats, manipulate keys, create and verify signatures, and perform elision operations with proper digest handling. - -Running this script will produce the same outputs shown in this tutorial and create all the necessary files in the output directory for further experimentation. - -## Exercises - -1. Experiment with elision to create different views of an XID for different audiences. - -2. Create nested assertions with multiple levels of data to see how they're represented in CBOR. - -3. Sign data with multiple different keys from the same XID and verify the signatures. - -4. Examine the binary structure of different XIDs to understand the encoding patterns. - -5. Create a verification chain that connects an XID to a specific Git commit via SSH key fingerprint. \ No newline at end of file diff --git a/tutorials/03-self-attestation-with-xids.md b/tutorials/03-self-attestation-with-xids.md deleted file mode 100644 index eb18c96..0000000 --- a/tutorials/03-self-attestation-with-xids.md +++ /dev/null @@ -1,778 +0,0 @@ -# Advanced Self-Attestation Frameworks with XIDs - -This tutorial demonstrates how Amira builds comprehensive trust frameworks using structured self-attestations with her "BWHacker" pseudonymous identity. You'll learn how to create advanced attestation models with multiple verification methods and evidence commitments while maintaining cryptographic verifiability. - -**Time to complete: 30-40 minutes** - -> **Related Concepts**: Before or after completing this tutorial, you may want to read about [Fair Witness Approach](../concepts/fair-witness-approach.md), [Attestation and Endorsement Model](../concepts/attestation-endorsement-model.md), and [Public Participation Profiles](../concepts/public-participation-profiles.md) to understand the theoretical foundations behind building trust with attestations while maintaining pseudonymity. - -## Prerequisites - -- Completed the first two XID tutorials -- The envelope CLI tool installed -- BWHacker's XID from the previous tutorials -- Understanding of cryptographic hashing -- Basic understanding of evidence commitments - -## What You'll Learn - -- How to create advanced self-attestation frameworks with multiple attestation types -- How to build hierarchical attestation structures with nested attestations -- How to include cryptographic evidence commitments for verifiable claims -- How to design different disclosure levels for different verification contexts -- How to apply fair witness principles to self-attestations at scale -- How to link multiple attestations to form a coherent trust network - -## Amira's Challenge: Building Comprehensive Trust Frameworks - -Amira has created her "BWHacker" identity, but now faces a critical challenge: how can she establish enough trust to work on meaningful projects while still maintaining her pseudonymity? - -Ben, the manager at the women's services non-profit, has seen her GitHub profile and is cautiously interested in having her develop their safety app. But he rightly hesitates - how can he trust a pseudonymous developer with such sensitive work? He needs more than just a name and public key. - -This tension reflects a fundamental challenge in pseudonymous participation: contributors need to share enough information to build trust while still protecting their privacy. The solution lies in creating a rich, verifiable trust framework using self-attestations. - -Through her pseudonymous identity, Amira needs to: - -1. Create different types of attestations that demonstrate her technical capabilities in API security, distributed systems, and privacy-preserving app development -2. Structure these attestations to support progressive trust building as her relationship with Ben evolves -3. Provide verifiable evidence of her skills (like code samples and problem solutions) without revealing her identity -4. Enable selective disclosure of her experience while maintaining cryptographic verifiability -5. Design a unified framework that helps Ben evaluate her suitability for the women's safety app project - -Without these trust-building attestations, Amira would remain just another anonymous developer - unable to contribute meaningfully to the projects she cares about most. With them, she can build the credibility needed for substantive participation while maintaining the separation between her pseudonymous and legal identities. - -This tutorial focuses on building these advanced attestation structures on top of the basic XID and verification chains established in the previous tutorials. - -## 1. Designing an Advanced Self-Attestation Framework - -Let's start by creating a comprehensive framework for organizing different types of self-attestations: - -First, let's create our output directories: - -👉 -```sh -mkdir -p output -mkdir -p evidence -``` - -Next, we'll load BWHacker's XID from the previous tutorial: - -```sh -if [ -f "output/enhanced-xid.envelope" ]; then - XID_DOC=$(cat output/enhanced-xid.envelope) -elif [ -f "output/amira-xid-with-tablet.envelope" ]; then - XID_DOC=$(cat output/amira-xid-with-tablet.envelope) -elif [ -f "output/amira-xid.envelope" ]; then - XID_DOC=$(cat output/amira-xid.envelope) -elif [ -f "../02-xid-structure/output/enhanced-xid.envelope" ]; then - cp ../02-xid-structure/output/enhanced-xid.envelope output/ - XID_DOC=$(cat output/enhanced-xid.envelope) -elif [ -f "../02-xid-structure/output/amira-xid-with-tablet.envelope" ]; then - cp ../02-xid-structure/output/amira-xid-with-tablet.envelope output/ - XID_DOC=$(cat output/amira-xid-with-tablet.envelope) -else - echo "Could not find BWHacker's XID from previous tutorials" - exit 1 -fi -``` - -Now let's create a comprehensive self-attestation framework: - -👉 -```sh -SELF_ATTESTATION_FRAMEWORK=$(envelope subject type string "Self-AttestationFramework") -SELF_ATTESTATION_FRAMEWORK=$(envelope assertion add pred-obj string "purpose" string "Provide verifiable self-attestations with appropriate context" "$SELF_ATTESTATION_FRAMEWORK") -SELF_ATTESTATION_FRAMEWORK=$(envelope assertion add pred-obj string "approach" string "Fair witness principles with evidence commitments" "$SELF_ATTESTATION_FRAMEWORK") -SELF_ATTESTATION_FRAMEWORK=$(envelope assertion add pred-obj string "verificationLevels" string "Public claims, Evidence commitments, Full disclosure under NDA" "$SELF_ATTESTATION_FRAMEWORK") -``` - -Next, let's add the framework categories for different attestation types: - -👉 -```sh -SELF_ATTESTATION_FRAMEWORK=$(envelope assertion add pred-obj string "attestationCategories" string "Project work, Skills, Education, Open source, Publications" "$SELF_ATTESTATION_FRAMEWORK") -``` - -Now let's define the framework's evidence commitment model: - -👉 -```sh -EVIDENCE_MODEL=$(envelope subject type string "Evidence commitment model") -EVIDENCE_MODEL=$(envelope assertion add pred-obj string "purpose" string "Cryptographically commit to evidence without revealing it" "$EVIDENCE_MODEL") -EVIDENCE_MODEL=$(envelope assertion add pred-obj string "hashAlgorithm" string "SHA-256" "$EVIDENCE_MODEL") -EVIDENCE_MODEL=$(envelope assertion add pred-obj string "timeValidityPolicy" string "Evidence must be dated and include temporal context" "$EVIDENCE_MODEL") -EVIDENCE_MODEL=$(envelope assertion add pred-obj string "verificationMethods" string "Direct hash verification, API verification, GitHub reference" "$EVIDENCE_MODEL") -``` - -Now let's add the evidence model to the framework: - -👉 -```sh -SELF_ATTESTATION_FRAMEWORK=$(envelope assertion add pred-obj string "evidenceModel" envelope "$EVIDENCE_MODEL" "$SELF_ATTESTATION_FRAMEWORK") -``` - -Next, let's add the self-attestation framework to BWHacker's XID: - -👉 -```sh -XID_DOC=$(envelope assertion add pred-obj string "attestationFramework" envelope "$SELF_ATTESTATION_FRAMEWORK" "$XID_DOC") -echo "$XID_DOC" > output/amira-xid-with-framework.envelope - -echo "BWHacker's Self-Attestation Framework:" -envelope format --type tree "$SELF_ATTESTATION_FRAMEWORK" -``` - -🔍 -```console -"Self-AttestationFramework" [ - "purpose": "Provide verifiable self-attestations with appropriate context" - "approach": "Fair witness principles with evidence commitments" - "verificationLevels": "Public claims, Evidence commitments, Full disclosure under NDA" - "attestationCategories": "Project work, Skills, Education, Open source, Publications" - "evidenceModel": "Evidence commitment model" [ - "purpose": "Cryptographically commit to evidence without revealing it" - "hashAlgorithm": "SHA-256" - "timeValidityPolicy": "Evidence must be dated and include temporal context" - "verificationMethods": "Direct hash verification, API verification, GitHub reference" - ] -] -``` - -This framework provides a structured approach to organizing different types of attestations with clear verification levels and evidence requirements. - -## 2. Creating a Hierarchical Project Attestation - -Now let's create a sophisticated project attestation with nested structure and multiple evidence commitments: - -👉 -First, let's create some sample project evidence files: - -```sh -echo "Privacy-preserving location services for secure user tracking without data exposure" > evidence/project_summary.txt -echo "Reduced PII data exposure by 80% while maintaining location accuracy for safety features" > evidence/security_metrics.txt -echo "Implementation uses zero-knowledge proofs, local data processing, and secure push notifications" > evidence/design_approach.txt -echo "Deployed as privacy-focused mobile app with offline capabilities for emergencies" > evidence/deployment_scope.txt -echo "Received security audit approval from independent researchers (Ref: SA-2022-0189)" > evidence/audit_results.txt -``` - -Now we'll create cryptographic hashes of this evidence: - -👉 -```sh -SUMMARY_HASH=$(cat evidence/project_summary.txt | envelope digest sha256) -METRICS_HASH=$(cat evidence/security_metrics.txt | envelope digest sha256) -DESIGN_HASH=$(cat evidence/design_approach.txt | envelope digest sha256) -DEPLOYMENT_HASH=$(cat evidence/deployment_scope.txt | envelope digest sha256) -AUDIT_HASH=$(cat evidence/audit_results.txt | envelope digest sha256) -``` - -Next, let's create the main project attestation: -👉 -```sh -PROJECT=$(envelope subject type string "Privacy-Focused Safety App") -PROJECT=$(envelope assertion add pred-obj string "role" string "Security & Privacy Engineer" "$PROJECT") -PROJECT=$(envelope assertion add pred-obj string "timeframe" string "2022-01 through 2022-06" "$PROJECT") -PROJECT=$(envelope assertion add pred-obj string "client" string "Nonprofit organization (details available after NDA)" "$PROJECT") -``` - -Now let's create a nested technical component for implementation details: -👉 -```sh -TECH_COMPONENT=$(envelope subject type string "Implementation Details") -TECH_COMPONENT=$(envelope assertion add pred-obj string "summaryHash" digest "$SUMMARY_HASH" "$TECH_COMPONENT") -TECH_COMPONENT=$(envelope assertion add pred-obj string "designApproachHash" digest "$DESIGN_HASH" "$TECH_COMPONENT") -TECH_COMPONENT=$(envelope assertion add pred-obj string "primaryLanguages" string "Rust, TypeScript, WebAssembly" "$TECH_COMPONENT") -TECH_COMPONENT=$(envelope assertion add pred-obj string "architecturePattern" string "Microservices with edge computing components" "$TECH_COMPONENT") -``` - -Next, let's create a nested results component for outcome evidence: -👉 -```sh -RESULTS_COMPONENT=$(envelope subject type string "Project Outcomes") -RESULTS_COMPONENT=$(envelope assertion add pred-obj string "metricsHash" digest "$METRICS_HASH" "$RESULTS_COMPONENT") -RESULTS_COMPONENT=$(envelope assertion add pred-obj string "deploymentHash" digest "$DEPLOYMENT_HASH" "$RESULTS_COMPONENT") -RESULTS_COMPONENT=$(envelope assertion add pred-obj string "auditHash" digest "$AUDIT_HASH" "$RESULTS_COMPONENT") -RESULTS_COMPONENT=$(envelope assertion add pred-obj string "successCriteria" string "Performance, security audit, and compliance requirements met" "$RESULTS_COMPONENT") -``` - -Finally, let's add the nested components to the main project: -👉 -```sh -PROJECT=$(envelope assertion add pred-obj string "implementation" envelope "$TECH_COMPONENT" "$PROJECT") -PROJECT=$(envelope assertion add pred-obj string "outcomes" envelope "$RESULTS_COMPONENT" "$PROJECT") -``` - -Now let's add verification methods and context (following fair witnessing principles): - -👉 -```sh -PROJECT=$(envelope assertion add pred-obj string "verificationContact" string "projectverify@example.com (reference #API-2022)" "$PROJECT") -PROJECT=$(envelope assertion add pred-obj string "methodology" string "Security metrics measured through automated testing, pre and post implementation" "$PROJECT") -PROJECT=$(envelope assertion add pred-obj string "limitations" string "Metrics cover controlled test environment; may vary in production" "$PROJECT") -PROJECT=$(envelope assertion add pred-obj string "independentVerification" string "Security audit conducted by external firm (certificate hash available on request)" "$PROJECT") -``` - -Now let's add this to BWHacker's XID as a formal self-attestation: -👉 -```sh -XID_DOC=$(envelope assertion add pred-obj string "projectAttestation" envelope "$PROJECT" "$XID_DOC") -echo "$XID_DOC" > output/amira-xid-with-project.envelope -``` - -Let's view the hierarchical project attestation structure: - -👉 -```sh -echo "Hierarchical Project Attestation Structure:" -envelope format --type tree "$PROJECT" -``` - -🔍 -```console -"Financial API Security Overhaul" [ - "role": "Lead Security Developer" - "timeframe": "2022-03 through 2022-09" - "client": "Financial services sector (details available after NDA)" - "implementation": "Implementation Details" [ - "summaryHash": DIGEST - "designApproachHash": DIGEST - "primaryLanguages": "Rust, TypeScript, WebAssembly" - "architecturePattern": "Microservices with edge computing components" - ] - "outcomes": "Project Outcomes" [ - "metricsHash": DIGEST - "deploymentHash": DIGEST - "auditHash": DIGEST - "successCriteria": "Performance, security audit, and compliance requirements met" - ] - "verificationContact": "projectverify@example.com (reference #API-2022)" - "methodology": "Security metrics measured through automated testing, pre and post implementation" - "limitations": "Metrics cover controlled test environment; may vary in production" - "independentVerification": "Security audit conducted by external firm (certificate hash available on request)" -] -``` - -This hierarchical structure organizes information logically while protecting sensitive details through evidence commitments, providing multiple levels of verification. - -## 3. Creating a Multi-Credential Educational Attestation - -Let's create an educational attestation with a multi-credential structure that respects privacy: - -👉 -```sh -EDUCATION=$(envelope subject type string "Educational Background") - -CS_DEGREE=$(envelope subject type string "Computer Science Degree") -CS_DEGREE=$(envelope assertion add pred-obj string "degreeLevel" string "Masters" "$CS_DEGREE") -CS_DEGREE=$(envelope assertion add pred-obj string "completionYear" string "2015" "$CS_DEGREE") -CS_DEGREE=$(envelope assertion add pred-obj string "specialization" string "Security & Distributed Systems" "$CS_DEGREE") -CS_DEGREE=$(envelope assertion add pred-obj string "credentialType" string "Accredited University Degree" "$CS_DEGREE") -CS_DEGREE=$(envelope assertion add pred-obj string "relevantCoursework" string "Cryptography, Secure Systems Design, Privacy Engineering" "$CS_DEGREE") -CS_DEGREE=$(envelope assertion add pred-obj string "projectTitle" string "Zero-Knowledge Authentication Framework" "$CS_DEGREE") - -CS_DEGREE=$(envelope assertion add pred-obj string "limitations" string "Cannot provide specific institution without compromising pseudonymity" "$CS_DEGREE") -CS_DEGREE=$(envelope assertion add pred-obj string "verificationOption" string "Partial transcript available under strict NDA" "$CS_DEGREE") - -CERT1=$(envelope subject type string "Security Certification") -CERT1=$(envelope assertion add pred-obj string "certName" string "Certified Information Systems Security Professional (CISSP)" "$CERT1") -CERT1=$(envelope assertion add pred-obj string "issueYear" string "2017" "$CERT1") -CERT1=$(envelope assertion add pred-obj string "status" string "Active" "$CERT1") -CERT1=$(envelope assertion add pred-obj string "verificationMethod" string "Certificate ID hash available for private verification" "$CERT1") - -CERT2=$(envelope subject type string "Cloud Security Certification") -CERT2=$(envelope assertion add pred-obj string "certName" string "Certified Cloud Security Professional (CCSP)" "$CERT2") -CERT2=$(envelope assertion add pred-obj string "issueYear" string "2019" "$CERT2") -CERT2=$(envelope assertion add pred-obj string "status" string "Active" "$CERT2") -CERT2=$(envelope assertion add pred-obj string "verificationMethod" string "Certificate ID hash available for private verification" "$CERT2") - -EDUCATION=$(envelope assertion add pred-obj string "primaryDegree" envelope "$CS_DEGREE" "$EDUCATION") -EDUCATION=$(envelope assertion add pred-obj string "certification" envelope "$CERT1" "$EDUCATION") -EDUCATION=$(envelope assertion add pred-obj string "certification" envelope "$CERT2" "$EDUCATION") - -XID_DOC=$(envelope assertion add pred-obj string "educationalAttestation" envelope "$EDUCATION" "$XID_DOC") -echo "$XID_DOC" > output/amira-xid-with-education.envelope - -echo "Multi-Credential Educational Attestation:" -envelope format --type tree "$EDUCATION" -``` - -🔍 -```console -"Educational Background" [ - "primaryDegree": "Computer Science Degree" [ - "degreeLevel": "Masters" - "completionYear": "2015" - "specialization": "Security & Distributed Systems" - "credentialType": "Accredited University Degree" - "relevantCoursework": "Cryptography, Secure Systems Design, Privacy Engineering" - "projectTitle": "Zero-Knowledge Authentication Framework" - "limitations": "Cannot provide specific institution without compromising pseudonymity" - "verificationOption": "Partial transcript available under strict NDA" - ] - "certification": "Security Certification" [ - "certName": "Certified Information Systems Security Professional (CISSP)" - "issueYear": "2017" - "status": "Active" - "verificationMethod": "Certificate ID hash available for private verification" - ] - "certification": "Cloud Security Certification" [ - "certName": "Certified Cloud Security Professional (CCSP)" - "issueYear": "2019" - "status": "Active" - "verificationMethod": "Certificate ID hash available for private verification" - ] -] -``` - -This multi-credential structure enables Amira to provide detailed educational information without revealing her identity, while still offering verification paths for each credential. - -## 4. Creating a GitHub-Verifiable Open Source Portfolio - -Now let's create an open source contribution portfolio with direct links to verifiable GitHub activity: - -👉 -```sh -PORTFOLIO=$(envelope subject type string "Open Source Portfolio") - -SSH_KEY_FINGERPRINT=$(envelope format --type tree "$XID_DOC" | grep "sshKeyFingerprint" | cut -d'"' -f2) - -CONTRIBUTION1=$(envelope subject type string "Privacy Library Contribution") -CONTRIBUTION1=$(envelope assertion add pred-obj string "repository" string "github.com/example/privacy-toolkit" "$CONTRIBUTION1") -CONTRIBUTION1=$(envelope assertion add pred-obj string "role" string "Core Contributor & Security Reviewer" "$CONTRIBUTION1") -CONTRIBUTION1=$(envelope assertion add pred-obj string "timeframe" string "2020-05 through 2022-01" "$CONTRIBUTION1") -CONTRIBUTION1=$(envelope assertion add pred-obj string "commitCount" string "47" "$CONTRIBUTION1") -CONTRIBUTION1=$(envelope assertion add pred-obj string "featuresImplemented" string "Zero-knowledge authentication module, GDPR compliance tools" "$CONTRIBUTION1") -CONTRIBUTION1=$(envelope assertion add pred-obj string "commitSignatureMethod" string "SSH signed with key fingerprint in XID" "$CONTRIBUTION1") -CONTRIBUTION1=$(envelope assertion add pred-obj string "sshKeyFingerprint" string "$SSH_KEY_FINGERPRINT" "$CONTRIBUTION1") -CONTRIBUTION1=$(envelope assertion add pred-obj string "verificationInstructions" string "Filter commits by author 'BWHacker', verify SSH signatures match fingerprint" "$CONTRIBUTION1") - -CONTRIBUTION2=$(envelope subject type string "Distributed Systems Framework") -CONTRIBUTION2=$(envelope assertion add pred-obj string "repository" string "github.com/example/distributed-consensus" "$CONTRIBUTION2") -CONTRIBUTION2=$(envelope assertion add pred-obj string "role" string "Security Auditor & Performance Optimizer" "$CONTRIBUTION2") -CONTRIBUTION2=$(envelope assertion add pred-obj string "timeframe" string "2021-04 through 2022-03" "$CONTRIBUTION2") -CONTRIBUTION2=$(envelope assertion add pred-obj string "commitCount" string "23" "$CONTRIBUTION2") -CONTRIBUTION2=$(envelope assertion add pred-obj string "issueCount" string "15" "$CONTRIBUTION2") -CONTRIBUTION2=$(envelope assertion add pred-obj string "contributionFocus" string "Security hardening, performance optimization, consensus protocol" "$CONTRIBUTION2") -CONTRIBUTION2=$(envelope assertion add pred-obj string "commitSignatureMethod" string "SSH signed with key fingerprint in XID" "$CONTRIBUTION2") -CONTRIBUTION2=$(envelope assertion add pred-obj string "sshKeyFingerprint" string "$SSH_KEY_FINGERPRINT" "$CONTRIBUTION2") -CONTRIBUTION2=$(envelope assertion add pred-obj string "verificationInstructions" string "Filter commits by author 'BWHacker', verify SSH signatures match fingerprint" "$CONTRIBUTION2") - -PORTFOLIO=$(envelope assertion add pred-obj string "majorContribution" envelope "$CONTRIBUTION1" "$PORTFOLIO") -PORTFOLIO=$(envelope assertion add pred-obj string "majorContribution" envelope "$CONTRIBUTION2" "$PORTFOLIO") - -PORTFOLIO=$(envelope assertion add pred-obj string "totalRepositories" string "12" "$PORTFOLIO") -PORTFOLIO=$(envelope assertion add pred-obj string "totalCommits" string "215" "$PORTFOLIO") -PORTFOLIO=$(envelope assertion add pred-obj string "primaryExpertiseAreas" string "Security, cryptography, distributed systems" "$PORTFOLIO") -PORTFOLIO=$(envelope assertion add pred-obj string "githubProfile" string "https://github.com/BWHacker" "$PORTFOLIO") -PORTFOLIO=$(envelope assertion add pred-obj string "verificationMethod" string "All commits signed with SSH key matching fingerprint in XID" "$PORTFOLIO") -PORTFOLIO=$(envelope assertion add pred-obj string "limitations" string "Some contributions to private repositories not included" "$PORTFOLIO") - -XID_DOC=$(envelope assertion add pred-obj string "openSourcePortfolio" envelope "$PORTFOLIO" "$XID_DOC") -echo "$XID_DOC" > output/amira-xid-with-os-portfolio.envelope - -echo "GitHub-Verifiable Open Source Portfolio:" -envelope format --type tree "$PORTFOLIO" -``` - -🔍 -```console -"Open Source Portfolio" [ - "majorContribution": "Privacy Library Contribution" [ - "repository": "github.com/example/privacy-toolkit" - "role": "Core Contributor & Security Reviewer" - "timeframe": "2020-05 through 2022-01" - "commitCount": "47" - "featuresImplemented": "Zero-knowledge authentication module, GDPR compliance tools" - "commitSignatureMethod": "SSH signed with key fingerprint in XID" - "sshKeyFingerprint": "SHA256:dFbxBGrqMQNJKpZccInX7l/QE1xH/jNzDvUo/jICSHE" - "verificationInstructions": "Filter commits by author 'BWHacker', verify SSH signatures match fingerprint" - ] - "majorContribution": "Distributed Systems Framework" [ - "repository": "github.com/example/distributed-consensus" - "role": "Security Auditor & Performance Optimizer" - "timeframe": "2021-04 through 2022-03" - "commitCount": "23" - "issueCount": "15" - "contributionFocus": "Security hardening, performance optimization, consensus protocol" - "commitSignatureMethod": "SSH signed with key fingerprint in XID" - "sshKeyFingerprint": "SHA256:dFbxBGrqMQNJKpZccInX7l/QE1xH/jNzDvUo/jICSHE" - "verificationInstructions": "Filter commits by author 'BWHacker', verify SSH signatures match fingerprint" - ] - "totalRepositories": "12" - "totalCommits": "215" - "primaryExpertiseAreas": "Security, cryptography, distributed systems" - "githubProfile": "https://github.com/BWHacker" - "verificationMethod": "All commits signed with SSH key matching fingerprint in XID" - "limitations": "Some contributions to private repositories not included" -] -``` - -This portfolio connects directly to Amira's GitHub activity, creating a verifiable chain between her pseudonymous XID and her public contributions. - -## 5. Creating a Comprehensive Skills Assessment with Evidence Levels - -Let's create a detailed skills assessment with evidence levels for different verification contexts: - -👉 -```sh -SKILLS=$(envelope subject type string "Technical Skills Assessment") - -SECURITY_SKILLS=$(envelope subject type string "Security Engineering Skills") -SECURITY_SKILLS=$(envelope assertion add pred-obj string "expertiseLevel" string "Expert (8+ years)" "$SECURITY_SKILLS") -SECURITY_SKILLS=$(envelope assertion add pred-obj string "domains" string "Privacy-preserving systems, secure messaging, location privacy" "$SECURITY_SKILLS") -SECURITY_SKILLS=$(envelope assertion add pred-obj string "publicEvidence" string "GitHub contributions to privacy projects, security advisories for mobile apps" "$SECURITY_SKILLS") -SECURITY_SKILLS=$(envelope assertion add pred-obj string "privateEvidence" string "Safety app architecture designs, privacy audit results" "$SECURITY_SKILLS") -SECURITY_SKILLS=$(envelope assertion add pred-obj string "verificationMethod" string "Review public contributions and request NDA for sensitive project details" "$SECURITY_SKILLS") - -DEVELOPMENT_SKILLS=$(envelope subject type string "Software Development Skills") -DEVELOPMENT_SKILLS=$(envelope assertion add pred-obj string "expertiseLevel" string "Expert (10+ years)" "$DEVELOPMENT_SKILLS") -DEVELOPMENT_SKILLS=$(envelope assertion add pred-obj string "languages" string "Rust, Swift, TypeScript, Kotlin, C" "$DEVELOPMENT_SKILLS") -DEVELOPMENT_SKILLS=$(envelope assertion add pred-obj string "frameworks" string "React Native, Flutter, SwiftUI, Jetpack Compose" "$DEVELOPMENT_SKILLS") -DEVELOPMENT_SKILLS=$(envelope assertion add pred-obj string "strengthAreas" string "Mobile app security, offline-first design, secure data storage" "$DEVELOPMENT_SKILLS") -DEVELOPMENT_SKILLS=$(envelope assertion add pred-obj string "improvementAreas" string "Accessibility features, UI animation, graphic design" "$DEVELOPMENT_SKILLS") -DEVELOPMENT_SKILLS=$(envelope assertion add pred-obj string "publicEvidence" string "Mobile security library contributions, GitHub mobile repos" "$DEVELOPMENT_SKILLS") -DEVELOPMENT_SKILLS=$(envelope assertion add pred-obj string "verificationMethod" string "Code review, technical discussion, prototype evaluation" "$DEVELOPMENT_SKILLS") - -CRYPTO_SKILLS=$(envelope subject type string "Privacy Engineering Skills") -CRYPTO_SKILLS=$(envelope assertion add pred-obj string "expertiseLevel" string "Advanced (6+ years)" "$CRYPTO_SKILLS") -CRYPTO_SKILLS=$(envelope assertion add pred-obj string "domains" string "Location privacy, data minimization, secure storage, safe notifications" "$CRYPTO_SKILLS") -CRYPTO_SKILLS=$(envelope assertion add pred-obj string "implementations" string "Privacy-preserving location tracking, secure local data storage, encrypted messaging" "$CRYPTO_SKILLS") -CRYPTO_SKILLS=$(envelope assertion add pred-obj string "publicEvidence" string "Privacy architecture contributions, secure notification protocols" "$CRYPTO_SKILLS") -CRYPTO_SKILLS=$(envelope assertion add pred-obj string "verificationMethod" string "Technical interview, architecture review, threat model evaluation" "$CRYPTO_SKILLS") - -# Add skill domains to the skills assessment -SKILLS=$(envelope assertion add pred-obj string "skillDomain" envelope "$SECURITY_SKILLS" "$SKILLS") -SKILLS=$(envelope assertion add pred-obj string "skillDomain" envelope "$DEVELOPMENT_SKILLS" "$SKILLS") -SKILLS=$(envelope assertion add pred-obj string "skillDomain" envelope "$CRYPTO_SKILLS" "$SKILLS") - -# Add fair witness context -SKILLS=$(envelope assertion add pred-obj string "selfAssessmentMethod" string "Structured self-evaluation based on project history, peer feedback, and objective metrics" "$SKILLS") -SKILLS=$(envelope assertion add pred-obj string "assessmentLimitations" string "Self-assessment may differ from formal evaluation; strengths in technical areas more than soft skills" "$SKILLS") -SKILLS=$(envelope assertion add pred-obj string "continuousLearning" string "Actively developing in: post-quantum cryptography, formal verification, zero-knowledge machine learning" "$SKILLS") -SKILLS=$(envelope assertion add pred-obj string "lastUpdated" string "$(date +%Y-%m-%d)" "$SKILLS") - -# Add to BWHacker's XID -XID_DOC=$(envelope assertion add pred-obj string "skillsAttestation" envelope "$SKILLS" "$XID_DOC") -echo "$XID_DOC" > output/amira-xid-with-skills.envelope - -# View the skills assessment structure -echo "Comprehensive Skills Assessment Framework:" -envelope format --type tree "$SKILLS" -``` - -🔍 -```console -"Technical Skills Assessment" [ - "skillDomain": "Security Engineering Skills" [ - "expertiseLevel": "Expert (8+ years)" - "domains": "Authentication systems, API security, threat modeling" - "publicEvidence": "GitHub contributions, published security advisories" - "privateEvidence": "Client project outcomes, security audit results" - "verificationMethod": "Review public contributions and request NDA for project details" - ] - "skillDomain": "Software Development Skills" [ - "expertiseLevel": "Expert (10+ years)" - "languages": "Rust, Go, TypeScript, Python, C" - "frameworks": "React, Node.js, WebAssembly, Tauri" - "strengthAreas": "Backend systems, cryptographic implementations, performance optimization" - "improvementAreas": "Mobile UI design, graphic design, front-end animations" - "publicEvidence": "Open source code, GitHub contributions" - "verificationMethod": "Code review, technical discussion, pair programming" - ] - "skillDomain": "Cryptography Skills" [ - "expertiseLevel": "Advanced (6+ years)" - "domains": "Zero-knowledge proofs, key management, secure multi-party computation" - "implementations": "ZK authentication systems, secure enclaves, threshold signatures" - "publicEvidence": "Cryptography library contributions, protocol designs" - "verificationMethod": "Technical interview, code review, protocol analysis" - ] - "selfAssessmentMethod": "Structured self-evaluation based on project history, peer feedback, and objective metrics" - "assessmentLimitations": "Self-assessment may differ from formal evaluation; strengths in technical areas more than soft skills" - "continuousLearning": "Actively developing in: post-quantum cryptography, formal verification, zero-knowledge machine learning" - "lastUpdated": "2023-05-12" -] -``` - -This skills framework provides a nuanced assessment with different evidence types and verification methods for each skill domain, while acknowledging limitations. - -## 6. Creating Custom Elided Views for Different Audiences - -Let's create specialized elided views of BWHacker's XID for different audiences. For a deeper understanding of how elision works cryptographically, see the [Elision Cryptography](../concepts/elision-cryptography.md) concept document. - -👉 -```sh -# Create a public view for general professional networking -PUBLIC_XID=$(envelope elide assertion predicate string "projectAttestation" "$XID_DOC") -PUBLIC_XID=$(envelope elide assertion predicate string "educationalAttestation" "$PUBLIC_XID") -echo "$PUBLIC_XID" > output/bwhacker-public-view.envelope - -# Create a technical view for potential collaborators (keeps skills and open source) -TECHNICAL_XID=$(envelope elide assertion predicate string "projectAttestation" "$XID_DOC") -TECHNICAL_XID=$(envelope elide assertion predicate string "educationalAttestation" "$TECHNICAL_XID") -echo "$TECHNICAL_XID" > output/bwhacker-technical-view.envelope - -# Create a project view for potential clients (keeps projects and skills) -PROJECT_XID=$(envelope elide assertion predicate string "educationalAttestation" "$XID_DOC") -PROJECT_XID=$(envelope elide assertion predicate string "openSourcePortfolio" "$PROJECT_XID") -echo "$PROJECT_XID" > output/bwhacker-project-view.envelope - -# View the sizes of the different profiles -echo "Size comparison of different XID views:" -echo "Full XID: $(echo "$XID_DOC" | wc -c) bytes" -echo "Public view: $(echo "$PUBLIC_XID" | wc -c) bytes" -echo "Technical view: $(echo "$TECHNICAL_XID" | wc -c) bytes" -echo "Project view: $(echo "$PROJECT_XID" | wc -c) bytes" -``` - -🔍 -```console -Size comparison of different XID views: -Full XID: 4782 bytes -Public view: 1654 bytes -Technical view: 2836 bytes -Project view: 3219 bytes -``` - -These different views enable Amira to share tailored portions of her identity with different audiences while maintaining cryptographic verifiability of each view. - -## 7. Affirming Attestations and Evidence - -Let's demonstrate the affirmation process for the evidence commitments and attestations: - -👉 -```sh -if [ -f "output/amira-key.private" ]; then - PRIVATE_KEYS=$(cat output/amira-key.private) - PUBLIC_KEYS=$(cat output/amira-key.public) - - WRAPPED_SKILLS=$(envelope subject type wrapped "$SKILLS") - - SIGNED_SKILLS=$(envelope sign -s "$PRIVATE_KEYS" "$WRAPPED_SKILLS") - echo "$SIGNED_SKILLS" > output/signed-skills-attestation.envelope - - echo "Verifying signature on skills attestation:" - if envelope verify -v "$PUBLIC_KEYS" "$SIGNED_SKILLS"; then - echo "✅ Signature verification successful" - else - echo "❌ Signature verification failed" - fi - - echo -e "\nThis verification confirms the attestation was signed by the XID holder" -fi - -echo -e "\nDemonstrating verification of evidence commitments:" -COMPUTED_HASH=$(cat evidence/security_metrics.txt | envelope digest sha256) -echo "Evidence content: $(cat evidence/security_metrics.txt)" -echo "Computed hash: $COMPUTED_HASH" -echo "Committed hash in attestation: $METRICS_HASH" - -if [ "$COMPUTED_HASH" = "$METRICS_HASH" ]; then - echo "✅ Evidence verified - matches the commitment in the attestation" -else - echo "❌ Evidence does not match commitment" -fi - -echo -e "\nThis verification process confirms:" -echo "1. The XID holder knew this evidence when creating the attestation" -echo "2. The evidence hasn't been modified since the attestation was created" -echo "3. The evidence exactly matches what was committed to in the attestation" -``` - -🔍 -```console -Verifying signature on skills attestation: -✅ Signature verification successful - -This verification confirms the attestation was signed by the XID holder - -Demonstrating verification of evidence commitments: -Evidence content: Reduced data exposure by 60% while improving authentication speed by 35% -Computed hash: 9c7b54a731a08643209d9b352392a3b1960a25b3f761b388b8180ed82d3e8cd2 -Committed hash in attestation: 9c7b54a731a08643209d9b352392a3b1960a25b3f761b388b8180ed82d3e8cd2 -✅ Evidence verified - matches the commitment in the attestation - -This verification process confirms: -1. The XID holder knew this evidence when creating the attestation -2. The evidence hasn't been modified since the attestation was created -3. The evidence exactly matches what was committed to in the attestation -``` - -This verification demonstrates how others can validate evidence and attestations through cryptographic means without Amira revealing her identity. - -## Adding Public Interest Attestations - -Now that Amira has established her technical capabilities, she wants to communicate her values and ethical commitments that align with Ben's women's safety app project. Let's create a public interest attestation: - -👉 -```sh -mkdir -p output - -PUBLIC_INTEREST=$(envelope subject type string "Public Interest Commitment") -PUBLIC_INTEREST=$(envelope assertion add pred-obj string "focus" string "Privacy as a Fundamental Right" "$PUBLIC_INTEREST") -PUBLIC_INTEREST=$(envelope assertion add pred-obj string "values" string "Data minimization, informed consent, user agency" "$PUBLIC_INTEREST") -PUBLIC_INTEREST=$(envelope assertion add pred-obj string "approach" string "Privacy by design, ethical data handling" "$PUBLIC_INTEREST") - -COMMITMENTS=$(envelope subject type string "Ethical Commitments") -COMMITMENTS=$(envelope assertion add pred-obj string "userControl" string "Systems that give users control over their data and identity" "$COMMITMENTS") -COMMITMENTS=$(envelope assertion add pred-obj string "dataMinimization" string "Collecting only what's necessary for the specific functionality" "$COMMITMENTS") -COMMITMENTS=$(envelope assertion add pred-obj string "safetyFirst" string "Designing for safety of vulnerable users as a primary requirement" "$COMMITMENTS") -PUBLIC_INTEREST=$(envelope assertion add pred-obj string "ethicalCommitments" envelope "$COMMITMENTS" "$PUBLIC_INTEREST") - -PUBLIC_INTEREST=$(envelope assertion add pred-obj string "limitations" string "Commitments represent aspirational values; implementation varies by context" "$PUBLIC_INTEREST") -PUBLIC_INTEREST=$(envelope assertion add pred-obj string "verification" string "Demonstrated through consistent application in project work" "$PUBLIC_INTEREST") - -XID_DOC=$(envelope assertion add pred-obj string "publicInterestAttestation" envelope "$PUBLIC_INTEREST" "$XID_DOC") -echo "$XID_DOC" > output/amira-xid-full.envelope - -echo "Public Interest Attestation:" -envelope format --type tree "$PUBLIC_INTEREST" -``` - -🔍 -```console -"Public Interest Commitment" [ - "focus": "Privacy as a Fundamental Right" - "values": "Data minimization, informed consent, user agency" - "approach": "Privacy by design, ethical data handling" - "ethicalCommitments": "Ethical Commitments" [ - "userControl": "Systems that give users control over their data and identity" - "dataMinimization": "Collecting only what's necessary for the specific functionality" - "safetyFirst": "Designing for safety of vulnerable users as a primary requirement" - ] - "limitations": "Commitments represent aspirational values; implementation varies by context" - "verification": "Demonstrated through consistent application in project work" -] -``` - -This public interest attestation helps Ben understand Amira's values and ethical approach, which are particularly important for a sensitive project like a women's safety app. - -## Understanding Disclosure Risks - -When creating attestations, Amira carefully evaluates the privacy risks of each type of information she includes: - -👉 -```sh -RISK_ASSESSMENT=$(envelope subject type string "Attestation Risk Assessment") - -TECHNICAL_RISK=$(envelope subject type string "Technical Skills Risk") -TECHNICAL_RISK=$(envelope assertion add pred-obj string "riskLevel" string "Low" "$TECHNICAL_RISK") -TECHNICAL_RISK=$(envelope assertion add pred-obj string "rationale" string "Technical skills are broadly shared by many developers" "$TECHNICAL_RISK") -TECHNICAL_RISK=$(envelope assertion add pred-obj string "mitigation" string "Use general skill domains without unique specializations" "$TECHNICAL_RISK") -RISK_ASSESSMENT=$(envelope assertion add pred-obj string "riskCategory" envelope "$TECHNICAL_RISK" "$RISK_ASSESSMENT") - -PROJECT_RISK=$(envelope subject type string "Project Details Risk") -PROJECT_RISK=$(envelope assertion add pred-obj string "riskLevel" string "Medium" "$PROJECT_RISK") -PROJECT_RISK=$(envelope assertion add pred-obj string "rationale" string "Project patterns can sometimes be traced to specific individuals" "$PROJECT_RISK") -PROJECT_RISK=$(envelope assertion add pred-obj string "mitigation" string "Use evidence commitments and elide client names" "$PROJECT_RISK") -RISK_ASSESSMENT=$(envelope assertion add pred-obj string "riskCategory" envelope "$PROJECT_RISK" "$RISK_ASSESSMENT") - -EDUCATION_RISK=$(envelope subject type string "Educational Background Risk") -EDUCATION_RISK=$(envelope assertion add pred-obj string "riskLevel" string "High" "$EDUCATION_RISK") -EDUCATION_RISK=$(envelope assertion add pred-obj string "rationale" string "Specific degrees, years, and institutions are highly identifying" "$EDUCATION_RISK") -EDUCATION_RISK=$(envelope assertion add pred-obj string "mitigation" string "Omit institution names, use general timeframes, focus on skills not credentials" "$EDUCATION_RISK") -RISK_ASSESSMENT=$(envelope assertion add pred-obj string "riskCategory" envelope "$EDUCATION_RISK" "$RISK_ASSESSMENT") - -echo "$RISK_ASSESSMENT" > output/attestation-risk-assessment.envelope - -echo "Attestation Risk Assessment:" -envelope format --type tree "$RISK_ASSESSMENT" -``` - -🔍 -```console -"Attestation Risk Assessment" [ - "riskCategory": "Technical Skills Risk" [ - "riskLevel": "Low" - "rationale": "Technical skills are broadly shared by many developers" - "mitigation": "Use general skill domains without unique specializations" - ] - "riskCategory": "Project Details Risk" [ - "riskLevel": "Medium" - "rationale": "Project patterns can sometimes be traced to specific individuals" - "mitigation": "Use evidence commitments and elide client names" - ] - "riskCategory": "Educational Background Risk" [ - "riskLevel": "High" - "rationale": "Specific degrees, years, and institutions are highly identifying" - "mitigation": "Omit institution names, use general timeframes, focus on skills not credentials" - ] -] -``` - -By understanding these risk levels, Amira can make informed decisions about what to include in her attestations and how to structure them to protect her privacy. - -## Understanding the Advanced Attestation Framework - -In this tutorial, we've seen how Amira creates a sophisticated self-attestation framework: - -1. **Structured Framework Design**: Creating a comprehensive framework to organize different attestation types and evidence models. - -2. **Hierarchical Information Organization**: Building nested structures that logically arrange information while supporting selective disclosure. - -3. **Multi-Credential Approach**: Organizing multiple credentials in a way that protects privacy while enabling verification. - -4. **GitHub Verification Integration**: Creating a bidirectional verification chain between the XID and GitHub activity. - -5. **Evidence Level Separation**: Distinguishing between public, private, and confidential evidence with appropriate verification paths. - -6. **Audience-Specific Views**: Creating tailored profiles for different verification contexts while maintaining integrity. - -7. **Fair Witness Principles at Scale**: Consistently applying proper context, limitations, and verification methods across all attestation types. - -8. **Value and Ethics Integration**: Including public interest attestations that demonstrate alignment with project values. - -9. **Risk-Aware Disclosure**: Carefully assessing the privacy risks of different attestation types and using appropriate mitigations. - -This approach enables Amira to build comprehensive trust frameworks without revealing her identity, using cryptographic verification and selective disclosure to control what information is shared with whom. - -### Theory to Practice: Attestation Frameworks and Fair Witnessing - -The self-attestation framework you've just implemented demonstrates several advanced identity concepts: - -1. **Fair Witnessing**: By documenting specific technical skills with verifiable evidence, you've implemented the **Fair Witness approach** to attestations. This includes separating observed facts from interpretations, documenting methodology, and acknowledging limitations - creating attestations that others can evaluate on their merits. - > **Historical Context**: The term "Fair Witness" comes from Robert Heinlein's "Stranger in a Strange Land," describing individuals trained to observe events objectively and report exactly what they see without interpretation or bias. - -2. **Evidence Commitments**: The links to project contributions and education implement **evidence commitments** - cryptographically verifiable references to external evidence that support claims without requiring disclosure of personal identity. These provide objective anchors that others can independently validate. - > **Why this matters**: Unlike simple claims ("I know security"), evidence commitments provide a verifiable basis for assertions, allowing others to independently validate claims without requiring disclosure of personal identity. - -3. **Multi-Dimensional Trust Framework**: The different types of attestations (education, skills, risk assessment) implement a **comprehensive trust framework**. Unlike flat credential systems, this approach provides multiple perspectives that collectively build a nuanced participation profile. - > **Real-World Analogy**: This is similar to how employers assess candidates through multiple dimensions: formal credentials, skills tests, previous work products, and reference checks. Each dimension provides a different perspective on capabilities. - -4. **Contextual Disclosure Through Elision**: The different elided views you created implement **proportional disclosure** - sharing only what's relevant for a specific audience or context. This supports the data minimization principle while still allowing verification of the information shared. - > **Cross-Tutorial Connection**: This builds on the elision concept from Tutorial #2, but applies it specifically to create audience-appropriate views of attestations. In Tutorial #4, you'll extend this to manage peer endorsements with similar contextual disclosure. - -5. **Progressive Trust Development**: The framework allows BWHacker to start with minimal disclosure (the public view) and progressively reveal more information as relationships develop. This implements **graduated information disclosure**, where trust and disclosure increase in tandem throughout a relationship. - -6. **Risk-Reward Assessment**: By creating different views for different audiences, BWHacker is implementing a **risk-reward calculus** - carefully weighing the benefits of additional disclosure against potential privacy risks for each specific context. - -These attestation concepts enable BWHacker to build credible, verifiable trust without compromising her pseudonymity, combining the benefits of traditional credentialing with the privacy advantages of self-sovereign identity. - -## Next Steps - -In the next tutorial, we'll explore how Amira can further strengthen her professional identity through peer endorsements - attestations made by others that verify her claims and add additional trust signals to her pseudonymous identity. - -For a deeper understanding of how self-attestations fit into a broader pseudonymous participation strategy, explore the [Public Participation Profiles](../concepts/public-participation-profiles.md) concept, which explains the principles behind building trust while maintaining privacy. You can also see practical examples of different attestation types in [Public Participation Profile Examples](../concepts/public-participation-profile-examples.md). - -## Example Scripts - -This tutorial has two accompanying scripts in the `examples/03-profile-xid` directory: - -1. **`create_self_attestation_framework.sh`**: Implements the advanced self-attestation framework exactly as shown in this tutorial, including the elision-based approach to selective disclosure. This is the primary script that matches the tutorial content. - -2. **`create_alternative_profile.sh`**: Demonstrates an alternative approach to progressive disclosure without using elision. Instead of selectively eliding parts of a single envelope, it creates separate profiles with different information levels. This script also includes additional fair witness practices and portfolio structures. - -Both approaches have their advantages: -- The elision approach maintains cryptographic verifiability across all views -- The separate profile approach provides more complete control over exactly what is included in each context - -## Exercises - -1. Create your own multi-level attestation structure for a different domain (e.g., creative work, research). - -2. Design different elided views for specific audiences and verification purposes. - -3. Create a verification chain that incorporates multiple types of evidence (e.g., GitHub, professional certification, project results). - -4. Build an attestation with nested evidence commitments that reveal progressively more detail. - -5. Design a hierarchical skills framework with evidence commitments for each skill level. \ No newline at end of file diff --git a/tutorials/04-peer-endorsement-with-xids.md b/tutorials/04-peer-endorsement-with-xids.md deleted file mode 100644 index 9705c87..0000000 --- a/tutorials/04-peer-endorsement-with-xids.md +++ /dev/null @@ -1,915 +0,0 @@ -# Peer Endorsements with XIDs - -This tutorial demonstrates how BWHacker's pseudonymous identity can be strengthened through attestations from others. You'll learn how peer endorsements work, how they differ from self-attestations, and how they create a network of verified claims while preserving pseudonymity for all parties. - -**Time to complete: 30-40 minutes** - -> **Related Concepts**: Before or after completing this tutorial, you may want to read about [Attestation and Endorsement Model](../concepts/attestation-endorsement-model.md), [Pseudonymous Trust Building](../concepts/pseudonymous-trust-building.md), [Public Participation Profiles](../concepts/public-participation-profiles.md), [Public Participation Profile Examples](../concepts/public-participation-profile-examples.md), and [Elision Cryptography](../concepts/elision-cryptography.md) to understand the theoretical foundations. - -## Prerequisites - -- Completed the first three XID tutorials -- The envelope CLI tool installed -- BWHacker's XID with self-attestations from previous tutorials -- Understanding of digital signatures and verification - -## What You'll Learn - -- How peer endorsements differ from self-attestations -- How to create, sign, and verify third-party attestations about an XID -- How to establish a network of pseudonymous trust relationships -- How to design different endorsement types with appropriate scope limitations -- How to verify endorsements from multiple independent sources -- How to form a web of trust with multiple pseudonymous identities - -## Peer Endorsements: The Missing Trust Element - -BWHacker has made significant progress with their pseudonymous identity. They've built a structured self-attestation framework and provided evidence of their skills. Ben, the non-profit manager, is more confident in their abilities, but still has reservations about trusting a pseudonymous developer with sensitive work. After all, self-attestations only represent BWHacker's claims about themselves. - -This reflects a fundamental trust challenge in pseudonymous networks: how can others verify claims when they can't connect them to established real-world identities? The answer lies in peer endorsements - a critical component of distributed trust models. - -Thanks to Charlene's involvement in the RISK network, BWHacker now has an opportunity to receive endorsements from respected members of the community who have worked with them on smaller projects. These peer attestations create a powerful complement to their self-attestations: claims that others make about their work and character. - -For a pseudonymous contributor like BWHacker, peer endorsements serve multiple crucial functions: - -1. **Trust Amplification**: They transform "trust me because I say so" into "trust me because others vouch for me" -2. **Reputation Building**: They create a portable reputation that follows their pseudonymous identity -3. **Risk Reduction**: They help project owners like Ben make safer decisions about collaboration -4. **Community Integration**: They embed them in a web of relationships that strengthen their position - -Key differences between self-attestations and peer endorsements: - -1. **Source of Truth**: Self-attestations come from BWHacker themselves, while peer endorsements come from others -2. **Signature Chain**: Self-attestations are signed with BWHacker's key, while peer endorsements are signed with the endorsers' keys -3. **Trust Model**: Self-attestations build trust through evidence, while peer endorsements build trust through third-party verification -4. **Validation Method**: Self-attestations require evidence validation, while peer endorsements leverage the endorsers' credibility - -Without these peer endorsements, BWHacker would remain isolated in the network - their claims unverified by others and their contributions limited to low-trust contexts. With them, they can build the robust trust framework needed to work on high-impact projects that align with their values. - -In this tutorial, we'll see how BWHacker expands their trust framework through various types of peer endorsements. - -## 1. Understanding the Peer Endorsement Model - -Let's begin by creating a peer endorsement framework that defines how third-party attestations work with XIDs: - -👉 -```sh -# Ensure output directory exists -mkdir -p output -mkdir -p endorsers - -# Create a peer endorsement model -ENDORSEMENT_MODEL=$(envelope subject type string "Peer-EndorsementModel") -ENDORSEMENT_MODEL=$(envelope assertion add pred-obj string "purpose" string "Enable third-party assessment of skills and contributions" "$ENDORSEMENT_MODEL") -ENDORSEMENT_MODEL=$(envelope assertion add pred-obj string "endorsementTypes" string "Skill assessment, Project collaboration, Code review, Character reference" "$ENDORSEMENT_MODEL") -ENDORSEMENT_MODEL=$(envelope assertion add pred-obj string "requirements" string "Specific scope, Temporal context, Limitations, Relationship context" "$ENDORSEMENT_MODEL") -ENDORSEMENT_MODEL=$(envelope assertion add pred-obj string "assessmentMethod" string "Verify endorser's signature cryptographically, then evaluate evidence if provided" "$ENDORSEMENT_MODEL") - -# Define endorsement proof levels -PROOF_LEVELS=$(envelope subject type string "EndorsementProofLevels") -PROOF_LEVELS=$(envelope assertion add pred-obj string "directCollaboration" string "First-hand knowledge through direct project collaboration" "$PROOF_LEVELS") -PROOF_LEVELS=$(envelope assertion add pred-obj string "codeReview" string "Direct examination of code or technical artifacts" "$PROOF_LEVELS") -PROOF_LEVELS=$(envelope assertion add pred-obj string "outputEvaluation" string "Evaluation of completed work products or deliverables" "$PROOF_LEVELS") -PROOF_LEVELS=$(envelope assertion add pred-obj string "testimonial" string "Second-hand knowledge or general character reference" "$PROOF_LEVELS") - -# Add proof levels to the model -ENDORSEMENT_MODEL=$(envelope assertion add pred-obj string "proofLevels" envelope "$PROOF_LEVELS" "$ENDORSEMENT_MODEL") - -# Save the endorsement model -echo "$ENDORSEMENT_MODEL" > output/endorsement-model.envelope - -# Display the endorsement model -echo "Peer Endorsement Model:" -envelope format --type tree "$ENDORSEMENT_MODEL" -``` - -🔍 -```console -"Peer-EndorsementModel" [ - "purpose": "Enable third-party verification of skills and contributions" - "endorsementTypes": "Skill verification, Project collaboration, Code review, Character reference" - "requirements": "Specific scope, Temporal context, Limitations, Relationship context" - "validationMethod": "Verify endorser's signature and credibility, then assess evidence if provided" - "proofLevels": "EndorsementProofLevels" [ - "directCollaboration": "First-hand knowledge through direct project collaboration" - "codeReview": "Direct examination of code or technical artifacts" - "outputEvaluation": "Evaluation of completed work products or deliverables" - "testimonial": "Second-hand knowledge or general character reference" - ] -] -``` - -This model establishes a framework for organizing and validating different types of peer endorsements, including their required components and proof levels. - -## 2. Creating an Endorser's XID - -For peer endorsements to work, we need another person with their own XID. Let's create one for Carlos, a security researcher who has collaborated with BWHacker. First, let's create Carlos's XID key pair: - -👉 -```sh -envelope generate prvkeys > endorsers/carlos-key.private -CARLOS_PRIVATE=$(cat endorsers/carlos-key.private) -CARLOS_PUBLIC=$(envelope generate pubkeys "$CARLOS_PRIVATE") -echo "$CARLOS_PUBLIC" > endorsers/carlos-key.public -``` - -Now, let's create Carlos's XID: - -👉 -```sh -CARLOS_XID=$(envelope xid new --name "Carlos_SecResearcher" "$CARLOS_PUBLIC") -``` - -Let's add basic information to Carlos's XID: - -👉 -```sh -CARLOS_XID=$(envelope assertion add pred-obj string "gitHubUsername" string "ResearchCarlos" "$CARLOS_XID") -CARLOS_XID=$(envelope assertion add pred-obj string "domain" string "Privacy Engineering & Mobile Security" "$CARLOS_XID") -CARLOS_XID=$(envelope assertion add pred-obj string "experienceLevel" string "10 years professional practice" "$CARLOS_XID") -CARLOS_XID=$(envelope assertion add pred-obj string "verifiableProjects" string "Consulted on 12+ privacy-focused mobile apps, security advisor for nonprofits" "$CARLOS_XID") -CARLOS_XID=$(envelope assertion add pred-obj string "affiliationContext" string "Independent privacy consultant, former security lead at domestic violence prevention organization" "$CARLOS_XID") -``` - -Let's save Carlos's XID and display it: - -👉 -```sh -echo "$CARLOS_XID" > endorsers/carlos-xid.envelope - -echo "Carlos's XID:" -envelope format --type tree "$CARLOS_XID" -``` - -🔍 -```console -"Carlos_SecResearcher" [ - "name": "Carlos_SecResearcher" - "publicKeys": ur:crypto-pubkeys/hdcxtbsrldcnldkplgsrtemwollopfhfaxuydaotptpdhtaadahtsaxlsdsdsaeaeae - "gitHubUsername": "ResearchCarlos" - "domain": "Security Research & Vulnerability Analysis" - "experienceLevel": "12 years professional practice" - "verifiableProjects": "Published 7 CVEs, Security audit lead for 20+ open source projects" - "affiliationContext": "Independent security researcher, previously CISO at midsize tech company" -] -``` - -Carlos's XID creates a pseudonymous identity that can now make endorsements about BWHacker. - -## 3. Creating a Project Collaboration Endorsement - -Now let's create a detailed project collaboration endorsement that Carlos makes about BWHacker: - -First, let's load the target XID information (BWHacker): - -👉 -```sh -BWHACKER_XID_DOC=$(cat ../03-profile-xid/output/bwhacker-xid-with-skills.envelope 2>/dev/null || cat output/bwhacker-xid-full.envelope 2>/dev/null || echo "ERROR: BWHacker's XID not found") -BWHACKER_XID=$(envelope xid id "$BWHACKER_XID_DOC") -``` - -Now, let's create the collaboration endorsement: - -👉 -```sh -COLLABORATION_ENDORSEMENT=$(envelope subject type string "Project Collaboration Endorsement") -``` - -Let's add the target (who is being endorsed): - -👉 -```sh -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "endorsementTarget" string "$BWHACKER_XID" "$COLLABORATION_ENDORSEMENT") -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "targetAlias" string "BWHacker" "$COLLABORATION_ENDORSEMENT") -``` - -Next, let's add core collaboration details: - -👉 -```sh -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "projectName" string "Privacy-First Safety Alert System" "$COLLABORATION_ENDORSEMENT") -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "repositoryURL" string "https://github.com/example/privacy-alert-system" "$COLLABORATION_ENDORSEMENT") -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "collaborationPeriod" string "2021-03 through 2021-09" "$COLLABORATION_ENDORSEMENT") -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "collaborationContext" string "Joint development of privacy-preserving location features for a women's safety app" "$COLLABORATION_ENDORSEMENT") -``` - -Now, let's add endorsed skills with specific examples: - -👉 -```sh -ENDORSED_SKILLS=$(envelope subject type string "Endorsed Skills") -ENDORSED_SKILLS=$(envelope assertion add pred-obj string "locationPrivacy" string "Implemented privacy-preserving location tracking that minimizes data exposure risk" "$ENDORSED_SKILLS") -ENDORSED_SKILLS=$(envelope assertion add pred-obj string "mobileAppSecurity" string "Designed secure offline mode with emergency alert capabilities" "$ENDORSED_SKILLS") -ENDORSED_SKILLS=$(envelope assertion add pred-obj string "userDataProtection" string "Created secure data storage with minimal personal information requirements" "$ENDORSED_SKILLS") -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "endorsedSkills" envelope "$ENDORSED_SKILLS" "$COLLABORATION_ENDORSEMENT") -``` - -Let's add the proof basis (why this endorsement is credible): - -👉 -```sh -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "proofBasis" string "directCollaboration" "$COLLABORATION_ENDORSEMENT") -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "contributionEvidence" string "32 co-authored commits on privacy features, joint design of secure location services" "$COLLABORATION_ENDORSEMENT") -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "verifiableMetrics" string "Reduced PII collection by 75%, emergency alert latency below 3 seconds" "$COLLABORATION_ENDORSEMENT") -``` - -Now, let's add endorser context and limitations: - -👉 -```sh -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "endorserRelationship" string "Technical advisor for nonprofit safety app project" "$COLLABORATION_ENDORSEMENT") -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "endorsementLimitations" string "Collaboration limited to privacy and security features, no visibility into UI development skills" "$COLLABORATION_ENDORSEMENT") -COLLABORATION_ENDORSEMENT=$(envelope assertion add pred-obj string "endorserContext" string "Privacy consultant with experience in women's safety applications" "$COLLABORATION_ENDORSEMENT") -``` - -Finally, let's wrap and sign the endorsement with Carlos's private key, then add the endorser's XID identifier: - -👉 -```sh -CARLOS_PRIVATE=$(cat endorsers/carlos-key.private) - -WRAPPED_COLLABORATION=$(envelope subject type wrapped "$COLLABORATION_ENDORSEMENT") - -SIGNED_COLLABORATION=$(envelope sign -s "$CARLOS_PRIVATE" "$WRAPPED_COLLABORATION") - -CARLOS_XID_ID=$(envelope xid id "$CARLOS_XID") -SIGNED_COLLABORATION=$(envelope assertion add pred-obj string "endorserXID" string "$CARLOS_XID_ID" "$SIGNED_COLLABORATION") -echo "$SIGNED_COLLABORATION" > output/carlos-collaboration-endorsement.envelope - -echo "Signed Project Collaboration Endorsement:" -envelope format --type tree "$SIGNED_COLLABORATION" -``` - -🔍 -```console -"Project Collaboration Endorsement" [ - "endorsementTarget": "7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3" - "targetAlias": "BWHacker" - "projectName": "Open Source Security Audit Framework" - "repositoryURL": "https://github.com/example/security-audit-framework" - "collaborationPeriod": "2021-06 through 2021-12" - "collaborationContext": "Joint development of cryptographic attestation modules" - "endorsedSkills": "Endorsed Skills" [ - "cryptography": "Implemented zero-knowledge proof system for privacy-preserving attestations" - "securityArchitecture": "Designed attack-resistant validation framework with minimal attack surface" - "codingPractices": "Maintained excellent code quality with comprehensive test coverage" - ] - "proofBasis": "directCollaboration" - "contributionEvidence": "47 co-authored commits, 15 joint pull request reviews" - "verifiableMetrics": "10,000+ lines of code, security module reached 98% test coverage" - "endorserRelationship": "Project collaborator without prior or subsequent professional relationship" - "endorsementLimitations": "Collaboration limited to cryptographic modules, no visibility into other skills" - "endorserContext": "Security researcher with cryptography specialization" - "endorserXID": "b43a1bbf4e834c658b243ad3af1dfa98f704959c0ac93a509e3388568b3a46e4" - SIGNATURE -] -``` - -This collaboration endorsement provides specific, contextual verification of BWHacker's skills through direct project experience, signed by Carlos's key. - -## 4. Creating a Code Review Endorsement - -Let's create another type of endorsement based on code review: - -Let's create a second endorser: Maya, a senior developer at an open source foundation: - -👉 -```sh -envelope generate prvkeys > endorsers/maya-key.private -MAYA_PRIVATE=$(cat endorsers/maya-key.private) -MAYA_PUBLIC=$(envelope generate pubkeys "$MAYA_PRIVATE") -echo "$MAYA_PUBLIC" > endorsers/maya-key.public -``` - -Now, let's create Maya's XID: - -👉 -```sh -MAYA_XID=$(envelope xid new --name "MayaCodeX" "$MAYA_PUBLIC") -MAYA_XID=$(envelope assertion add pred-obj string "gitHubUsername" string "MayaDevX" "$MAYA_XID") -MAYA_XID=$(envelope assertion add pred-obj string "domain" string "Distributed Systems & Performance Engineering" "$MAYA_XID") -MAYA_XID=$(envelope assertion add pred-obj string "experienceLevel" string "15 years professional development" "$MAYA_XID") -MAYA_XID=$(envelope assertion add pred-obj string "affiliationContext" string "Lead Developer at Open Source Foundation" "$MAYA_XID") -echo "$MAYA_XID" > endorsers/maya-xid.envelope - -Let's create the code review endorsement: - -👉 -```sh -CODE_REVIEW=$(envelope subject type string "Code Review Endorsement") -``` - -Now, let's add target and relationship context: - -👉 -```sh -CODE_REVIEW=$(envelope assertion add pred-obj string "endorsementTarget" string "$BWHACKER_XID" "$CODE_REVIEW") -CODE_REVIEW=$(envelope assertion add pred-obj string "targetAlias" string "BWHacker" "$CODE_REVIEW") -CODE_REVIEW=$(envelope assertion add pred-obj string "relationshipContext" string "Technical reviewer for contribution to open source project" "$CODE_REVIEW") -``` - -Let's add review details: - -👉 -```sh -CODE_REVIEW=$(envelope assertion add pred-obj string "projectName" string "Privacy-Focused Location Services" "$CODE_REVIEW") -CODE_REVIEW=$(envelope assertion add pred-obj string "repositoryURL" string "https://github.com/example/safety-location-privacy" "$CODE_REVIEW") -CODE_REVIEW=$(envelope assertion add pred-obj string "pullRequestURL" string "https://github.com/example/safety-location-privacy/pull/27" "$CODE_REVIEW") -CODE_REVIEW=$(envelope assertion add pred-obj string "reviewDate" string "2022-03-15" "$CODE_REVIEW") -CODE_REVIEW=$(envelope assertion add pred-obj string "codebaseSize" string "Significant contribution: ~3,500 lines of privacy-focused code" "$CODE_REVIEW") -``` - -Now, let's create a technical assessment: - -👉 -```sh -TECHNICAL_ASSESSMENT=$(envelope subject type string "Technical Assessment") -TECHNICAL_ASSESSMENT=$(envelope assertion add pred-obj string "algorithmicComplexity" string "Excellent: Optimized location privacy algorithm with minimal battery impact" "$TECHNICAL_ASSESSMENT") -TECHNICAL_ASSESSMENT=$(envelope assertion add pred-obj string "codeQuality" string "Exceptional: Clear structure, well-documented, comprehensive tests" "$TECHNICAL_ASSESSMENT") -TECHNICAL_ASSESSMENT=$(envelope assertion add pred-obj string "securityConsiderations" string "Strong: Robust privacy protections, careful location data handling, secure caching" "$TECHNICAL_ASSESSMENT") -TECHNICAL_ASSESSMENT=$(envelope assertion add pred-obj string "performanceImpact" string "Significant: 70% reduction in location data exposure while maintaining functionality" "$TECHNICAL_ASSESSMENT") -CODE_REVIEW=$(envelope assertion add pred-obj string "assessment" envelope "$TECHNICAL_ASSESSMENT" "$CODE_REVIEW") -``` - -Let's add endorsement context: - -👉 -```sh -CODE_REVIEW=$(envelope assertion add pred-obj string "proofBasis" string "codeReview" "$CODE_REVIEW") -CODE_REVIEW=$(envelope assertion add pred-obj string "reviewDepth" string "Comprehensive line-by-line review with performance profiling" "$CODE_REVIEW") -CODE_REVIEW=$(envelope assertion add pred-obj string "endorsementLimitations" string "Assessment limited to this specific contribution and codebase" "$CODE_REVIEW") -CODE_REVIEW=$(envelope assertion add pred-obj string "verifiableEvidence" string "Code review comments and approval in GitHub PR thread" "$CODE_REVIEW") -``` - -Finally, let's wrap and sign with Maya's key and add the endorser's XID identifier: - -👉 -```sh -WRAPPED_CODE_REVIEW=$(envelope subject type wrapped "$CODE_REVIEW") - -SIGNED_CODE_REVIEW=$(envelope sign -s "$MAYA_PRIVATE" "$WRAPPED_CODE_REVIEW") - -MAYA_XID_ID=$(envelope xid id "$MAYA_XID") -SIGNED_CODE_REVIEW=$(envelope assertion add pred-obj string "endorserXID" string "$MAYA_XID_ID" "$SIGNED_CODE_REVIEW") -echo "$SIGNED_CODE_REVIEW" > output/maya-code-review-endorsement.envelope - -echo "Signed Code Review Endorsement:" -envelope format --type tree "$SIGNED_CODE_REVIEW" -``` - -🔍 -```console -WRAPPED [ - subject: "Code Review Endorsement" [ - "endorsementTarget": "7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3" - "targetAlias": "BWHacker" - "relationshipContext": "Technical reviewer for contribution to open source project" - "projectName": "Privacy-Focused Location Services" - "repositoryURL": "https://github.com/example/safety-location-privacy" - "pullRequestURL": "https://github.com/example/safety-location-privacy/pull/27" - "reviewDate": "2022-03-15" - "codebaseSize": "Significant contribution: ~3,500 lines of privacy-focused code" - "assessment": "Technical Assessment" [ - "algorithmicComplexity": "Excellent: Optimized location privacy algorithm with minimal battery impact" - "codeQuality": "Exceptional: Clear structure, well-documented, comprehensive tests" - "securityConsiderations": "Strong: Robust privacy protections, careful location data handling, secure caching" - "performanceImpact": "Significant: 70% reduction in location data exposure while maintaining functionality" - ] - "proofBasis": "codeReview" - "reviewDepth": "Comprehensive line-by-line review with performance profiling" - "endorsementLimitations": "Assessment limited to this specific contribution and codebase" - "verifiableEvidence": "Code review comments and approval in GitHub PR thread" - "endorserXID": "c8f05e72bf9f6a2d8dde84ac9f679d3fc2e4fa56f4edc7fda2f43d18d17821a6" - ] - SIGNATURE -] -``` - -This code review endorsement provides specific technical validation of BWHacker's capabilities based on in-depth analysis of actual code. - -## 5. Creating a Skill Verification Endorsement - -Let's create a focused skill verification endorsement for a specific technical capability: - -Let's create a third endorser: Priya, a cryptography specialist: - -👉 -```sh -envelope generate prvkeys > endorsers/priya-key.private -PRIYA_PRIVATE=$(cat endorsers/priya-key.private) -PRIYA_PUBLIC=$(envelope generate pubkeys "$PRIYA_PRIVATE") -echo "$PRIYA_PUBLIC" > endorsers/priya-key.public -``` - -Now, let's create Priya's XID: - -👉 -```sh -PRIYA_XID=$(envelope xid new --name "PriyaCrypto" "$PRIYA_PUBLIC") -PRIYA_XID=$(envelope assertion add pred-obj string "gitHubUsername" string "PriyaZK" "$PRIYA_XID") -PRIYA_XID=$(envelope assertion add pred-obj string "domain" string "Privacy Engineering & Data Minimization" "$PRIYA_XID") -PRIYA_XID=$(envelope assertion add pred-obj string "credentials" string "PhD in Computer Science, Focus on Privacy-Preserving Computation" "$PRIYA_XID") -PRIYA_XID=$(envelope assertion add pred-obj string "affiliationContext" string "University researcher and privacy advocate for women's safety organizations" "$PRIYA_XID") -echo "$PRIYA_XID" > endorsers/priya-xid.envelope -``` - -Let's create the skill verification endorsement: - -👉 -```sh -SKILL_ASSESSMENT=$(envelope subject type string "Skill Assessment Endorsement") -``` - -Now, let's add target and assessment context: - -👉 -```sh -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "endorsementTarget" string "$BWHACKER_XID" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "targetAlias" string "BWHacker" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "skillCategory" string "Privacy-Preserving Location Tracking" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "assessmentContext" string "Detailed review of location privacy implementation in women's safety app" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "assessmentDate" string "2023-01-10" "$SKILL_ASSESSMENT") - -``` - -Let's add the technical skill assessment: - -👉 -```sh -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "technicalAccuracy" string "Excellent: Implementation correctly balances privacy with safety requirements" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "securityConsiderations" string "Strong: Prevents location tracking without compromising emergency features" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "innovationLevel" string "High: Novel approach to secure location sharing with minimal metadata leakage" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "codeRobustness" string "Excellent: Comprehensive test suite including adversarial scenarios" "$SKILL_ASSESSMENT") - -``` - -Now, let's add the skill level assessment: - -👉 -```sh -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "proficiencyLevel" string "Expert" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "proficiencyJustification" string "Implementation shows deep understanding of privacy engineering principles" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "comparativeAssessment" string "Among the most skilled privacy engineers I've worked with in safety applications" "$SKILL_ASSESSMENT") - -``` - -Let's add assessment context: - -👉 -```sh -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "proofBasis" string "outputEvaluation" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "assessmentMethod" string "Source code review, usability testing, and privacy analysis" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "endorsementLimitations" string "Assessment focused on location privacy features, not the entire application" "$SKILL_ASSESSMENT") -SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "specificReference" string "https://github.com/example/safety-app/tree/main/location-privacy" "$SKILL_ASSESSMENT") - -``` - -Finally, let's wrap and sign with Priya's key and add the endorser's XID identifier: - -👉 -```sh -WRAPPED_SKILL_ASSESSMENT=$(envelope subject type wrapped "$SKILL_ASSESSMENT") - -SIGNED_SKILL_ASSESSMENT=$(envelope sign -s "$PRIYA_PRIVATE" "$WRAPPED_SKILL_ASSESSMENT") - -PRIYA_XID_ID=$(envelope xid id "$PRIYA_XID") -SIGNED_SKILL_ASSESSMENT=$(envelope assertion add pred-obj string "endorserXID" string "$PRIYA_XID_ID" "$SIGNED_SKILL_ASSESSMENT") -echo "$SIGNED_SKILL_ASSESSMENT" > output/priya-skill-assessment.envelope - -echo "Signed Skill Assessment Endorsement:" -envelope format --type tree "$SIGNED_SKILL_ASSESSMENT" -``` - -🔍 -```console -WRAPPED [ - subject: "Skill Assessment Endorsement" [ - "endorsementTarget": "7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3" - "targetAlias": "BWHacker" - "skillCategory": "Privacy-Preserving Location Tracking" - "assessmentContext": "Detailed review of location privacy implementation in women's safety app" - "assessmentDate": "2023-01-10" - "technicalAccuracy": "Excellent: Implementation correctly balances privacy with safety requirements" - "securityConsiderations": "Strong: Prevents location tracking without compromising emergency features" - "innovationLevel": "High: Novel approach to secure location sharing with minimal metadata leakage" - "codeRobustness": "Excellent: Comprehensive test suite including adversarial scenarios" - "proficiencyLevel": "Expert" - "proficiencyJustification": "Implementation shows deep understanding of privacy engineering principles" - "comparativeAssessment": "Among the most skilled privacy engineers I've worked with in safety applications" - "proofBasis": "outputEvaluation" - "assessmentMethod": "Source code review, usability testing, and privacy analysis" - "endorsementLimitations": "Assessment focused on location privacy features, not the entire application" - "specificReference": "https://github.com/example/safety-app/tree/main/location-privacy" - "endorserXID": "d7e32f409b7a96c53a87e8e18b12b3fa6c8f5fd2a3d7e8c9b4a2f1e3d5c7b9a8" - ] - SIGNATURE -] -``` - -This focused endorsement provides an expert's assessment of a specific technical skill with clear context and limitations. - -## 6. Adding Endorsements to BWHacker's XID and Establishing the Web of Trust - -Now, let's add these endorsements to BWHacker's XID and demonstrate how to establish the web of trust: - -First, let's load the most complete version of BWHacker's XID: - -👉 -```sh -if [ -f "../03-profile-xid/output/bwhacker-xid-with-skills.envelope" ]; then - XID_DOC=$(cat ../03-profile-xid/output/bwhacker-xid-with-skills.envelope) -else - XID_DOC=$(cat output/bwhacker-xid-full.envelope 2>/dev/null || echo "ERROR: BWHacker's XID not found") -fi -``` - -Now, let's add the endorsement model: - -👉 -```sh -XID_DOC=$(envelope assertion add pred-obj string "peerEndorsementModel" envelope "$ENDORSEMENT_MODEL" "$XID_DOC") -``` - -Next, let's add the specific endorsements: - -👉 -```sh -COLLABORATION=$(cat output/carlos-collaboration-endorsement.envelope) -CODE_REVIEW=$(cat output/maya-code-review-endorsement.envelope) -SKILL_ASSESSMENT=$(cat output/priya-skill-assessment.envelope) - -XID_DOC=$(envelope assertion add pred-obj string "peerEndorsement" envelope "$COLLABORATION" "$XID_DOC") -XID_DOC=$(envelope assertion add pred-obj string "peerEndorsement" envelope "$CODE_REVIEW" "$XID_DOC") -XID_DOC=$(envelope assertion add pred-obj string "peerEndorsement" envelope "$SKILL_ASSESSMENT" "$XID_DOC") -``` - -Let's save the updated XID: - -👉 -```sh -echo "$XID_DOC" > output/bwhacker-xid-with-endorsements.envelope -``` - -Now, let's create a trust network diagram: - -👉 -```sh -echo "Creating Web of Trust Diagram..." -echo 'digraph XIDTrustNetwork { - rankdir=LR; - node [shape=box, style=filled, fillcolor=lightblue]; - - BWHacker [label="BWHacker\nDistributed Systems & Security"]; - Carlos [label="Carlos_SecResearcher\nSecurity Research"]; - Maya [label="MayaCodeX\nDistributed Systems"]; - Priya [label="PriyaCrypto\nZero-Knowledge Proofs"]; - - Carlos -> BWHacker [label="Project Collaboration\nCryptographic Modules"]; - Maya -> BWHacker [label="Code Review\nConsensus Algorithm"]; - Priya -> BWHacker [label="Skill Assessment\nZKP Implementation"]; -}' > output/trust-network.dot - -echo "Web of Trust created for BWHacker with 3 independent peer endorsements" - -``` - -Now, let's cryptographically verify the endorsement signatures: - -👉 -```sh -echo -e "\nCryptographically verifying peer endorsement signatures..." - -CARLOS_PUBLIC=$(cat endorsers/carlos-key.public) -if envelope verify -v "$CARLOS_PUBLIC" "$COLLABORATION"; then - echo "✅ Carlos's project collaboration endorsement verified" -else - echo "❌ Carlos's endorsement verification failed" -fi - -MAYA_PUBLIC=$(cat endorsers/maya-key.public) -if envelope verify -v "$MAYA_PUBLIC" "$CODE_REVIEW"; then - echo "✅ Maya's code review endorsement verified" -else - echo "❌ Maya's endorsement verification failed" -fi - -PRIYA_PUBLIC=$(cat endorsers/priya-key.public) -if envelope verify -v "$PRIYA_PUBLIC" "$SKILL_ASSESSMENT"; then - echo "✅ Priya's skill assessment endorsement signature verified" -else - echo "❌ Priya's endorsement signature verification failed" -fi - -echo -e "\nAll peer endorsement signatures successfully verified!" -``` - -🔍 -```console -Web of Trust created for BWHacker with 3 independent peer endorsements - -Verifying peer endorsements... -✅ Carlos's project collaboration endorsement verified -✅ Maya's code review endorsement verified -✅ Priya's skill verification endorsement verified - -All peer endorsements successfully verified! -``` - -This verification process demonstrates how the endorsements form a web of trust around BWHacker, with each endorsement independently verifiable. - -## 7. Selective Disclosure of Endorsements for Different Contexts - -Just like with self-attestations, Amira may want to selectively disclose endorsements for different situations using elision techniques. This leverages the powerful cryptographic capabilities described in [Elision Cryptography](../concepts/elision-cryptography.md), which explains how hash-based structures allow for selective disclosure while maintaining cryptographic verification. - -Let's create a technical skills view that only includes skill-related endorsements. The elision process replaces other endorsements with their cryptographic hashes, preserving signature validity while only showing selected content. - -👉 -```sh -TECHNICAL_VIEW=$(envelope elide assertion predicate string "peerEndorsement" "$XID_DOC" 2) -TECHNICAL_VIEW=$(envelope assertion add pred-obj string "peerEndorsement" envelope "$SKILL_ASSESSMENT" "$TECHNICAL_VIEW") -echo "$TECHNICAL_VIEW" > output/skills-endorsement-view.envelope -``` - -Now, let's create a project collaboration view: - -👉 -```sh -COLLABORATION_VIEW=$(envelope elide assertion predicate string "peerEndorsement" "$XID_DOC" 3) -COLLABORATION_VIEW=$(envelope assertion add pred-obj string "peerEndorsement" envelope "$COLLABORATION" "$COLLABORATION_VIEW") -echo "$COLLABORATION_VIEW" > output/collaboration-endorsement-view.envelope -``` - -Let's create a code quality view: - -👉 -```sh -CODE_QUALITY_VIEW=$(envelope elide assertion predicate string "peerEndorsement" "$XID_DOC" 3) -CODE_QUALITY_VIEW=$(envelope assertion add pred-obj string "peerEndorsement" envelope "$CODE_REVIEW" "$CODE_QUALITY_VIEW") -echo "$CODE_QUALITY_VIEW" > output/code-quality-endorsement-view.envelope -``` - -Finally, let's compare the sizes of the different views: - -👉 -```sh -echo "Size comparison of different endorsement views:" -echo "Full XID with all endorsements: $(echo "$XID_DOC" | wc -c) bytes" -echo "Technical skills view: $(echo "$TECHNICAL_VIEW" | wc -c) bytes" -echo "Collaboration view: $(echo "$COLLABORATION_VIEW" | wc -c) bytes" -echo "Code quality view: $(echo "$CODE_QUALITY_VIEW" | wc -c) bytes" -``` - -🔍 -```console -Size comparison of different endorsement views: -Full XID with all endorsements: 8735 bytes -Technical skills view: 5632 bytes -Collaboration view: 5841 bytes -Code quality view: 5729 bytes -``` - -These different views allow BWHacker to share the most relevant endorsements for specific contexts while maintaining the cryptographic verifiability of each. - -## 8. BWHacker Creating Endorsements for Others - -Just as others have endorsed BWHacker, they can also endorse other pseudonymous identities: - -Let's create another developer to endorse: - -👉 -```sh -envelope generate prvkeys > endorsers/dev-key.private -DEV_PRIVATE=$(cat endorsers/dev-key.private) -DEV_PUBLIC=$(envelope generate pubkeys "$DEV_PRIVATE") -echo "$DEV_PUBLIC" > endorsers/dev-key.public -``` - -Now, let's create the developer's XID: - -👉 -```sh -DEV_XID=$(envelope xid new --name "PrivacyDev" "$DEV_PUBLIC") -DEV_XID=$(envelope assertion add pred-obj string "gitHubUsername" string "PrivacyDev" "$DEV_XID") -DEV_XID=$(envelope assertion add pred-obj string "domain" string "Privacy Engineering & UX Design" "$DEV_XID") -echo "$DEV_XID" > endorsers/dev-xid.envelope -DEV_XID_ID=$(envelope xid id "$DEV_XID") - -``` - -Now, let's have BWHacker create an endorsement for PrivacyDev: - -👉 -```sh -BWHACKER_PRIVATE=$(cat output/bwhacker-key.private) -BW_ENDORSEMENT=$(envelope subject type string "Endorsement: Collaborative Development Work") -``` - -Let's identify the endorser and relationship: - -👉 -```sh -BW_ENDORSEMENT=$(envelope assertion add pred-obj string "endorser" string "BWHacker - Security specialist with 8 years experience" "$BW_ENDORSEMENT") -BW_ENDORSEMENT=$(envelope assertion add pred-obj string "relationship" string "Collaborated as peers on privacy authentication library for 4 months" "$BW_ENDORSEMENT") -BW_ENDORSEMENT=$(envelope assertion add pred-obj string "endorsementTarget" string "$DEV_XID_ID" "$BW_ENDORSEMENT") -``` - -Now, let's add specific observations: - -👉 -```sh -BW_ENDORSEMENT=$(envelope assertion add pred-obj string "projectReference" string "Privacy-First Authentication Library" "$BW_ENDORSEMENT") -BW_ENDORSEMENT=$(envelope assertion add pred-obj string "observation" string "PrivacyDev demonstrated exceptional skill in cryptographic implementation and API design" "$BW_ENDORSEMENT") -BW_ENDORSEMENT=$(envelope assertion add pred-obj string "specificContributions" string "Implemented novel zero-knowledge protocol optimization, reduced computational overhead by 40%" "$BW_ENDORSEMENT") -``` - -Let's add fair witness principles: - -👉 -```sh -BW_ENDORSEMENT=$(envelope assertion add pred-obj string "basis" string "Direct collaboration on codebase with code review and pair programming" "$BW_ENDORSEMENT") -BW_ENDORSEMENT=$(envelope assertion add pred-obj string "observationPeriod" string "January through April 2023" "$BW_ENDORSEMENT") -BW_ENDORSEMENT=$(envelope assertion add pred-obj string "endorserLimitation" string "Limited exposure to PrivacyDev's frontend work" "$BW_ENDORSEMENT") -BW_ENDORSEMENT=$(envelope assertion add pred-obj string "potentialBias" string "Shared research interest in privacy-preserving systems" "$BW_ENDORSEMENT") -``` - -Finally, let's wrap and sign the endorsement: - -👉 -```sh -WRAPPED_BW_ENDORSEMENT=$(envelope subject type wrapped "$BW_ENDORSEMENT") - -SIGNED_BW_ENDORSEMENT=$(envelope sign -s "$AMIRA_PRIVATE" "$WRAPPED_BW_ENDORSEMENT") -echo "$SIGNED_BW_ENDORSEMENT" > output/bwhacker-endorsement-of-dev.envelope -``` - -Now, let's add this to PrivacyDev's XID: - -👉 -```sh -DEV_XID_UPDATED=$(envelope assertion add pred-obj string "receivedEndorsement" envelope "$SIGNED_BW_ENDORSEMENT" "$DEV_XID") -echo "$DEV_XID_UPDATED" > endorsers/dev-xid-with-endorsement.envelope - -echo "BWHacker has created an endorsement for PrivacyDev:" -envelope format --type tree "$SIGNED_BW_ENDORSEMENT" | head -10 -echo "..." -``` - -🔍 -```console -BWHacker has created an endorsement for PrivacyDev: -"Endorsement: Collaborative Development Work" [ - "endorser": "BWHacker - Security specialist with 8 years experience" - "relationship": "Collaborated as peers on privacy authentication library for 4 months" - "endorsementTarget": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" - "projectReference": "Privacy-First Authentication Library" - "observation": "PrivacyDev demonstrated exceptional skill in cryptographic implementation and API design" - "specificContributions": "Implemented novel zero-knowledge protocol optimization, reduced computational overhead by 40%" - "basis": "Direct collaboration on codebase with code review and pair programming" - "observationPeriod": "January through April 2023" - ... -``` - -This demonstrates how endorsements can flow in multiple directions, creating a true web of pseudonymous trust where identity verification occurs without revealing real-world identities. - -## Understanding Progression Through Trust Levels - -Through this process, BWHacker's pseudonymous identity has progressed through several trust levels aligned with the progressive trust life cycle: - -👉 -```sh -TRUST_PROGRESSION=$(envelope subject type string "BWHacker's Trust Level Progression") - -INITIAL_LEVEL=$(envelope subject type string "Initial Contributor") -INITIAL_LEVEL=$(envelope assertion add pred-obj string "status" string "Completed" "$INITIAL_LEVEL") -INITIAL_LEVEL=$(envelope assertion add pred-obj string "attestations" string "Basic XID with self-declarations" "$INITIAL_LEVEL") -INITIAL_LEVEL=$(envelope assertion add pred-obj string "verification" string "Cryptographic control of keys" "$INITIAL_LEVEL") -TRUST_PROGRESSION=$(envelope assertion add pred-obj string "trustLevel" envelope "$INITIAL_LEVEL" "$TRUST_PROGRESSION") - -REGULAR_LEVEL=$(envelope subject type string "Regular Contributor") -REGULAR_LEVEL=$(envelope assertion add pred-obj string "status" string "Completed" "$REGULAR_LEVEL") -REGULAR_LEVEL=$(envelope assertion add pred-obj string "attestations" string "Skill framework with evidence commitments" "$REGULAR_LEVEL") -REGULAR_LEVEL=$(envelope assertion add pred-obj string "verification" string "Self-attestations with cryptographic commitments" "$REGULAR_LEVEL") -TRUST_PROGRESSION=$(envelope assertion add pred-obj string "trustLevel" envelope "$REGULAR_LEVEL" "$TRUST_PROGRESSION") - -TRUSTED_LEVEL=$(envelope subject type string "Trusted Contributor") -TRUSTED_LEVEL=$(envelope assertion add pred-obj string "status" string "Completed" "$TRUSTED_LEVEL") -TRUSTED_LEVEL=$(envelope assertion add pred-obj string "attestations" string "Multiple peer endorsements from different contexts" "$TRUSTED_LEVEL") -TRUSTED_LEVEL=$(envelope assertion add pred-obj string "verification" string "Independent verification by multiple endorsers" "$TRUSTED_LEVEL") -TRUST_PROGRESSION=$(envelope assertion add pred-obj string "trustLevel" envelope "$TRUSTED_LEVEL" "$TRUST_PROGRESSION") - -CORE_LEVEL=$(envelope subject type string "Core Contributor") -CORE_LEVEL=$(envelope assertion add pred-obj string "status" string "In Progress" "$CORE_LEVEL") -CORE_LEVEL=$(envelope assertion add pred-obj string "attestations" string "Project leadership endorsements required" "$CORE_LEVEL") -CORE_LEVEL=$(envelope assertion add pred-obj string "nextSteps" string "Multi-party verification from project governance" "$CORE_LEVEL") -TRUST_PROGRESSION=$(envelope assertion add pred-obj string "trustLevel" envelope "$CORE_LEVEL" "$TRUST_PROGRESSION") - -echo "$TRUST_PROGRESSION" > output/trust-progression.envelope -echo "Trust Level Progression:" -envelope format --type tree "$TRUST_PROGRESSION" -``` - -🔍 -```console -"BWHacker's Trust Level Progression" [ - "trustLevel": "Initial Contributor" [ - "status": "Completed" - "attestations": "Basic XID with self-declarations" - "verification": "Cryptographic control of keys" - ] - "trustLevel": "Regular Contributor" [ - "status": "Completed" - "attestations": "Skill framework with evidence commitments" - "verification": "Self-attestations with cryptographic commitments" - ] - "trustLevel": "Trusted Contributor" [ - "status": "Completed" - "attestations": "Multiple peer endorsements from different contexts" - "verification": "Independent verification by multiple endorsers" - ] - "trustLevel": "Core Contributor" [ - "status": "In Progress" - "attestations": "Project leadership endorsements required" - "nextSteps": "Multi-party verification from project governance" - ] -] -``` - -This trust progression shows how Amira has moved from being an unknown pseudonymous contributor to a trusted member of the community through a structured process of increasing attestations and verification. - -## Understanding the Power of Peer Endorsements - -Through this tutorial, we've seen how peer endorsements significantly strengthen BWHacker's pseudonymous identity: - -1. **Independent Verification**: Third parties have independently verified specific skills and contributions. - -2. **Context-Rich Assessment**: Each endorsement provides rich context about what was verified, how, and any limitations. - -3. **Diverse Perspectives**: Different endorsers with varied expertise evaluate different aspects of BWHacker's capabilities. - -4. **Pseudonymous Credibility**: Trust is established without revealing anyone's real identity. - -5. **Verifiable Chain**: Each endorsement is cryptographically signed and verifiable against the endorser's public key. - -6. **Web of Trust**: Multiple endorsements create a network of verification that strengthens BWHacker's claims. - -7. **Selective Disclosure**: BWHacker can share different endorsements based on the specific context. - -8. **Progressive Trust Building**: Through structured attestations and endorsements, BWHacker moves through clear trust levels from Initial to Trusted Contributor. - -This rich web of peer endorsements transforms BWHacker from a self-attested identity to a community-verified presence with substantial credibility. - -### Theory to Practice: Building a Verifiable Trust Network - -The peer endorsement system you've implemented demonstrates how cryptographic identities can support social trust mechanisms: - -1. **Web of Trust Architecture**: By connecting multiple independent XIDs through endorsements, you've implemented a **decentralized trust network**. Unlike centralized reputation systems, this web of trust derives its credibility from the connections between identities rather than a single authoritative source. - > **Historical Context**: This model builds on the web of trust concept first implemented in PGP in the 1990s, but enhances it with structured attestations, contextual information, and explicit relationship disclosure. - -2. **Proof Basis in Endorsements**: Each endorsement includes a clear **proof basis** - the foundation for the endorser's claims. Maya's code review endorsement explicitly states the specific code she reviewed, while Carlos documents the specific collaboration experiences that form the basis of his endorsement. - > **Why this matters**: Without a clear proof basis, endorsements become vague character references rather than specific, verifiable claims. The proof basis allows others to evaluate the endorser's knowledge and authority. - -3. **Relationship Context Disclosure**: The endorsements properly implement **relationship transparency** by documenting how the endorser knows BWHacker and the context of their professional relationship, providing critical context for evaluating the endorsement's significance. - > **ANTI-PATTERN**: Many recommendation systems don't require relationship disclosure, leading to situations where close friends or family members provide seemingly independent endorsements without revealing their connection. - -4. **Trust Amplification**: When Maya's code review endorsement is combined with Priya's skill assessment, it creates **trust amplification** through multiple independent verifications. This implements the principle that trust is strengthened when confirmed from different perspectives and contexts. - > **Real-World Analogy**: This is similar to how multiple independent product reviews create more confidence than a single review, especially when they come from reviewers with different expertise and perspectives. - -5. **Endorsement Acceptance Model**: The process follows the proper **endorsement lifecycle** - where endorsements are created by peers, reviewed by the recipient, and then accepted into their trust framework, giving the recipient control over what endorsements become part of their identity. - -6. **Contextual Disclosure of Endorsements**: The elided views of endorsements implement **context-sensitive information sharing**, allowing BWHacker to present different aspects of her endorsed capabilities to different audiences without revealing her entire trust network. - -7. **Trust Network Visualization**: The graph visualization you created demonstrates **trust relationship mapping**, making abstract trust connections concrete and helping understand how reputation flows through the network. - -These social trust mechanisms transform individual XIDs from isolated identities into a rich ecosystem where reputation and trust can flow while still preserving the pseudonymous nature of the identities involved. - -## Next Steps - -In the next tutorial, we'll explore how BWHacker can evolve their XID over time, managing key rotation, updating assertions, and building a long-term pseudonymous presence that maintains continuity while adapting to changing needs. - -To build on what you've learned about peer endorsements, check out [Public Participation Profiles](../concepts/public-participation-profiles.md) for a comprehensive framework on balancing privacy with trust-building. For practical examples of how different peer endorsements can be structured for various contexts and trust levels, see the [Public Participation Profile Examples](../concepts/public-participation-profile-examples.md) document, which includes detailed examples aligned with BWHacker's women's safety app contributions. - -## Exercises - -1. Create your own endorser XID and make an endorsement about a technical skill. - -2. Design an endorsement format for academic peer review or creative work evaluation. - -3. Create a multi-level endorsement that combines direct experience, code review, and reputation assessment. - -4. Build a visualization of a more complex trust network with endorsements in both directions. - -5. Design a system for endorsement verification that doesn't require direct access to the endorser's XID. - -## Example Scripts - -This tutorial has an accompanying script in the `examples/04-peer-endorsement` directory: - -**`create_peer_endorsements.sh`**: Implements the peer endorsement framework shown in this tutorial, including creating endorser XIDs, generating different types of endorsements, and verifying their signatures. - -The script demonstrates all the key concepts: -- Creating XIDs for endorsers with their own key pairs -- Building different types of endorsements (collaboration, code review, skill assessment) -- Signing endorsements with appropriate keys -- Adding endorsements to BWHacker's XID -- Verifying endorsement signatures -- Creating selective disclosure views for different contexts diff --git a/tutorials/05-key-management-with-xids.md b/tutorials/05-key-management-with-xids.md deleted file mode 100644 index 4726105..0000000 --- a/tutorials/05-key-management-with-xids.md +++ /dev/null @@ -1,648 +0,0 @@ -# Key Management with Pseudonymous XIDs - -This tutorial demonstrates how Amira manages cryptographic keys for her "BWHacker" pseudonymous identity. You'll learn how to create a trust-based key hierarchy, implement secure key rotation, and establish recovery procedures - all while maintaining pseudonymity and supporting progressive trust development. - -**Time to complete: 30-40 minutes** - -> **Related Concepts**: Before or after completing this tutorial, you may want to read about [Key Management Essentials](../concepts/key-management-essentials.md) to understand the theoretical foundations behind secure key management for XIDs. - -## Prerequisites - -- Completed the first four XID tutorials -- The envelope CLI tool installed -- BWHacker's XID with self-attestations and endorsements from the previous tutorials -- Basic understanding of cryptographic key concepts - -## What You'll Learn - -- How to manage keys without compromising pseudonymity -- How to create a trust-based key hierarchy for different contexts -- How to implement key rotation as both a security and privacy enhancement -- How to establish recovery mechanisms that preserve pseudonymous identity -- How to create progressive permission models aligned with trust relationships -- How to apply fair witnessing principles to key management decisions - -## Amira's Challenge: Managing Keys for Pseudonymous Trust - -After establishing her "BWHacker" identity and building trust through self-attestations and peer endorsements, Amira now faces a new challenge. She needs a comprehensive key management strategy that will: - -1. Allow her to use different devices securely without compromising her pseudonymity -2. Support different trust relationships with varying levels of disclosure -3. Protect against potential compromise without losing her established identity -4. Maintain transparency in her key management without revealing her real identity -5. Enable progressive trust development with new collaborators - -The way she manages her keys must align with her existing trust framework while enhancing both security and privacy. - -## 1. Foundations of Pseudonymous Key Management - -Let's start by examining BWHacker's current XID from the previous tutorial: - -👉 -```sh -mkdir -p output -XID_DOC=$(cat output/bwhacker-with-endorsements.envelope) -echo "BWHacker's XID identifier:" -envelope xid id "$XID_DOC" -``` - -🔍 -```console -BWHacker's XID identifier: -7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3 -``` - -Let's review BWHacker's current keys: - -👉 -```sh -echo "Current keys in BWHacker's XID:" -KEYS=$(envelope xid key all "$XID_DOC") -echo "$KEYS" -``` - -🔍 -```console -ur:crypto-pubkeys/hdcxlkadjnghfejtmyyloeadmyfqzswdaeayfnmddpjygtmyaeaelytsqdisaeaeaeae -ur:crypto-pubkeys/hdcxaeluhhfymwfldptadtfehsbeiyoschktwzmeticyaasrrfbyatjtcmzsbnsgtszo -``` - -Before adding more keys, let's create a key management policy document that will guide BWHacker's key usage while preserving her pseudonymity: - -👉 -```sh -KEY_POLICY=$(envelope subject type string "BWHacker Key Management Policy") -KEY_POLICY=$(envelope assertion add pred-obj string "purpose" string "Manage cryptographic keys while maintaining pseudonymity" "$KEY_POLICY") -KEY_POLICY=$(envelope assertion add pred-obj string "created" string "$(date +%Y-%m-%d)" "$KEY_POLICY") -KEY_POLICY=$(envelope assertion add pred-obj string "principle" string "Different keys for different trust contexts" "$KEY_POLICY") -KEY_POLICY=$(envelope assertion add pred-obj string "principle" string "Least privilege for each key" "$KEY_POLICY") -KEY_POLICY=$(envelope assertion add pred-obj string "principle" string "Recovery procedures that don't expose identity" "$KEY_POLICY") -KEY_POLICY=$(envelope assertion add pred-obj string "rotationPolicy" string "Regular rotation for active keys, immediate rotation for suspected compromise" "$KEY_POLICY") - -echo "$KEY_POLICY" > output/bwhacker-key-policy.envelope -``` - -This policy will help BWHacker maintain consistent key management practices aligned with her pseudonymous identity needs. - -## 2. Creating a Trust-Based Key Hierarchy - -Now, let's create a key hierarchy that aligns with BWHacker's trust framework. We'll define keys for different purposes and contexts: - -### Primary Identity Key - -First, let's clearly label the existing primary key: - -👉 -```sh -PRIMARY_KEY=$(cat output/bwhacker-key.public) -UPDATED_XID=$(envelope xid key rename "$PRIMARY_KEY" "BWHacker Primary Identity" "$XID_DOC") -echo "$UPDATED_XID" > output/bwhacker-updated.envelope -``` - -### Project-Specific Key - -Now, let's create a key specifically for the API security project BWHacker is joining: - -👉 -```sh -PROJECT_KEY_PRIVATE=$(envelope generate prvkeys) -echo "$PROJECT_KEY_PRIVATE" > output/project-key.private -PROJECT_KEY_PUBLIC=$(envelope generate pubkeys "$PROJECT_KEY_PRIVATE") -echo "$PROJECT_KEY_PUBLIC" > output/project-key.public - -UPDATED_XID=$(envelope xid key add --name "API Security Project" --allow sign --allow encrypt "$PROJECT_KEY_PUBLIC" "$UPDATED_XID") -echo "$UPDATED_XID" > output/bwhacker-updated.envelope -``` - -By limiting this key to only sign and encrypt (not manage other keys), BWHacker implements least privilege principles. - -### Evidence Commitment Key - -For managing evidence commitments from Tutorial #3, let's create a specialized key: - -👉 -```sh -EVIDENCE_KEY_PRIVATE=$(envelope generate prvkeys) -echo "$EVIDENCE_KEY_PRIVATE" > output/evidence-key.private -EVIDENCE_KEY_PUBLIC=$(envelope generate pubkeys "$EVIDENCE_KEY_PRIVATE") -echo "$EVIDENCE_KEY_PUBLIC" > output/evidence-key.public - -UPDATED_XID=$(envelope xid key add --name "Evidence Commitment Key" --allow sign "$EVIDENCE_KEY_PUBLIC" "$UPDATED_XID") -echo "$UPDATED_XID" > output/bwhacker-updated.envelope -``` - -This key will only be used for signing evidence commitments, further compartmentalizing BWHacker's cryptographic activities. - -### Endorsement Signing Key - -Let's create a dedicated key for signing endorsements of other people's work: - -👉 -```sh -ENDORSE_KEY_PRIVATE=$(envelope generate prvkeys) -echo "$ENDORSE_KEY_PRIVATE" > output/endorsement-key.private -ENDORSE_KEY_PUBLIC=$(envelope generate pubkeys "$ENDORSE_KEY_PRIVATE") -echo "$ENDORSE_KEY_PUBLIC" > output/endorsement-key.public - -UPDATED_XID=$(envelope xid key add --name "Endorsement Signing Key" --allow sign "$ENDORSE_KEY_PUBLIC" "$UPDATED_XID") -echo "$UPDATED_XID" > output/bwhacker-updated.envelope -``` - -This dedicated key makes it clear when BWHacker is endorsing others' work. - -### Recovery Key (For Emergency Use Only) - -Let's create a recovery key with extremely limited permissions, to be stored securely offline: - -👉 -```sh -RECOVERY_KEY_PRIVATE=$(envelope generate prvkeys) -echo "$RECOVERY_KEY_PRIVATE" > output/recovery-key.private -RECOVERY_KEY_PUBLIC=$(envelope generate pubkeys "$RECOVERY_KEY_PRIVATE") -echo "$RECOVERY_KEY_PUBLIC" > output/recovery-key.public - -UPDATED_XID=$(envelope xid key add --name "Recovery Key" --allow update --allow elect "$RECOVERY_KEY_PUBLIC" "$UPDATED_XID") -echo "$UPDATED_XID" > output/bwhacker-updated.envelope -``` - -This recovery key can only update endpoints and manage other keys, not sign or encrypt as BWHacker. - -### Reviewing Our Key Hierarchy - -Let's see all the keys we've added: - -👉 -```sh -echo "BWHacker's key hierarchy:" -envelope xid key all "$UPDATED_XID" -``` - -🔍 -```console -ur:crypto-pubkeys/hdcxlkadjnghfejtmyyloeadmyfqzswdaeayfnmddpjygtmyaeaelytsqdisaeaeaeae -ur:crypto-pubkeys/hdcxaeluhhfymwfldptadtfehsbeiyoschktwzmeticyaasrrfbyatjtcmzsbnsgtszo -ur:crypto-pubkeys/hdcxbylyrtjohsmtaeaeaeaeaeaeaeaeaximutmudaahaeaeaeaeaeaeaeaeaeaegscecpck -ur:crypto-pubkeys/hdcxiocmvazesectrfbaidaddaadaeaeaekoiodlvskptimoeowdpfiegrfwoylkatkemh -ur:crypto-pubkeys/hdcxftghvabdvskpoybssbkbcsaodmdsiezsfdknflkidylgrpmomeptgwchcprsueae -ur:crypto-pubkeys/hdcxpkiyflvsbyidfsaeaeaeaeaecnurdyzmchinlkcpdmaxgubsdridonnyhdmomtmsba -``` - -Let's also check key names and permissions: - -👉 -```sh -echo "Key details and permissions:" -for KEY in $(envelope xid key all "$UPDATED_XID"); do - NAME=$(envelope xid key name "$KEY" "$UPDATED_XID" 2>/dev/null || echo "Unnamed key") - PERMS=$(envelope xid key permissions "$KEY" "$UPDATED_XID") - echo "- $NAME: $PERMS" -done -``` - -🔍 -```console -- BWHacker Primary Identity: all -- Tablet Key: sign -- API Security Project: sign encrypt -- Evidence Commitment Key: sign -- Endorsement Signing Key: sign -- Recovery Key: update elect -``` - -This structured approach provides BWHacker with the right keys for each purpose while minimizing risk through appropriate permission boundaries. - -## 3. Key Rotation as a Privacy Enhancement - -Key rotation is essential for both security and privacy. Let's demonstrate how BWHacker can rotate a key while maintaining her pseudonymous identity. - -First, let's document the reason for rotation following fair witnessing principles: - -👉 -```sh -ROTATION_RECORD=$(envelope subject type string "Key Rotation Record") -ROTATION_RECORD=$(envelope assertion add pred-obj string "date" string "$(date +%Y-%m-%d)" "$ROTATION_RECORD") -ROTATION_RECORD=$(envelope assertion add pred-obj string "keyName" string "Tablet Key" "$ROTATION_RECORD") -ROTATION_RECORD=$(envelope assertion add pred-obj string "reason" string "Suspected device tampering at public cafe" "$ROTATION_RECORD") -ROTATION_RECORD=$(envelope assertion add pred-obj string "observation" string "Device left unattended for approximately 3 minutes" "$ROTATION_RECORD") -ROTATION_RECORD=$(envelope assertion add pred-obj string "action" string "Preventative key rotation and device reset" "$ROTATION_RECORD") -ROTATION_RECORD=$(envelope assertion add pred-obj string "methodology" string "Complete replacement with new key material" "$ROTATION_RECORD") - -echo "$ROTATION_RECORD" > output/key-rotation-record.envelope -``` - -Now let's generate a new tablet key: - -👉 -```sh -NEW_TABLET_KEY_PRIVATE=$(envelope generate prvkeys) -echo "$NEW_TABLET_KEY_PRIVATE" > output/new-tablet-key.private -NEW_TABLET_KEY_PUBLIC=$(envelope generate pubkeys "$NEW_TABLET_KEY_PRIVATE") -echo "$NEW_TABLET_KEY_PUBLIC" > output/new-tablet-key.public -``` - -Remove the old tablet key and add the new one: - -👉 -```sh -TABLET_KEY=$(envelope xid key find "Tablet Key" "$UPDATED_XID") -ROTATED_XID=$(envelope xid key remove "$TABLET_KEY" "$UPDATED_XID") -ROTATED_XID=$(envelope xid key add --name "Tablet Key (Rotated)" --allow sign "$NEW_TABLET_KEY_PUBLIC" "$ROTATED_XID") -echo "$ROTATED_XID" > output/bwhacker-rotated.envelope -``` - -Let's verify that BWHacker's identity remains stable despite this key change: - -👉 -```sh -ORIGINAL_ID=$(envelope xid id "$XID_DOC") -ROTATED_ID=$(envelope xid id "$ROTATED_XID") -echo "Original XID: $ORIGINAL_ID" -echo "After rotation: $ROTATED_ID" -``` - -🔍 -```console -Original XID: 7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3 -After rotation: 7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3 -``` - -👉 -```sh -if [ "$ORIGINAL_ID" = "$ROTATED_ID" ]; then - echo "✅ BWHacker's identity remained stable through key rotation" -else - echo "❌ Identity changed during rotation (unexpected)" -fi -``` - -🔍 -```console -✅ BWHacker's identity remained stable through key rotation -``` - -To inform collaborators about the key rotation in a transparent way: - -👉 -```sh -NOTIFICATION=$(envelope subject type string "Key Rotation Notification") -NOTIFICATION=$(envelope assertion add pred-obj string "date" string "$(date +%Y-%m-%d)" "$NOTIFICATION") -NOTIFICATION=$(envelope assertion add pred-obj string "keyChanged" string "Tablet Key" "$NOTIFICATION") -NOTIFICATION=$(envelope assertion add pred-obj string "rotationRecord" envelope "$ROTATION_RECORD" "$NOTIFICATION") -NOTIFICATION=$(envelope assertion add pred-obj string "verificationInstructions" string "Update your contacts with the new public key" "$NOTIFICATION") - -PRIMARY_KEY_PRIVATE=$(cat output/bwhacker-key.private) - -WRAPPED_NOTIFICATION=$(envelope subject type wrapped "$NOTIFICATION") - -SIGNED_NOTIFICATION=$(envelope sign -s "$PRIMARY_KEY_PRIVATE" "$WRAPPED_NOTIFICATION") -echo "$SIGNED_NOTIFICATION" > output/key-rotation-notification.envelope -``` - -This notification could be shared with collaborators so they can update their verification procedures, while the transparent explanation builds trust through adherence to fair witnessing principles. - -## 4. Recovery Without Identity Exposure - -Let's prepare for a worst-case scenario: what if BWHacker loses access to her primary key? We need a recovery process that doesn't compromise her pseudonymity. - -First, let's establish a social recovery approach by creating a trusted peer XID: - -👉 -```sh -PEER_KEYS_PRIVATE=$(envelope generate prvkeys) -echo "$PEER_KEYS_PRIVATE" > output/trusted-peer.private -PEER_KEYS_PUBLIC=$(envelope generate pubkeys "$PEER_KEYS_PRIVATE") -echo "$PEER_KEYS_PUBLIC" > output/trusted-peer.public - -PEER_XID=$(envelope xid new --name "TrustedPeer" "$PEER_KEYS_PUBLIC") -echo "$PEER_XID" > output/trusted-peer.envelope -``` - -Now, let's create a recovery attestation signed by this peer: - -👉 -```sh -RECOVERY_ATTESTATION=$(envelope subject type string "Recovery Authorization") -RECOVERY_ATTESTATION=$(envelope assertion add pred-obj string "regarding" string "$ORIGINAL_ID" "$RECOVERY_ATTESTATION") -RECOVERY_ATTESTATION=$(envelope assertion add pred-obj string "recoveryKey" digest "$RECOVERY_KEY_PUBLIC" "$RECOVERY_ATTESTATION") -RECOVERY_ATTESTATION=$(envelope assertion add pred-obj string "validFrom" string "$(date +%Y-%m-%d)" "$RECOVERY_ATTESTATION") -RECOVERY_ATTESTATION=$(envelope assertion add pred-obj string "validUntil" string "$(date -d "+6 months" +%Y-%m-%d 2>/dev/null || date -v+6m +%Y-%m-%d)" "$RECOVERY_ATTESTATION") -RECOVERY_ATTESTATION=$(envelope assertion add pred-obj string "limitations" string "One-time use for primary key recovery only" "$RECOVERY_ATTESTATION") -RECOVERY_ATTESTATION=$(envelope assertion add pred-obj string "verificationMethod" string "In-person confirmation with pre-established challenges" "$RECOVERY_ATTESTATION") -RECOVERY_ATTESTATION=$(envelope assertion add pred-obj string "observer" string "Collaborator since 2022, 3 joint projects completed" "$RECOVERY_ATTESTATION") - -WRAPPED_RECOVERY_ATTESTATION=$(envelope subject type wrapped "$RECOVERY_ATTESTATION") - -SIGNED_RECOVERY_ATTESTATION=$(envelope sign -s "$PEER_KEYS_PRIVATE" "$WRAPPED_RECOVERY_ATTESTATION") -echo "$SIGNED_RECOVERY_ATTESTATION" > output/recovery-attestation.envelope -``` - -Now, let's simulate a recovery where BWHacker has lost her primary key but still has her recovery key: - -👉 -```sh -echo "Simulating primary key loss and recovery process..." - -NEW_PRIMARY_KEY_PRIVATE=$(envelope generate prvkeys) -echo "$NEW_PRIMARY_KEY_PRIVATE" > output/new-primary-key.private -NEW_PRIMARY_KEY_PUBLIC=$(envelope generate pubkeys "$NEW_PRIMARY_KEY_PRIVATE") -echo "$NEW_PRIMARY_KEY_PUBLIC" > output/new-primary-key.public - -RECOVERY_KEY_PRIVATE=$(cat output/recovery-key.private) -PRIMARY_KEY=$(cat output/bwhacker-key.public) - -RECOVERY_RECORD=$(envelope subject type string "Key Recovery Record") -RECOVERY_RECORD=$(envelope assertion add pred-obj string "date" string "$(date +%Y-%m-%d)" "$RECOVERY_RECORD") -RECOVERY_RECORD=$(envelope assertion add pred-obj string "action" string "Recovery of primary identity key" "$RECOVERY_RECORD") -RECOVERY_RECORD=$(envelope assertion add pred-obj string "methodology" string "Social recovery with peer attestation verification" "$RECOVERY_RECORD") -RECOVERY_RECORD=$(envelope assertion add pred-obj string "verificationMethod" string "Cross-referenced with existing attestations in BWHacker's trust framework" "$RECOVERY_RECORD") -RECOVERY_RECORD=$(envelope assertion add pred-obj string "peerAttestation" envelope "$SIGNED_RECOVERY_ATTESTATION" "$RECOVERY_RECORD") - -WRAPPED_RECOVERY_RECORD=$(envelope subject type wrapped "$RECOVERY_RECORD") - -SIGNED_RECOVERY_RECORD=$(envelope sign -s "$RECOVERY_KEY_PRIVATE" "$WRAPPED_RECOVERY_RECORD") -echo "$SIGNED_RECOVERY_RECORD" > output/recovery-record.envelope - -RECOVERED_XID=$(envelope xid key remove "$PRIMARY_KEY" "$ROTATED_XID") -RECOVERED_XID=$(envelope xid key add --name "BWHacker Primary Identity (Recovered)" --allow all "$NEW_PRIMARY_KEY_PUBLIC" "$RECOVERED_XID") -echo "$RECOVERED_XID" > output/bwhacker-recovered.envelope -``` - -Verify that the XID remained stable through this recovery process: - -👉 -```sh -RECOVERED_ID=$(envelope xid id "$RECOVERED_XID") -echo "Original XID: $ORIGINAL_ID" -echo "After recovery: $RECOVERED_ID" -``` - -🔍 -```console -Original XID: 7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3 -After recovery: 7e1e25d7c4b9e4c92753f4476158e972be2fbbd9dffdd13b0561b5f1177826d3 -``` - -👉 -```sh -if [ "$ORIGINAL_ID" = "$RECOVERED_ID" ]; then - echo "✅ BWHacker's identity remained stable through recovery process" -else - echo "❌ Identity changed during recovery (unexpected)" -fi -``` - -🔍 -```console -✅ BWHacker's identity remained stable through recovery process -``` - -This recovery mechanism maintains BWHacker's pseudonymous identity while providing a secure way to recover from key loss. - -## 5. Progressive Permission Models - -As trust relationships evolve, key permissions may need to change. Let's demonstrate how BWHacker can implement a progressive permission model for a new collaborator relationship: - -First, let's create an initial collaboration key with minimal permissions: - -👉 -```sh -COLLAB_KEY_PRIVATE=$(envelope generate prvkeys) -echo "$COLLAB_KEY_PRIVATE" > output/collab-key.private -COLLAB_KEY_PUBLIC=$(envelope generate pubkeys "$COLLAB_KEY_PRIVATE") -echo "$COLLAB_KEY_PUBLIC" > output/collab-key.public - -UPDATED_XID=$(envelope xid key add --name "New Collaboration (Initial)" --allow encrypt "$COLLAB_KEY_PUBLIC" "$RECOVERED_XID") -echo "$UPDATED_XID" > output/bwhacker-updated2.envelope -``` - -This key initially only allows encryption, which means BWHacker can receive encrypted messages but not sign as BWHacker in this collaboration. - -Let's document the progressive permission plan: - -👉 -```sh -PERMISSION_PLAN=$(envelope subject type string "Progressive Permission Plan") -PERMISSION_PLAN=$(envelope assertion add pred-obj string "keyName" string "New Collaboration (Initial)" "$PERMISSION_PLAN") -PERMISSION_PLAN=$(envelope assertion add pred-obj string "initialPermissions" string "encrypt" "$PERMISSION_PLAN") -PERMISSION_PLAN=$(envelope assertion add pred-obj string "stage1Upgrade" string "After successful first deliverable: add sign permission" "$PERMISSION_PLAN") -PERMISSION_PLAN=$(envelope assertion add pred-obj string "stage2Upgrade" string "After 3 successful collaborations: add auth permission" "$PERMISSION_PLAN") -PERMISSION_PLAN=$(envelope assertion add pred-obj string "finalUpgrade" string "After 1 year of successful collaboration: full permissions" "$PERMISSION_PLAN") -PERMISSION_PLAN=$(envelope assertion add pred-obj string "rationale" string "Progressive trust development through demonstrated reliability" "$PERMISSION_PLAN") -PERMISSION_PLAN=$(envelope assertion add pred-obj string "documentation" string "Each upgrade will be documented with specific accomplishments" "$PERMISSION_PLAN") - -echo "$PERMISSION_PLAN" > output/permission-plan.envelope -``` - -Now, let's simulate the first permission upgrade after a successful deliverable: - -👉 -```sh -echo "Simulating permission upgrade after successful deliverable..." - -DELIVERABLE=$(envelope subject type string "Collaborative Deliverable") -DELIVERABLE=$(envelope assertion add pred-obj string "project" string "API Security Assessment" "$DELIVERABLE") -DELIVERABLE=$(envelope assertion add pred-obj string "date" string "$(date +%Y-%m-%d)" "$DELIVERABLE") -DELIVERABLE=$(envelope assertion add pred-obj string "outcome" string "Successfully completed initial security analysis" "$DELIVERABLE") -DELIVERABLE=$(envelope assertion add pred-obj string "contribution" string "BWHacker: security system design, vulnerability analysis; Collaborator: testing, documentation" "$DELIVERABLE") -DELIVERABLE=$(envelope assertion add pred-obj string "evaluationMethod" string "Peer review by project stakeholders" "$DELIVERABLE") -DELIVERABLE=$(envelope assertion add pred-obj string "evaluationResult" string "Exceeds expectations - methodology highly praised" "$DELIVERABLE") - -NEW_PRIMARY_KEY_PRIVATE=$(cat output/new-primary-key.private) - -WRAPPED_DELIVERABLE=$(envelope subject type wrapped "$DELIVERABLE") - -SIGNED_DELIVERABLE=$(envelope sign -s "$NEW_PRIMARY_KEY_PRIVATE" "$WRAPPED_DELIVERABLE") -echo "$SIGNED_DELIVERABLE" > output/successful-deliverable.envelope - -UPGRADE_RECORD=$(envelope subject type string "Permission Upgrade Record") -UPGRADE_RECORD=$(envelope assertion add pred-obj string "date" string "$(date +%Y-%m-%d)" "$UPGRADE_RECORD") -UPGRADE_RECORD=$(envelope assertion add pred-obj string "keyName" string "New Collaboration (Initial)" "$UPGRADE_RECORD") -UPGRADE_RECORD=$(envelope assertion add pred-obj string "newName" string "New Collaboration (Stage 1)" "$UPGRADE_RECORD") -UPGRADE_RECORD=$(envelope assertion add pred-obj string "addedPermissions" string "sign" "$UPGRADE_RECORD") -UPGRADE_RECORD=$(envelope assertion add pred-obj string "justification" envelope "$SIGNED_DELIVERABLE" "$UPGRADE_RECORD") -UPGRADE_RECORD=$(envelope assertion add pred-obj string "methodology" string "Evaluation against pre-established success criteria" "$UPGRADE_RECORD") -UPGRADE_RECORD=$(envelope assertion add pred-obj string "limitations" string "Sign permission limited to this specific collaboration" "$UPGRADE_RECORD") - -WRAPPED_UPGRADE_RECORD=$(envelope subject type wrapped "$UPGRADE_RECORD") - -SIGNED_UPGRADE_RECORD=$(envelope sign -s "$NEW_PRIMARY_KEY_PRIVATE" "$WRAPPED_UPGRADE_RECORD") -echo "$SIGNED_UPGRADE_RECORD" > output/permission-upgrade-record.envelope - -COLLAB_KEY=$(envelope xid key find "New Collaboration (Initial)" "$UPDATED_XID") - -PROGRESSIVE_XID=$(envelope xid key remove "$COLLAB_KEY" "$UPDATED_XID") - -PROGRESSIVE_XID=$(envelope xid key add --name "New Collaboration (Stage 1)" --allow encrypt --allow sign "$COLLAB_KEY_PUBLIC" "$PROGRESSIVE_XID") -echo "$PROGRESSIVE_XID" > output/bwhacker-progressive.envelope -``` - -Now let's verify the new permission structure: - -👉 -```sh -echo "Updated permission structure:" -for KEY in $(envelope xid key all "$PROGRESSIVE_XID"); do - NAME=$(envelope xid key name "$KEY" "$PROGRESSIVE_XID" 2>/dev/null || echo "Unnamed key") - PERMS=$(envelope xid key permissions "$KEY" "$PROGRESSIVE_XID") - echo "- $NAME: $PERMS" -done -``` - -🔍 -```console -- BWHacker Primary Identity (Recovered): all -- Tablet Key (Rotated): sign -- API Security Project: sign encrypt -- Evidence Commitment Key: sign -- Endorsement Signing Key: sign -- Recovery Key: update elect -- New Collaboration (Stage 1): sign encrypt -``` - -This progressive approach to permissions: -1. Aligns key privileges with demonstrated trust -2. Documents the basis for permission changes -3. Maintains fair witnessing principles with transparent evaluation -4. Preserves BWHacker's pseudonymity throughout the process - -## 6. Maintaining Endorsements Through Key Changes - -A crucial aspect of key management is ensuring that previously received endorsements remain valid even when keys change. Let's update one of the endorsements BWHacker received to work with her new key: - -👉 -```sh -PM_ENDORSEMENT=$(cat output/pm-endorsement.envelope) - -if envelope verify -v "$(cat output/greenpm-key.public)" "$PM_ENDORSEMENT"; then - echo "✅ PM endorsement signature still valid" -else - echo "❌ Invalid endorsement signature" -fi - -ENDORSEMENT_UPDATE=$(envelope subject type string "Endorsement Validity Update") -ENDORSEMENT_UPDATE=$(envelope assertion add pred-obj string "endorsementReference" digest "$PM_ENDORSEMENT" "$ENDORSEMENT_UPDATE") -ENDORSEMENT_UPDATE=$(envelope assertion add pred-obj string "keyRotationReference" digest "$SIGNED_RECOVERY_RECORD" "$ENDORSEMENT_UPDATE") -ENDORSEMENT_UPDATE=$(envelope assertion add pred-obj string "validityStatement" string "This endorsement remains valid through key rotation, as BWHacker's identity is preserved" "$ENDORSEMENT_UPDATE") -ENDORSEMENT_UPDATE=$(envelope assertion add pred-obj string "updateDate" string "$(date +%Y-%m-%d)" "$ENDORSEMENT_UPDATE") - -WRAPPED_UPDATE=$(envelope subject type wrapped "$ENDORSEMENT_UPDATE") - -SIGNED_UPDATE=$(envelope sign -s "$NEW_PRIMARY_KEY_PRIVATE" "$WRAPPED_UPDATE") - -PROGRESSIVE_XID=$(envelope assertion add pred-obj string "endorsementUpdate" envelope "$SIGNED_UPDATE" "$PROGRESSIVE_XID") -echo "$PROGRESSIVE_XID" > output/bwhacker-endorsement-preserved.envelope - -echo "✅ Endorsement validity preserved through key rotation" -``` - -This ensures that BWHacker's professional reputation and trust network remains intact despite key changes. - -## 7. BWHacker's Complete Key Management Plan - -Let's put all these elements together in a comprehensive key management plan: - -👉 -```sh -KM_PLAN=$(envelope subject type string "BWHacker's Comprehensive Key Management Plan") - -KM_PLAN=$(envelope assertion add pred-obj string "principle" string "Maintain pseudonymity across all key operations" "$KM_PLAN") -KM_PLAN=$(envelope assertion add pred-obj string "principle" string "Apply least privilege to all keys" "$KM_PLAN") -KM_PLAN=$(envelope assertion add pred-obj string "principle" string "Document all key changes with fair witnessing principles" "$KM_PLAN") -KM_PLAN=$(envelope assertion add pred-obj string "principle" string "Enable progressive trust through granular permissions" "$KM_PLAN") -KM_PLAN=$(envelope assertion add pred-obj string "principle" string "Maintain stable identity through all key changes" "$KM_PLAN") -KM_PLAN=$(envelope assertion add pred-obj string "principle" string "Preserve endorsement validity through key rotations" "$KM_PLAN") - -KM_PLAN=$(envelope assertion add pred-obj string "keyCategories" string "Identity, Project-specific, Function-specific, Recovery, Collaboration, Endorsement" "$KM_PLAN") -KM_PLAN=$(envelope assertion add pred-obj string "storagePractices" string "Primary keys: offline secure storage; Project keys: project-specific hardware; Recovery keys: distributed with trusted peers" "$KM_PLAN") - -KM_PLAN=$(envelope assertion add pred-obj string "rotationSchedule" string "Identity keys: yearly; Project keys: project conclusion; Collaboration keys: with permission upgrades" "$KM_PLAN") -KM_PLAN=$(envelope assertion add pred-obj string "recoveryProtocol" string "Social recovery with multiple peer attestations and pre-established challenges" "$KM_PLAN") - -KM_PLAN=$(envelope assertion add pred-obj string "documentationRequirements" string "All key operations must include: date, justification, methodology, limitations, and verification method" "$KM_PLAN") -KM_PLAN=$(envelope assertion add pred-obj string "notificationProtocol" string "All collaborators must receive signed notifications of key changes that affect them" "$KM_PLAN") -KM_PLAN=$(envelope assertion add pred-obj string "endorsementPolicy" string "All endorsements must be preserved through key changes with signed validity updates" "$KM_PLAN") - -WRAPPED_KM_PLAN=$(envelope subject type wrapped "$KM_PLAN") - -SIGNED_KM_PLAN=$(envelope sign -s "$NEW_PRIMARY_KEY_PRIVATE" "$WRAPPED_KM_PLAN") -echo "$SIGNED_KM_PLAN" > output/bwhacker-key-management-plan.envelope -``` - -## Key Concepts - -- **Pseudonymous Key Management**: Managing keys to support pseudonymous identity without compromising privacy -- **Trust-Based Key Hierarchy**: Structuring keys based on their role in trust relationships -- **Key Rotation for Privacy**: Using key rotation as both a security and privacy enhancement -- **Social Recovery**: Establishing recovery methods that don't compromise pseudonymity -- **Progressive Permissions**: Aligning key permissions with trust development -- **Fair Witnessing in Key Management**: Applying transparency principles to key operations -- **Endorsement Preservation**: Maintaining the validity of peer endorsements through key changes - -### Theory to Practice: Identity Continuity Through Cryptographic Evolution - -The key management strategies you've implemented demonstrate advanced concepts in cryptographic identity systems: - -1. **Identity/Key Separation**: When you rotated the tablet key while maintaining BWHacker's stable identifier, you demonstrated the crucial separation between cryptographic keys and identity. Unlike traditional systems where changing keys means changing identity, XIDs maintain continuity of identity across cryptographic changes. - > **Historical Context**: Early cryptographic identity systems like PGP linked identity directly to public keys, making key rotation a complex, identity-changing event. XIDs solve this problem by deriving identity from an inception event rather than from the current key material. - -2. **Least Privilege Architecture**: The different permission levels assigned to various keys (e.g., sign-only for tablet, full permissions for primary) implement the **least privilege principle**. This minimizes risk by ensuring that compromise of any single key limits the potential damage to specific operations. - > **Why this matters**: If BWHacker's tablet is compromised, the attacker can only sign statements - they cannot add or remove keys. This significantly limits the potential damage compared to a compromise of a key with full permissions. - -3. **Trust-Based Key Hierarchy**: By creating different keys for different purposes (primary identity, project-specific, evidence commitment, recovery), you've implemented a **context-specific key hierarchy** that aligns cryptographic capabilities with specific trust relationships and usage contexts. - > **Real-World Analogy**: This is similar to how you might have different physical keys for different purposes - a master key for your home, a separate key for a storage unit, another for a vehicle - each with different levels of access and consequences if lost. - -4. **Social Recovery Mechanisms**: The peer-based recovery process demonstrates **trust-based resilience**. Unlike centralized recovery systems that rely on a single authority, this distributed approach maintains the self-sovereign nature of the identity even during critical operations like recovery. - > **ANTI-PATTERN**: Many systems rely on centralized recovery through customer service or "forgot password" flows, creating single points of failure and social engineering vulnerabilities. Social recovery distributes this trust across multiple peers. - -5. **Progressive Permission Models**: The collaboration key that gained increased permissions after successful deliverables implements **graduated permission elevation**. This aligns cryptographic capabilities with demonstrated trustworthiness, rather than granting excessive permissions upfront. - -6. **Fair Witnessing in Key Operations**: The detailed documentation of key changes with observable facts, methodology, and limitations implements **transparent key governance**. This maintains the integrity of the identity system by making cryptographic operations transparent and verifiable. - > **Cross-Tutorial Connection**: This builds on the Fair Witness principles introduced in Tutorial #3, applying them specifically to key management operations for transparent yet privacy-preserving documentation. - -7. **Permission Types Specialization**: The tutorial demonstrates the full range of permission types (sign, encrypt, update, elect) and their appropriate application for different keys, implementing **functional permission separation**. - -These key management concepts enable XIDs to maintain long-term viability while adapting to changing security requirements and trust relationships - a critical aspect of persistent digital identity that's often overlooked in simpler identity systems. - -## Permission Types - -When adding keys, you can specify different permission levels: - -- **all**: Allow all operations -- **auth**: Authenticate as the subject -- **sign**: Sign communications as the subject -- **encrypt**: Encrypt messages from the subject -- **elide**: Perform data minimization through elision on the subject's data (see [Elision Cryptography](../concepts/elision-cryptography.md)) -- **update**: Update service endpoints -- **elect**: Add or remove other keys - -## Best Practices for Pseudonymous Key Management - -1. **Never Link Keys to Real Identity**: Keep all key management separate from your real identity -2. **Context Separation**: Use different keys for different contexts and trust relationships -3. **Document Without Identifying**: Create thorough documentation that maintains pseudonymity -4. **Progressive Trust Development**: Start with minimal permissions and expand based on demonstrated trust -5. **Transparent Key Changes**: Document key changes with fair witnessing principles -6. **Distributed Recovery**: Create recovery systems that don't rely on a single point of failure -7. **Regular Rotation**: Rotate keys on a regular schedule and immediately if compromise is suspected -8. **Preserve Endorsements**: Ensure peer endorsements remain valid through key changes - -## Next Steps - -In the next tutorial, we'll see how BWHacker leverages her key management strategy while evolving her identity over time, maintaining trust relationships even as her cryptographic foundations change. - -## Example Scripts - -This tutorial has a corresponding example script that implements all the concepts covered: - -- [pseudonymous_key_management.sh](../examples/05-key-management/pseudonymous_key_management.sh) - Implements BWHacker's complete key management strategy including key hierarchy creation, key rotation, recovery mechanisms, and progressive permissions. - -You can run this script to see the entire key management workflow in action, or reference specific sections as you work through the tutorial. - -## Exercises - -1. Create a key hierarchy for a specific pseudonymous use case with at least three different trust contexts -2. Implement a key rotation with proper documentation following fair witnessing principles -3. Design a social recovery mechanism with multiple pseudonymous identities -4. Create a progressive permission plan for a new collaborative relationship -5. Document a comprehensive key management plan for a pseudonymous identity -6. Implement a system for preserving endorsements through key changes \ No newline at end of file diff --git a/tutorials/README.md b/tutorials/README.md deleted file mode 100644 index 606cc49..0000000 --- a/tutorials/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# XID Tutorials - -Welcome to the eXtensible IDentifiers (XIDs) tutorial series. These -tutorials will guide you through creating, understanding, and working -with XIDs, which are a powerful identity framework built on Gordian -Envelope technology. - -## Getting Started - -To complete these tutorials, you'll need: - -1. The `envelope` CLI tool installed -2. Basic familiarity with the command line -3. No prior knowledge of XIDs or Gordian Envelope is required - -## Tutorial Structure - -The tutorials are designed to be completed in order: - -1. [Creating Your First XID](01-your-first-xid.md) - Learn to create a -basic XID and understand its components -2. [Understanding XID Structure](02-understanding-xid-structure.md) - -Explore the inner workings of XIDs -3. [Self-Attestation with XIDs](03-self-attestation-with-xids.md) - -Create structured self-claims with verifiable evidence -4. [Peer Endorsement with XIDs](04-peer-endorsement-with-xids.md) - -Build a network of trust through independent verification -5. [Key Management with XIDs](05-key-management-with-xids.md) - Learn -to manage keys while maintaining identity - -Each tutorial builds on skills from previous sections. Complete -working examples for each tutorial can be found in the `examples` -directory. - -## Key Concepts - -XIDs (eXtensible IDentifiers) provide: - -- **Stable Identity**: Your identifier remains stable even as keys change -- **Self-Sovereign Control**: You control your identity, not a third party -- **Cryptographic Verification**: Digitally sign and verify information -- **Privacy Features**: Selectively share aspects of your identity - -## Running the Examples - -For each tutorial, there is a corresponding example script in the -`examples` directory. These scripts implement the full functionality -covered in the tutorials. - -To run an example: - -👉 -```sh -cd examples/01-basic-xid -./create_basic_xid.sh -``` - -## Next Steps - -After completing these tutorials, you'll be able to: - -- Create and manage XIDs -- Understand the relationship between XIDs and cryptographic keys -- Build rich, structured identity profiles -- Sign and verify data using your XID - -Advanced tutorials on secure messaging, selective disclosure, and -integration with other systems will be coming soon. \ No newline at end of file From d31f881293f9f16c059832be976751d07f1dbe21 Mon Sep 17 00:00:00 2001 From: "@ChristopherA" Date: Wed, 26 Nov 2025 16:46:54 -0800 Subject: [PATCH 2/4] Add Tutorial 01: Creating Your First XID Pedagogically-redesigned tutorial with: - Subject-Assertion-Object model explanation - Known vs String predicates distinction - Merkle tree explanation for elision - Ed25519 keypair generation - Encrypted private keys (SSH-like model) - Provenance marks and signature verification - 15 atomic learnings covered Test validated: tests/01-your-first-xid-TEST.sh passes 100% Signed-off-by: @ChristopherA --- tutorials/01-your-first-xid.md | 791 +++++++++++++++++++++++++++++++++ 1 file changed, 791 insertions(+) create mode 100644 tutorials/01-your-first-xid.md diff --git a/tutorials/01-your-first-xid.md b/tutorials/01-your-first-xid.md new file mode 100644 index 0000000..fca4a62 --- /dev/null +++ b/tutorials/01-your-first-xid.md @@ -0,0 +1,791 @@ +# Creating Your First XID + +This tutorial introduces Amira, a software developer with a politically sensitive background who wants to contribute to social impact projects without risking her professional position or revealing her identity. By the end, you'll have created a basic XID (eXtensible IDentifier) that enables pseudonymous contributions while maintaining security. + +**Time to complete: 10-15 minutes** + +> **Related Concepts**: Before or after completing this tutorial, you may want to read about [XID Fundamentals](../concepts/xid.md) and [Gordian Envelope Basics](../concepts/gordian-envelope.md) to understand the theoretical foundations. + +## Prerequisites + +- Basic terminal/command line familiarity +- The [Gordian Envelope-CLI](https://github.com/BlockchainCommons/bc-envelope-cli-rust) tool installed (release 0.27.0 or later recommended) +- Optional: [bc-dcbor-cli](https://github.com/BlockchainCommons/bc-dcbor-cli) (`dcbor` command) for advanced recovery workflows + +## What You'll Learn + +- How to create a basic XID for pseudonymous identity +- How to selectively encrypt just your private key (SSH-like model) +- How to create public versions of your XID using elision +- How to verify signatures and inspect provenance marks +- How to maintain strong cryptographic integrity while sharing selectively +- How to understand XID file organization using secure naming conventions + +## Amira's Story: Why Pseudonymous Identity Matters + +Amira is a successful software developer working at a prestigious multinational bank in Boston. With her expertise in distributed systems security, she earns a comfortable living, but she wants more purpose in her work. On the advice of her friend Charlene, Amira discovers RISK, a network that connects developers with social impact projects while protecting participants' privacy. + +Given Amira's background in a politically tense region, contributing openly to certain social impact projects could risk her visa status, professional position, or even the safety of family members back home. Yet she's deeply motivated to use her skills to help oppressed people globally. This tension between professional security and meaningful contribution creates a specific need. + +However, Amira faces a dilemma: she can't contribute anonymously because anonymous contributions lack credibility. Project maintainers need confidence in the quality and provenance of code, especially for socially important applications. She needs a solution that protects her identity while allowing her to build a verifiable reputation for her skills. + +Amira needs a technological solution that allows her to: + +1. Share her valuable security expertise without revealing her real identity +2. Build verifiable trust through the quality of her work, not her existing credentials +3. Establish a consistent "BRadvoc8" (Basic Rights Advocate) digital presence that can evolve and build reputation over time +4. Connect with project leaders like Ben from the women's services non-profit +5. Protect herself from adversaries who might target her for her contributions + +This is where XIDs come in: they enable pseudonymous identity with progressive trust development, allowing Amira to safely collaborate on projects aligned with her values while maintaining separation between her pseudonymous contributions and her legal identity. + +## Why XIDs Matter + +XIDs provide significant advantages that go well beyond standard cryptographic keys: + +1. **Stable identity** - XIDs maintain the same identifier even when you rotate keys +2. **Progressive trust** - XIDs let you selectively share different information with different parties +3. **Rich metadata** - XIDs can contain structured attestations, endorsements, and claims +4. **Peer validation** - XIDs enable others to make cryptographically verifiable claims about your identity +5. **Multi-key support** - XIDs can link multiple keys for different devices while maintaining a single identity +6. **Recovery mechanisms** - XIDs support recovery without losing your reputation history +7. **Cryptographic integrity** - XIDs preserve verifiability even when portions are elided + +This first tutorial is deliberately simple to get you started with the basics. In subsequent tutorials, we'll explore more advanced capabilities like data minimization and rich persona structures. + +## Step 1: Create Your XID + +Now that we understand why XIDs are valuable, let's help Amira create her "BRadvoc8" identity. + +Like creating an SSH key with `ssh-keygen`, this single operation creates your complete XID with both private and public keys: + +👉 +```sh +XID_NAME=BRadvoc8 +PASSWORD="Amira's strong password" + +XID=$(envelope generate keypairs --signing ed25519 | \ + envelope xid new \ + --private encrypt \ + --encrypt-password "$PASSWORD" \ + --nickname "$XID_NAME" \ + --generator encrypt \ + --sign inception) + +echo "Created your XID: $XID_NAME" +``` + +**What just happened?** This command created your complete, production-ready XID identity: +- **Generated keypairs**: Both private and public keys using modern algorithms +- **Encrypted private keys**: Protected with your password (like `ssh-keygen -N "passphrase"`) +- **Added provenance mark**: Genesis timestamp establishing when this identity was created +- **Signed the document**: Cryptographically signed for authenticity + +**Keypairs created:** +- **SigningPrivateKey**: For creating signatures (Ed25519 algorithm) +- **EncapsulationPrivateKey**: For decryption (X25519 algorithm) +- **SigningPublicKey**: For signature verification (Ed25519 algorithm) +- **EncapsulationPublicKey**: For encryption (X25519 algorithm) + +**Why Ed25519?** +- **Industry standard**: Same algorithm used by SSH, git, Signal, and modern security tools +- **Fast and secure**: Proven cryptography with excellent performance +- **Future-ready**: Later tutorials can export to SSH format for git commit signing +- **Better compatibility**: More widely supported than specialized signature schemes + +> **Security Note**: Your XID contains your private keys (encrypted with your password). This is like your SSH `id_rsa` file - keep it secure! The same keys will always generate the same XID identifier deterministically. + +**View your XID structure:** + +👉 +```sh +envelope format "$XID" +``` + +🔎 +``` +{ + XID(c7e764b7) [ + 'key': PublicKeys(88d90933, SigningPublicKey(c5385c8f, Ed25519PublicKey(a1fae6ca)), EncapsulationPublicKey(a20a01e7, X25519PublicKey(a20a01e7))) [ + { + 'privateKey': ENCRYPTED [ + 'hasSecret': EncryptedKey(Argon2id) + ] + } [ + 'salt': Salt + ] + 'allow': 'All' + 'nickname': "BRadvoc8" + ] + 'provenance': ProvenanceMark(632330b4) [ + { + 'provenanceGenerator': ENCRYPTED [ + 'hasSecret': EncryptedKey(Argon2id) + ] + } [ + 'salt': Salt + ] + ] + ] +} [ + 'verifiedBy': Signature +] +``` + +**What you see:** +- **Curly braces** `{ }`: The XID is wrapped (required for signing) +- **XID identifier**: `XID(c7e764b7)` - Amira's unique identifier +- **Public keys**: `PublicKeys(...)` showing Ed25519PublicKey and X25519PublicKey - Safe to share +- **Private keys**: `ENCRYPTED` with `'hasSecret': EncryptedKey(Argon2id)` - Protected by password +- **Salt**: Random value that ensures each XID has a unique structure, preventing privacy leaks from comparing envelopes +- **Nickname**: `"BRadvoc8"` - Human-readable identifier +- **Provenance mark**: `ProvenanceMark(...)` - Establishes document genesis +- **Provenance generator**: Also `ENCRYPTED` - Used to advance the provenance chain (Tutorial 03) +- **Signature**: `'verifiedBy': Signature` - Document is cryptographically signed + +The `ENCRYPTED` markers show sensitive data is protected. The `'hasSecret': EncryptedKey(Argon2id)` indicates password-based encryption using the Argon2id algorithm, which provides strong protection against brute-force attacks. + +> **🔍 Notice the Predicate Styles**: +> +> You see two types of predicates in your XID: +> - **Single quotes** (`'key'`, `'provenance'`, `'verifiedBy'`): **Known predicates** - standardized names defined by the Gordian Envelope specification. These ensure different tools understand your XID the same way. +> - **Double quotes** (`"nickname"`, `"service"`, `"github"`): **String predicates** - custom names you define for application-specific data. +> +> **When to use each**: +> - Use **known predicates** when there's a standard meaning - the envelope spec defines dozens of these for common needs (`'key'`, `'isA'`, `'verifiedBy'`, `'note'`, etc.) +> - Use **string predicates** for custom data unique to your use case - anything specific to your application +> +> This distinction ensures interoperability: tools that understand envelopes will correctly interpret known predicates, while string predicates give you flexibility for custom data. In Tutorial 02, you'll add custom assertions using string predicates to build BRadvoc8's rich persona. + +**You now have a production-ready XID!** It includes: +- ✅ Encrypted private keys +- ✅ Provenance tracking (for document lineage) +- ✅ Cryptographic signature (proving authenticity) +- ✅ Ready to share (after eliding private keys) + +### 🔍 Understanding the Envelope Structure: Subject-Assertion-Object Model + +Before going further, you need to understand the fundamental pattern that organizes all envelope data. This mental model will guide you through every tutorial and help you build and manipulate your BRadvoc8 identity effectively. + +**Every envelope follows a simple but powerful pattern: Subject + Assertions** + +Your XID structure breaks down like this: + +``` +{ + XID(c7e764b7) ← THE SUBJECT (the main thing) + [ + 'key': PublicKeys(...) ← ASSERTION 1 (predicate + object) + 'provenance': ProvenanceMark(...) ← ASSERTION 2 (predicate + object) + ] +} +``` + +**The Subject**: The main thing this envelope is about +- In your case: `XID(c7e764b7)` - your identity identifier +- This is what all the assertions describe + +**Assertions**: Claims about the subject (predicate-object pairs) +- `'key': PublicKeys(...)` = "this XID **has** these public keys" +- `'provenance': ProvenanceMark(...)` = "this XID **has** this provenance history" + +Think of it like natural language: +- **Subject** = "This XID" (the thing we're talking about) +- **Predicate** = "has key", "has provenance" (the relationship) +- **Object** = PublicKeys, ProvenanceMark (the value) + +**This pattern repeats at every level** + +Even the assertions can have their own assertions! Look at the `'key'` assertion: + +``` +'key': PublicKeys(88d90933) [ ← Subject of this nested envelope + 'allow': 'All' ← Assertion about the key + 'privateKey': ENCRYPTED ← Another assertion +] +``` + +The public keys object is itself a subject with assertions about it! + +**Why this matters for BRadvoc8**: +- You can **add assertions** to your XID (Tutorial 02: GitHub service, SSH keys) +- You can **remove assertions** via elision (coming up next: removing private keys) +- You can **nest assertions** to create rich structures (Tutorial 02: complex personas) +- Every envelope you encounter follows this same pattern + +**The power of this model**: Once you understand subject-assertion-object, you can reason about any envelope structure - from simple XIDs to complex attestations to nested persona data. It's the universal grammar of Gordian Envelopes. + +### 🔍 About the Abbreviated Display + +Notice that `envelope format` shows abbreviated labels like `PublicKeys(32de0f2b)`, `ENCRYPTED`, and `Salt` rather than the actual data. This is intentional - the formatter recognizes known cryptographic types and displays them concisely for readability. + +**What's contained inside these abbreviations:** + +**`PublicKeys(32de0f2b)`** contains: +- **SigningPublicKey** - Used to verify signatures (Ed25519 in this case) +- **X25519PublicKey** - Used for encryption key agreement + +The display doesn't show these two keys separately, but they're both in there! This is why it's called PublicKeys (plural) - it's a composite containing two cryptographic keys for different purposes. + +**`ENCRYPTED`** contains: +- The actual encrypted PrivateKeys data (ciphertext) +- Argon2id key derivation parameters +- Nonce/IV for the encryption + +**`Salt`** contains: +- Random bytes (typically 16-32 bytes) +- Makes each XID's envelope digest unique +- Prevents correlation by digest matching + +**Why abbreviate?** To keep things readable. Showing full cryptographic data (hundreds of bytes of base64/hex) would obscure the structure. The abbreviated view lets you focus on the **relationships** between components rather than the raw bytes. + +**Keypairs and XID Structure**: Your XID contains both `PrivateKeys` and `PublicKeys` that were generated together as keypairs: +- **SigningPrivateKey** - Used to create signatures (Ed25519 algorithm) +- **EncapsulationPrivateKey** - Used for decryption (X25519 algorithm) +- **SigningPublicKey** - Used to verify signatures (Ed25519 algorithm) +- **EncapsulationPublicKey** - Used for encryption (X25519 algorithm) + +> **Important**: The same keypairs will always create the same XID structure (deterministic). The XID identifier is derived from the public key, so the same keypairs always produce the same XID identifier. + +> **Learn more**: [Key Derivation](concepts/key-derivation.md) + +### 🔍 What Just Happened: Understanding Keypairs in XIDs + +When you piped keypairs to `envelope xid new`, the CLI embedded your keypairs into the XID structure: + +**The Process:** +``` +Step 1: Your input + Keypairs (ur:crypto-prvkeys + ur:crypto-pubkeys) + ├─ SigningPrivateKey + SigningPublicKey + └─ EncapsulationPrivateKey + EncapsulationPublicKey + +Step 2: CLI creates XID structure + XID embeds both private and public keys + ├─ PrivateKeys (encrypted with your password) + └─ PublicKeys (always readable) + +Step 3: Result + Complete identity document with all cryptographic material +``` + +**Critical to understand:** + +| Aspect | Input Keypairs | Keys in XID | +|--------|---------------|-------------| +| What it is | Matched private+public key pairs | Same keys embedded in XID structure | +| **Contains** | Two keypairs (signing + encryption) | **SigningPrivateKey + EncapsulationPrivateKey + PublicKeys** | +| Purpose | Generate XID | Operational keys for signing/decryption | +| Location | Your input variable | Embedded in XID document | +| Format | UR format (`ur:crypto-prvkeys`) | CBOR envelope format | +| Display | Not shown in tutorial | `PrivateKeys(hash, SigningPrivateKey(...), EncapsulationPrivateKey(...))` | + +> **Note**: The `envelope format` display shows algorithm details in version 0.27.0+. In this tutorial, the private keys are encrypted so you see `ENCRYPTED` instead of the actual keys. The public keys are always visible and show both SigningPublicKey and EncapsulationPublicKey (X25519PublicKey). + +**Why this matters:** Your XID is your complete identity. The private keys embedded in it are what make it yours - losing the XID file means losing your identity, just like losing an SSH `id_rsa` file. + +## Step 2: Creating a Public Version by Elision + +Now Amira wants to create a shareable public version. Instead of creating a new XID, she **elides** (removes) the private key from her XID. This is a key envelope feature: **elision preserves the root hash**. + +First, since the XID was automatically wrapped and signed with `--sign inception`, we need to unwrap it to access its assertions: + +👉 +```sh +# Unwrap the signed XID to access its assertions +UNWRAPPED_XID=$(envelope extract wrapped "$XID") +``` + +Now find the digest of the encrypted private key: + +👉 +```sh +# Find the key assertion +KEY_ASSERTION=$(envelope assertion find predicate known key "$UNWRAPPED_XID") +KEY_OBJECT=$(envelope extract object "$KEY_ASSERTION") + +# Find the private key assertion within the key object +PRIVATE_KEY_ASSERTION=$(envelope assertion find predicate known privateKey "$KEY_OBJECT") +PRIVATE_KEY_DIGEST=$(envelope digest "$PRIVATE_KEY_ASSERTION") + +echo "Found private key digest" +``` + +Now elide the private key to create a public version: + +👉 +```sh +PUBLIC_XID=$(envelope elide removing "$PRIVATE_KEY_DIGEST" "$XID") +echo "Created public version by eliding private key" +``` + +View the public version: + +👉 +```sh +envelope format "$PUBLIC_XID" +``` + +🔎 +``` +{ + XID(c7e764b7) [ + 'key': PublicKeys(32de0f2b) [ + 'allow': 'All' + 'nickname': "BRadvoc8" + ELIDED ← Private key removed + ] + 'provenance': ProvenanceMark(632330b4) [ + { + 'provenanceGenerator': ENCRYPTED [ + 'hasSecret': EncryptedKey(Argon2id) + ] + } [ + 'salt': Salt + ] + ] + ] +} [ + 'verifiedBy': Signature +] +``` + +**Important distinction - XID identifier vs Envelope hash:** + +Notice `XID(c7e764b7)` is the same as before. But **this doesn't prove elision preserved the hash!** Here's why: + +- **`XID(c7e764b7)`** = XID identifier (derived from the public key) + - Stays the same across ALL versions of this identity + - Would be the same even if you completely changed the document + - Identifies the **entity**, not the document version + +- **Envelope digest** = Hash of the entire envelope structure + - Changes when document content changes + - THIS is what elision preserves + - THIS is what allows signatures to verify + +**Critical:** The XID identifier is persistent (based on public key), so seeing it unchanged proves nothing about hash preservation. We need to compare the **envelope digest**. + +### Proving Elision Preserves the Envelope Hash + +The tutorial claims that elision preserves the root hash. Let's **verify** this claim by comparing the digests: + +👉 +```sh +# Get digest of original XID (with encrypted private key) +ORIGINAL_DIGEST=$(envelope digest "$XID") + +# Get digest of public XID (without private key) +PUBLIC_DIGEST=$(envelope digest "$PUBLIC_XID") + +# Compare them +echo "Original XID digest: $ORIGINAL_DIGEST" +echo "Public XID digest: $PUBLIC_DIGEST" + +if [ "$ORIGINAL_DIGEST" = "$PUBLIC_DIGEST" ]; then + echo "✅ VERIFIED: Digests are identical - elision preserved the root hash!" +else + echo "❌ ERROR: Digests differ" +fi +``` + +🔎 +``` +Original XID digest: ur:digest/hdcxzswfhsqdfmlujtjnkiylsfwshytlynfzglaeenksjtmweeqzswnebnlumdytfgqdlbgs +Public XID digest: ur:digest/hdcxzswfhsqdfmlujtjnkiylsfwshytlynfzglaeenksjtmweeqzswnebnlumdytfgqdlbgs +✅ VERIFIED: Digests are identical - elision preserved the root hash! +``` + +**Critical Observation**: The digests are **exactly the same!** This proves that elision doesn't change the envelope hash. + +**What this means**: +- The **envelope hash** (digest we just compared) is identical before and after elision +- The signature was created over the **full envelope** (with encrypted private key) +- The signature **verifies on the elided version** (without private key) +- This proves they're the **same cryptographic commitment**, just different views +- You can cryptographically prove properties about data you can't see! + +### 🔍 Understanding WHY Elision Preserves the Hash + +You just proved something remarkable: you removed data (the private key), yet the envelope digest stayed identical. This seems impossible - how can removing data not change the hash? + +**The secret: Merkle tree structure** + +Envelopes use a structure similar to Merkle trees where each part has its own hash that combines into parent hashes. Here's how your XID's hash is actually calculated: + +``` +Envelope Root Hash + ├─ Subject Hash (XID identifier) + ├─ Assertion 1 Hash ('key' → PublicKeys) + ├─ Assertion 2 Hash ('provenance' → ProvenanceMark) + └─ Assertion 3 Hash (nested 'privateKey' → ENCRYPTED) +``` + +**How elision works**: + +1. **Each assertion is hashed independently** + - `'key' assertion` → produces hash `abc123...` + - `'privateKey' assertion` (nested) → produces hash `def456...` + - etc. + +2. **Root hash is calculated FROM these hashes** + - Root = hash(subject_hash + assertion_hash_1 + assertion_hash_2 + ...) + - The root doesn't hash the content directly, it hashes the hashes! + +3. **When you elide, you remove content but KEEP the hash** + - Before eliding: `'privateKey': ENCRYPTED` → hash `def456...` used in parent calculation + - After eliding: `ELIDED` → **still uses hash `def456...`** in parent calculation + - The actual encrypted data is gone, but its hash remains + +4. **Root hash stays the same because the hash inputs are unchanged** + - Still calculating: hash(subject_hash + hash_1 + hash_2 + hash_3...) + - The hashes themselves haven't changed, only the content visibility changed + +**Visual comparison**: + +``` +Full version: + XID [key: PublicKeys, privateKey: ENCRYPTED, ...] + ↓ (calculate digests) + Root hash: ur:digest/hdcxzswf... + +Elided version: + XID [key: PublicKeys, ELIDED (hash=def456), ...] + ↓ (calculate digests using same hashes) + Root hash: ur:digest/hdcxzswf... ← SAME! +``` + +The root hash is calculated from the hashes of parts, not the parts themselves. When you elide, you keep the hash of the elided part in the calculation, so the root hash doesn't change. + +**Why this is powerful for BRadvoc8**: + +- ✅ Sign once (over full data including private keys) +- ✅ Create elided versions (removing sensitive data) +- ✅ Signature verifies on ALL versions (same root hash) +- ✅ **Prove properties without revealing data** - the foundation of selective disclosure +- ✅ Share different views with different people - all cryptographically valid + +This Merkle tree property enables all the data minimization you'll do in Tutorial 02. You can create different views of your identity (for Ben, for public) while maintaining cryptographic integrity across all versions. Amira can prove she has a GitHub account to Ben while showing nothing to the public - all from the same signed XID. + +> **Technical note**: While similar to Merkle trees used in blockchain, Gordian Envelopes extend the concept to handle arbitrary assertion graphs, not just linear chains. This flexibility enables complex identity structures while preserving the hash-preserving properties of elision. + +**Understanding the two different identifiers:** + +| Identifier | What it identifies | Changes when... | Purpose | +|------------|-------------------|-----------------|----------| +| **XID identifier** (`XID(c7e764b7)`) | The **entity** (person/thing) | Public key changes | Persistent identity across document versions | +| **Envelope digest** (`ur:digest/hdcx...`) | The **document version** | Content changes | Cryptographic commitment for signatures | + +**Key insights:** + +**XID identifier** stays the same even if you: +- Change the nickname +- Add/remove assertions +- Elide content +- Update the document in any way (as long as public key is same) +- **It's persistent across ALL document versions** + +**Envelope digest** behavior: +- ✅ **Changes** when you add new assertions (normal modification) +- ✅ **Changes** when you remove assertions (normal deletion) +- ✅ **Changes** when you modify existing content +- ⚠️ **Preserved** when you use elision (special property!) + +**This is the magic of elision:** +- Normal edits (add/remove assertions) → envelope hash changes +- Elision (remove via `envelope elide`) → envelope hash **preserved** +- This is why signatures verify on elided versions! +- Elision is the ONLY way to remove data without changing the hash + +> **Key Envelope Property**: Elision removes data while preserving cryptographic integrity. The root hash remains unchanged, so signatures over the complete document verify on elided versions. This enables data minimization while maintaining verifiability. + +**Why this is powerful:** +- Sign once (over full data) +- Create multiple elided versions (removing different sensitive parts) +- All versions have the same root hash +- Signature verifies on ALL versions +- Recipients can verify without seeing the elided data! + +## Step 3: Verification + +Now let's verify both the signature and provenance on our XID: + +👉 +```sh +# Extract public keys (the XID contains everything needed for verification) +KEY_ASSERTION=$(envelope assertion find predicate known key "$UNWRAPPED_XID") +KEY_OBJECT=$(envelope extract object "$KEY_ASSERTION") +PUBLIC_KEYS=$(envelope extract ur "$KEY_OBJECT") + +# Verify the signature +envelope verify -v "$PUBLIC_KEYS" "$PUBLIC_XID" >/dev/null && echo "✅ Signature verified!" +``` + +🔎 +``` +✅ Signature verified! +``` + +Now verify the provenance mark - notice we can verify from the **public** XID: + +👉 +```sh +# Extract the provenance mark from the PUBLIC XID (no secrets needed!) +PROVENANCE_MARK=$(envelope xid provenance get "$PUBLIC_XID") + +# Verify it's a valid genesis mark +provenance validate "$PROVENANCE_MARK" +``` + +🔎 +``` +✅ (silent success - validation passed!) +``` + +Want to see what was verified? Get the detailed report: + +👉 +```sh +# Show detailed validation report +provenance validate --format json-pretty "$PROVENANCE_MARK" +``` + +🔎 +```json +{ + "chains": [ + { + "chain_id": "...", + "has_genesis": true, + "sequences": [ + { + "start_seq": 0, + "end_seq": 0, + "marks": [ + { + "mark": "ur:provenance/...", + "issues": [] + } + ] + } + ] + } + ] +} +``` + +**What just happened?** +- ✅ **Signature verified** - Confirms this XID is authentically from BRadvoc8 +- ✅ **Provenance verified** - Confirms this is a valid genesis mark (sequence 0, no issues) +- Both verifications worked from the **public XID** - no secrets required! + +**What requires secrets vs. what's public:** + +| Operation | Requires Secrets? | What You Need | +|-----------|------------------|---------------| +| **Verify signature** | ❌ No | Public keys only | +| **Verify provenance** | ❌ No | Provenance mark (public) | +| **Create signature** | ✅ Yes | Private signing key | +| **Advance provenance** | ✅ Yes | Encrypted generator | + +**What the verification proves:** +- `has_genesis: true` - This is the first mark in a provenance chain +- `sequence: 0` - Genesis mark (version 1 of this XID) +- `issues: []` - No validation problems detected + +> **Key insight**: Just like signature verification only needs public keys, provenance verification only needs the mark itself (which is public). You only need secrets to *create* new signatures or *advance* the provenance mark to the next version. + +## What Just Happened? Understanding the Modern XID Workflow + +Let's review what we created and why each piece matters: + +### Encrypted Private Keys (`--private encrypt`) + +When we created the XID, we used `--private encrypt --encrypt-password` to protect the private keys. This is the **SSH-like model**: + +- Your XID contains both private and public keys (like `id_rsa` and `id_rsa.pub`) +- Private keys are encrypted with your password (like `ssh-keygen -N "passphrase"`) +- Public parts (nickname, public keys, provenance) remain readable without password +- Only decryption operations require the password + +**Why this matters**: You can freely share your XID file or store it in email, cloud storage, or version control - the private keys are protected by encryption. + +### Provenance Marks (`--generator encrypt`) + +The `'provenance'` section establishes **document genesis** - a timestamped record of when and how this XID was created: + +``` +'provenance': [ + 'continuations': ProvenanceLog [ + { + 'date': 2025-11-17T00:00:00Z + } [ + 'generator': "bc-envelope-cli-rust/0.27.0" + ] + ] +] +``` + +**What this provides:** +- **Timestamp**: When this identity was created (inception date) +- **Generator info**: Which tool created it (useful for compatibility tracking) +- **Version tracking foundation**: As you update your XID in future tutorials, new provenance marks create an auditable history + +**Why it's brief here**: Provenance becomes critical in Tutorial 03 when you start advancing your XID with updated information. For now, it's just marking your starting point. + +> **Learn more**: Tutorial 03 will show how provenance marks create cryptographic lineage as your identity evolves. + +### Auto-Signing (`--sign inception`) + +The `'verifiedBy': Signature` proves cryptographic authenticity. When we used `--sign inception`, the CLI: + +1. Wrapped your XID (the `{ }` curly braces) +2. Decrypted your private keys using your password +3. Created a signature over the entire document +4. Attached the signature to the envelope + +**The sign-then-elide workflow:** +- Sign the complete document (with encrypted private keys) +- Elide the private keys for sharing (public version) +- Signature verifies on BOTH versions (elision preserves the hash!) +- This is how data minimization with verification works + +**Why automatic is better**: +- **Best practice from day 1**: Production XIDs should always be signed +- **Simpler workflow**: 2 commands to working XID (vs 8 with manual signing) +- **Proven security model**: Sign-then-elide is the correct pattern + +**What about manual signing?** You'll learn the mechanics in Tutorial 02 when we cover building and publishing your identity - where understanding the signing process is more relevant. + +> **Learn more**: The [Signing and Verification](../concepts/signing.md) concept doc explains the cryptographic details. + +### One-Operation Workflow Summary + +Creating a production-ready XID is remarkably simple: + +```bash +# Generate Ed25519 keypairs and create signed XID in one operation +XID=$(envelope generate keypairs --signing ed25519 | \ + envelope xid new \ + --private encrypt \ + --encrypt-password "$PASSWORD" \ + --nickname "$NAME" \ + --generator encrypt \ + --sign inception) +``` + +**What you get:** +- ✅ Complete identity document +- ✅ Encrypted private keys +- ✅ Provenance tracking +- ✅ Cryptographic signature +- ✅ Ready to share (after eliding private keys) +- ✅ Best practices built-in + +**Core value preserved**: Tutorial 01 still teaches the critical insight - **elision preserves the root hash**, enabling data minimization with cryptographic integrity. The automated signing just removes mechanical complexity that's better learned in context (Tutorial 02). + +## Proper File Organization + +For real-world usage, Amira will want to organize her files in a dedicated directory with clear naming conventions. Like SSH keys, she'll have two files: + +**SSH Mental Model:** + +| SSH | XID | Purpose | +|-----|-----|---------| +| `id_rsa` | `BRadvoc8-xid.envelope` | 🔒 Your complete identity (encrypted private keys) | +| `id_rsa.pub` | `BRadvoc8-xid-public.envelope` | ✅ Public version (safe to share) | + +**File structure:** + +``` +xid-20251117/ +├── BRadvoc8-xid.envelope # 🔒 Your complete XID (like id_rsa) +├── BRadvoc8-xid.format # Human-readable version +├── BRadvoc8-xid-public.envelope # ✅ Public XID (like id_rsa.pub) +└── BRadvoc8-xid-public.format # Human-readable version +``` + +**File naming conventions:** +- `.envelope` extension = Binary serialized format (for tools) +- `.format` extension = Human-readable version (for humans) + +**Security levels:** +- 🔒 **KEEP SECRET**: `BRadvoc8-xid.envelope` - Contains your encrypted private keys +- ✅ **SAFE TO SHARE**: `BRadvoc8-xid-public.envelope` - Public keys only (private keys elided) + +All files are stored in a timestamp-based directory (e.g., `xid-20251117`) to keep versions organized. + +**Your XID is your complete identity - backup it like an SSH key:** +- The `BRadvoc8-xid.envelope` file contains everything: private keys (encrypted), public keys, nickname, provenance, and signature +- If you lose this file, you lose your identity (just like losing `id_rsa`) + +**Important**: Unlike traditional SSH keys, your XID includes identity metadata (nickname, permissions, provenance history). This makes it a complete, self-contained identity document - not just raw key material. + +## Understanding What Happened + +Beyond the technical mechanics covered in the previous sections, there are several deeper insights about what this XID enables: + +1. **Self-Sovereign Identity**: BRadvoc8's identity is fully under Amira's control with no central authority. No service provider issued this identifier, and she maintains complete ownership of both the keys and the resulting XID document. + > **Why this matters**: Unlike traditional identities (email accounts, social profiles) that can be suspended or controlled by providers, BRadvoc8's XID remains under Amira's control regardless of any third party. + +2. **Pseudonymity vs. Anonymity**: This XID implements **pseudonymity** rather than anonymity. The identity "BRadvoc8" can build reputation over time through verifiable contributions, while still protecting Amira's real-world identity. + > **Real-World Analogy**: This is similar to how authors might use pen names (like Mark Twain for Samuel Clemens) - they can build reputation under their pseudonym while keeping their personal identity separate. + +3. **Autonomous Storage**: The encrypted XID can be stored anywhere without infrastructure - on a USB drive, in email, printed as a QR code, or cloud storage - because it's a self-contained cryptographic object protected by your password. + +4. **Signature and Provenance Verification**: The signature proves authenticity, and the ProvenanceMark confirms this is the first version (inception), establishing the baseline for future provenance chain verification. The timestamp in the provenance is asserted (not cryptographically verified), but the inception mark allows verifying that future updates came after this point. + +## Common Questions + +### Q: Why Ed25519 instead of Schnorr or other algorithms? + +**A:** Ed25519 is the industry standard (SSH, git, Signal) with wide compatibility and excellent security. Advanced users can use other algorithms (`--signing schnorr`, `--signing ecdsa`, `--signing mldsa44`), but Ed25519 is recommended for beginners. + +### Q: What if I lose my XID file? + +**A:** If you lose your `BRadvoc8-xid.envelope` file without a backup, **you lose your identity**. This is just like losing your SSH `id_rsa` file. There's no recovery mechanism without a backup - make sure to store encrypted copies in multiple secure locations. + +### Q: Can I use this XID on multiple devices? + +**A:** Yes! Copy your `BRadvoc8-xid.envelope` file to other devices. Since the private keys are encrypted, the file is safe to sync via cloud storage (as long as you have a strong password). + +**Like SSH keys**: You can use the same XID across multiple devices, just like you might copy `id_rsa` to a new machine. The XID identifier stays the same regardless of which device you're using. + +**Advanced (Tutorial 02-03)**: You can also create device-specific keys and delegate permissions, allowing each device to have its own key while maintaining a single XID identity. + +## What's Next + +Amira now has a basic, secure XID - but it's quite simple. In the next tutorial, she'll build her BRadvoc8 persona and make it discoverable so others (like Ben from SisterSpaces) can find and verify her identity. We'll learn how to: + +- **Build rich persona structures** - Add GitHub account info, SSH signing keys, and structured metadata +- **Understand key separation** - Why different keys for different purposes (identity vs code signing) +- **Add dereferenceVia assertions** - Tell the world where to find your canonical XID +- **Establish repository authority** - Use Open Integrity inception commits to prove you control a GitHub repo +- **Publish your XID** - Make BRadvoc8 discoverable while maintaining pseudonymity +- **Verify updates** - How others can confirm they have your latest, authentic XID +- **Master manual signing** - Understand the wrap → sign → unwrap workflow (we automated this for simplicity) +- **Advance provenance** - Update your XID and maintain cryptographic lineage + +The key insight: You'll make your XID **discoverable** so endorsers can find you, while maintaining control over what information is public. This enables the trust-building that comes in Tutorial 03. + +## Exercises + +1. Create your own XID with a pseudonym of your choice +2. Experiment with different passwords for protecting your private key +3. Practice creating public versions by eliding the private keys +4. Try signature verification and provenance inspection using your own XID +5. Save and load your XID from files, then verify the signature still works + +## Example Script + +A complete working script implementing this tutorial is available at `tests/01-your-first-xid-TEST.sh`. Run it to see all steps in action: + +```sh +bash tests/01-your-first-xid-TEST.sh +``` + +This script will create all the files shown in the File Organization section with proper naming conventions and directory structure. + +--- + +**Next Tutorial**: [Building & Publishing Your Identity](02-building-publishing.md) - Build your persona, add discovery mechanisms, and make BRadvoc8 findable while maintaining pseudonymity. From 89e703ae9436731a6cefab40345a03b6e1c0baab Mon Sep 17 00:00:00 2001 From: "@ChristopherA" Date: Wed, 26 Nov 2025 16:48:28 -0800 Subject: [PATCH 3/4] Add Tutorial 01 test script Comprehensive test validating all code blocks: - XID creation with Ed25519 keypairs - Elision and hash preservation verification - Signature and provenance validation - Algorithm verification (Ed25519, Argon2id) Signed-off-by: @ChristopherA --- tests/01-your-first-xid-TEST.sh | 152 ++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100755 tests/01-your-first-xid-TEST.sh diff --git a/tests/01-your-first-xid-TEST.sh b/tests/01-your-first-xid-TEST.sh new file mode 100755 index 0000000..f13eeef --- /dev/null +++ b/tests/01-your-first-xid-TEST.sh @@ -0,0 +1,152 @@ +#!/bin/bash +# Comprehensive test of Tutorial 01 - testing every code block +set -e + +echo "=== COMPREHENSIVE TUTORIAL 01 CODE TEST ===" +echo "" + +# Step 1: Create Your XID +echo "STEP 1: Create Your XID" +echo "========================" + +XID_NAME=BRadvoc8 +PASSWORD="Amira's strong password" + +XID=$(envelope generate keypairs --signing ed25519 | \ + envelope xid new \ + --private encrypt \ + --encrypt-password "$PASSWORD" \ + --nickname "$XID_NAME" \ + --generator encrypt \ + --sign inception) + +echo "✓ Created your XID: $XID_NAME" +echo "" + +# View XID structure +echo "Viewing XID structure:" +envelope format "$XID" +echo "" + +# Step 2: Creating a Public Version by Elision +echo "STEP 2: Creating a Public Version by Elision" +echo "=============================================" + +# Unwrap the signed XID +UNWRAPPED_XID=$(envelope extract wrapped "$XID") +echo "✓ Unwrapped signed XID" + +# Find the key assertion +KEY_ASSERTION=$(envelope assertion find predicate known key "$UNWRAPPED_XID") +KEY_OBJECT=$(envelope extract object "$KEY_ASSERTION") + +# Find the private key assertion within the key object +PRIVATE_KEY_ASSERTION=$(envelope assertion find predicate known privateKey "$KEY_OBJECT") +PRIVATE_KEY_DIGEST=$(envelope digest "$PRIVATE_KEY_ASSERTION") + +echo "✓ Found private key digest" + +# Elide the private key +PUBLIC_XID=$(envelope elide removing "$PRIVATE_KEY_DIGEST" "$XID") +echo "✓ Created public version by eliding private key" +echo "" + +echo "Public XID structure:" +envelope format "$PUBLIC_XID" +echo "" + +# Proving Elision Preserves the Envelope Hash +echo "Proving elision preserves envelope hash:" +ORIGINAL_DIGEST=$(envelope digest "$XID") +PUBLIC_DIGEST=$(envelope digest "$PUBLIC_XID") + +echo "Original XID digest: $ORIGINAL_DIGEST" +echo "Public XID digest: $PUBLIC_DIGEST" + +if [ "$ORIGINAL_DIGEST" = "$PUBLIC_DIGEST" ]; then + echo "✅ VERIFIED: Digests are identical - elision preserved the root hash!" +else + echo "❌ ERROR: Digests differ" + exit 1 +fi +echo "" + +# Step 3: Verification +echo "STEP 3: Verification" +echo "====================" + +# Extract public keys from unwrapped XID +KEY_ASSERTION=$(envelope assertion find predicate known key "$UNWRAPPED_XID") +KEY_OBJECT=$(envelope extract object "$KEY_ASSERTION") +PUBLIC_KEYS=$(envelope extract ur "$KEY_OBJECT") + +# Verify signature +envelope verify -v "$PUBLIC_KEYS" "$PUBLIC_XID" >/dev/null && echo "✅ Signature verified!" + +# Verify provenance mark from PUBLIC XID (no secrets needed!) +echo "" +echo "Verifying provenance mark from public XID:" +PROVENANCE_MARK=$(envelope xid provenance get "$PUBLIC_XID") + +# Validate it (silent success) +if provenance validate "$PROVENANCE_MARK" 2>/dev/null; then + echo "✅ Provenance mark verified from public XID (no secrets needed)" +else + echo "❌ Provenance mark validation failed" + exit 1 +fi +echo "" + +# Test Common Questions code snippets +echo "TESTING COMMON QUESTIONS CODE SNIPPETS" +echo "=======================================" + +# Q: How can I verify that elision really preserves the envelope hash? +echo "Test: Verifying elision preserves hash (from Q&A)" +SIGNED_XID="$XID" +PUBLIC_SIGNED_XID="$PUBLIC_XID" + +# Before elision +ORIGINAL_DIGEST=$(envelope digest "$SIGNED_XID") + +# After elision +PUBLIC_DIGEST=$(envelope digest "$PUBLIC_SIGNED_XID") + +# Compare +if [ "$ORIGINAL_DIGEST" = "$PUBLIC_DIGEST" ]; then + echo "✅ Same hash! (from Common Questions example)" +else + echo "❌ Different hash!" + exit 1 +fi +echo "" + +echo "=== ALL TUTORIAL CODE BLOCKS TESTED SUCCESSFULLY ===" +echo "" + +# Check for Ed25519 in output +echo "Verifying Ed25519 usage:" +if envelope format "$XID" | grep -q "Ed25519PublicKey"; then + echo "✅ Ed25519PublicKey found in XID" +else + echo "❌ Ed25519PublicKey NOT found in XID" + exit 1 +fi + +if envelope format "$XID" | grep -q "Signature(Ed25519)"; then + echo "✅ Ed25519 Signature found" +else + echo "❌ Ed25519 Signature NOT found" + exit 1 +fi + +# Check for encrypted generator +if envelope format "$XID" | grep -q "'provenanceGenerator': ENCRYPTED"; then + echo "✅ Encrypted provenance generator found" +else + echo "❌ Encrypted provenance generator NOT found" + exit 1 +fi + +echo "" +echo "✅ ALL TESTS PASSED - Tutorial code is correct!" From 73501a3cb08d487384c52e6adb405643703c422b Mon Sep 17 00:00:00 2001 From: "@ChristopherA" Date: Fri, 28 Nov 2025 12:06:29 -0800 Subject: [PATCH 4/4] Add Key Terminology section to Tutorial 01 - Define 8 core terms taught in T01: XID, Subject, Assertion, Known/String Predicates, Elision, Provenance Mark, Envelope Digest - Matches T02 blockquote format for consistency across tutorials - Placed after Common Questions, before What's Next Signed-off-by: @ChristopherA --- tutorials/01-your-first-xid.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tutorials/01-your-first-xid.md b/tutorials/01-your-first-xid.md index fca4a62..036efdf 100644 --- a/tutorials/01-your-first-xid.md +++ b/tutorials/01-your-first-xid.md @@ -753,6 +753,24 @@ Beyond the technical mechanics covered in the previous sections, there are sever **Advanced (Tutorial 02-03)**: You can also create device-specific keys and delegate permissions, allowing each device to have its own key while maintaining a single XID identity. +## Key Terminology + +> **XID (eXtensible IDentifier)** - A self-contained identity document combining public keys, metadata, provenance, and cryptographic signatures into a single shareable object. +> +> **Subject** - The main thing an envelope describes; in XIDs, this is the XID identifier derived from your public key. +> +> **Assertion** - A predicate-object pair making a claim about the subject (e.g., `'key': PublicKeys(...)`). +> +> **Known Predicate** - Standardized predicate from the Gordian Envelope spec, shown in single quotes (`'key'`, `'verifiedBy'`, `'provenance'`). +> +> **String Predicate** - Custom application-specific predicate, shown in double quotes (`"nickname"`, `"service"`). +> +> **Elision** - Removing data while preserving the envelope's root hash, enabling selective disclosure with maintained cryptographic integrity. +> +> **Provenance Mark** - Cryptographic timestamp establishing when a document was created or updated, forming a verifiable chain of identity evolution. +> +> **Envelope Digest** - The root hash of an envelope structure; preserved across elision, enabling signature verification on different views of the same document. + ## What's Next Amira now has a basic, secure XID - but it's quite simple. In the next tutorial, she'll build her BRadvoc8 persona and make it discoverable so others (like Ben from SisterSpaces) can find and verify her identity. We'll learn how to: