Skip to content

Latest commit

 

History

History
537 lines (398 loc) · 23.4 KB

bcr-2024-010-xid.md

File metadata and controls

537 lines (398 loc) · 23.4 KB

XID: Extensible Identifiers

BCR-2024-010

© 2024 Blockchain Commons

Authors: Wolf McNally, Christopher Allen
Date: December 6, 2024

Introduction

This document defines the XID (“eXtensible IDentifier”), a unique 32-byte identifier for a subject entity. A subject may be a person, an organization, a device, or any other entity, real or abstract. XIDs may be extended to XID documents, which can contain keys, endpoints, permissions, delegation of capabilities, and other information.

Status

This document is a work in progress, with a partial reference implementation in the bc-xid crate.

Terminology Clarification Note

XID documents described herein are encoded using Gordian Envelope, which is a recursive data structure having the form:

<subject> [
    <predicate>: <object>
    <predicate>: <object>
    ...
]

The term subject as used in Gordian Envelope documentation and literature derives from the domain of knowledge representation such as the Semantic Web and Resource Description Framework (RDF) where subject-predicate-object triples are the basic unit of relational knowledge. As such, the "subject" of an envelope can be any entity, real or abstract, and the predicate-object pairs are called assertions.

This particular use of the term subject is not to be confused with the same word used in the Verifiable Credential (VC) domain to mean, "the entity about whom claims are being made," which is typically a real-world entity such as a person or organization. Furthermore, envelope assertions are not to be confused with Verifiable Credential claims.

Since Envelopes consist of recursively-nested envelopes, most "subjects" in a typical envelope will not be "subjects" as construed in Verifiable Credentials.

<subject> [
    <predicate>: <object>
    <predicate>: <subject> [
        <predicate>: <object>
        <predicate>: <object>
        ...
    ]
    ...
]

Nonetheless, a XID as the top-level subject of a XID document envelope may very well be such an identifier of a real-world entity, and hence be a subject in both senses. In specific circumstances, it is also possible for envelope assertions to represent verifiable claims.

Introducing XID

A XID (“eXtensible IDentifier”, IPA pronunciation /zɪd/) is a unique 32-byte identifier for a subject entity. A subject may be a person, an organization, a device, or any other entity, real or abstract:

XID(71274df133169a0e2d2ffb11cbc7917732acafa31989f685cca6cb69d473b93c)

XIDs are encoded using CBOR, and are a 32-length CBOR byte string tagged with the CBOR tag #6.40024.

NOTE: This tag has not yet been assigned in the IANA registry of CBOR tags.

So the XID above, in CBOR diagnostic notation, is:

40024(h'71274df133169a0e2d2ffb11cbc7917732acafa31989f685cca6cb69d473b93c')

And when converted to binary is:

D9 9C58                                 # tag(40024)
   58 20                                # bytes(32)
      71274DF133169A0E2D2FFB11CBC7917732ACAFA31989F685CCA6CB69D473B93C

Identifying XIDs

We will frequently identify XIDs by the first four bytes, sufficient for quick recognition by humans:

XID(71274df1)

These first four bytes can be translated to a sequence of Bytemoji or Bytewords prefixed by 🅧 U+1F167 (NEGATIVE CIRCLED LATIN CAPITAL LETTER X) for quick and memorable identification of a XID in any context:

🅧 🌊 😹 🌽 🐞
🅧 JUGS DELI GIFT WHEN
🅧 71 27 4d f1

For additional recognizability and security, a LifeHash may also be used, which is created using the full tagged CBOR encoding of the XID:

image
🅧 JUGS DELI GIFT WHEN

XID URs

To encode a XID as a URI, we encode it as a Uniform Resource (UR) using the UR type xid to take the place of the tag:

ur:xid/hdcxjsdigtwneocmnybadpdlzobysbstmekteypspeotcfldynlpsfolsbintyjkrhfnvsbyrdfw

❇️ Note: None of these alternate encodings change the characteristic bytes (and hence Bytewords) used to quickly identify the XID itself. Comparison of XIDs by machines always uses all 32 bytes.

XIDs With Resolution Methods

To gain access to the information to which a XID refers, it must undergo resolution. A XID alone does not specify a resolution method. It would be desirable for a future XID standard to define as part of its ecosystem a decentralized universal XID resolver that would be useful for many purposes. However, some applications of XIDs will require that one or more alternate or required resolution methods be specified along with the basic XID.

To accomplish this, we can create a minimal XID Document (see below) which only includes one or more resolution methods. This is a Gordian Envelope with the XID as its subject and one or more dereferenceVia assertions describing recommended resolution methods:

XID(71274df1) [
    'dereferenceVia': URI(btcr:01234567)
    'dereferenceVia': URI(https://resolver.example.com)
]

We then wrap the CBOR encoding of this envelope in the XID tag.

40024(200(<XID envelope contents>))

If we want to handle this as a UR, we can use the xid UR type, just like with a bare XID. As with all URs, the UR type (xid) replaces the outer tag:

200(<XID envelope contents>)

So handline a XID document as a UR looks just like a bare XID, just longer:

ur:xid/tpsplstpsotanshdhdcxjsdigtwneocmnybadpdlzobysbstmekteypspeotcfldynlpsfolsbintyjkrhfnoyastpsotpcxksceisjyjyjojkftdldljpihjkjljzkoihjpdmihkshsjnjojzihdmiajljnoyastpsotpcxjnidjyiajpftdyeheyeoeeecenemmtcwrogm

Therefore, when parsing a ur:xid, if the encapsulated CBOR is a byte string, then it is a bare XID. If it begins with tag #6.200, then it is a Gordian Envelope, and hence a XID document.

XID Inception Key

A XID is generated from the SHA-256 hash of the CBOR representation of a specific PublicSigningKey structure called the inception key.

Since the CBOR representation of a PublicSigningKey is self-describing, including the type of algorithm (Ed25519, BIP-340 Schnorr, etc.) the hash is unique to both the key material and the algorithm used.

Therefore, when parsing a ur:xid, if the encapsulated CBOR is a byte string, then it is a bare XID. If it begins with tag #6.200, then it is a Gordian Envelope, and hence a XID document.

XID Inception Key

A XID is generated from the SHA-256 hash of the CBOR representation of a specific PublicSigningKey structure called the inception key.

Since the CBOR representation of a PublicSigningKey is self-describing, including the type of algorithm (Ed25519, BIP-340 Schnorr, etc.) the hash is unique to both the key material and the algorithm used.

SHA256(PublicSigningKey(Ed25519))

71274df133169a0e2d2ffb11cbc7917732acafa31989f685cca6cb69d473b93c

XID(71274df1)

The private half of the inception key is held by the document's inception controller.

The fact that at inception a XID is tied to the cryptographic material of a specific key provides simplicity of lookup and initial authentication, also ensuring that a XID is never generated from arbitrarily chosen numbers, but rather from a unique private key verified to be possessed by the inception controller.

However, a XID's verification keys (which initially include the inception key) can be rotated, including removing (revoking) the inception key, without needing to change the XID itself. This provides for using the XID as a stable identifier throughout its lifetime.

One implication of uniquely tying a XID to a key pair at inception is that a new key pair must be generated and managed for each new XID created. The primary challenge with this is key management when multiple XIDs are managed, while the primary benefit is key isolation in the event of compromise.

XID Document

A XID document is the result of resolving a XID, and provides the foundational information needed to:

  • authenticate the subject entity,
  • communicate with it,
  • delegate one or more controllers of the entity's functions.
  • declare endpoints controllers may use to carry out actions on the subject's behalf.

The format of a XID document makes it easy to:

  • delegate all authority to the subject (in which case it is a self-sovereign XID)
  • share some authority, or
  • completely transfer some or all authority.

Whether function access is granted or denied must be enforced by the verifiers of the rules in the XID document, including XID resolution mechanisms.

A XID document is encoded as a Gordian Envelope, with the XID itself as the envelope subject, and containing a number of assertions about the XID.

Key Declarations

A primary role of a XID document is to declare public keys and their associated attributes, including specific operations they are permitted to perform (their permissions), and (optionally) the endpoints through which they may perform these functions. Public keys are declared in a XID document using the key assertion:

XID(71274df1) [
    'key': PublicKeyBase [
        'allow': 'All'
        'endpoint': URI(https://example.com/endpoint)
    ]
]

Key assertions have:

  • The PublicKeyBase as their object, which includes both a verfier key and an encryption key.
  • One or more allow or deny assertions, which specify the operations the key is permitted to perform.
  • One or more endpoint assertions, which specify the endpoints through which the key may perform these operations.
  • An optional PrivateKeyBase assertion, which includes the private key corresponding to the public key. This key SHOULD be omitted or elided when the XID document is published.

Keys declared at the top level of a XID document are controlled by the inception controller (the key that generated the XID).

The Inception key may be replaced. This must be done by submitting an updated XID document to the XID resolver, which will verify that the signing key has permission to update the XID document in the resolver's database before making the change.

XID(2d9296d0) [
    'key': PublicKeyBase [ // Not the inception key
        'allow': 'All'
        'endpoint': URI(https://example.com/endpoint)
    ]
]

For publication, a XID document envelope must first be wrapped and then signed with one of the declared keys with the Verify permission. If more than one key has the Verify permission, either key may be used. Any key with the All permission implicitly has the Verify permission and may be used to sign the envelope.

{
    XID(71274df1) [
        'key': PublicKeyBase [
            'allow': 'All'
            'endpoint': URI(https://example.com/endpoint)
        ]
    ]
} [
    'signed': Signature
]

Resolution Methods

As mentioned above, XIDs may include non-default resolution methods. A XID document may also include special-purpose resolution mechanisms for a given XID in exactly the same way:

XID(71274df1) [
    'dereferenceVia': "https://resolver.example.com"
    'dereferenceVia': "btcr:01234567"
    'key': PublicKeyBase [
        'allow': 'All'
        'endpoint': URI(https://example.com/endpoint)
    ]
]

Delegates

Delegates are entities that are granted some level of control over a XID. Delegates are declared in a XID document using the delegate assertion. XIDs declared as delegates may also declare non-default resolution mechanisms. In this example, the delegate is granted the ability to sign and encrypt, while the inception key retains all permissions:

XID(71274df1) [
    'delegate': {
        XID(7c30cafe) [
            'dereferenceVia': "https://resolver.example.com"
        ]
    } [
        'allow': 'Encrypt'
        'allow': 'Sign'
        'deny': 'All'
    ]
    'key': PublicKeyBase [
        'allow': 'All'
    ]
]

After resolution, the delegate's keys(s), endpoints, etc. are available:

XID(71274df1) [
    'delegate': {
        XID(7c30cafe) [
            'key': PublicKeyBase [
                'allow': 'All'
                'dereferenceVia': "https://resolver.example.com"
                'endpoint': URI(https://example.com/endpoint)
            ]
        ]
    } [
        'allow': 'Encrypt'
        'allow': 'Sign'
        'deny': 'All'
    ]
    'key': PublicKeyBase [
        'allow': 'All'
    ]
]

Delegates are assigned a set of permissions that are a subset of the permissions of their parent XID. The delegate may also have its own delegates, and so on. Even if a delegate's XID document declares it has All permissions, it is still subject to the permissions of its parent XID, meaning permissions can only narrow as you go down the delegation tree.

Multisigned XID Documents

If policy requires multiple parties to sign an updated XID document:

  • Multiple 'signed': Signature assertions along with a verificationThreshold rule assertion may be used:
{
    XID(2d9296d0) [
        'key': PublicKeyBase [
            'allow': 'Verify'
        ]
        'key': PublicKeyBase [
            'allow': 'Sign'
        ]
        'key': PublicKeyBase [
            'allow': 'Encrypt'
        ]
        'verificationThreshold': 2        // 2 of 3 signatures required
    ]
} [
    'verifiedBy': Signature               // Signed by any two of the above
    'verifiedBy': Signature               // verifiers
]
  • Or, a multiparty threshold signature scheme like FROST could be used where a single XID may be controlled by a quorum of group members, who cooperatively produce a single valid signature:
{
    XID(9699ea9b) [
        'key': PublicKeyBase [  // Corresponding FROST private key
            'allow': 'Verify'   // never known by individual group members.
        ]
    ]
} [
    'verifiedBy': Signature      // Multiparty signature indistinguishable
]                                // from a single-party signature.

Functions

Functions are various actions that may be executed on behalf of the XID subject. The exercise of functions often occurs through one or more endpoints, which serve as APIs enabling the associated operations.

❇️ *Note: The list of functions here is provisional and non-exhaustive.

Operational Functions

Operational functions relate to interacting with services in the day-to-day usage of the XID, where authentication, signing, and accessing resources are the main activities.

  • Auth: Authenticate as the subject (e.g., log into services)
  • Sign: Sign digital communications as the subject
  • Encrypt: Encrypt messages from the subject
  • Elide: Elide data under the subject's control
  • Issue: Issue or revoke verifiable credentials on the subject's authority
  • Access: Access resources allocated to the subject

Management Functions

Management functions affect a XID’s lifecycle and governance. These actions typically require a higher level of trust and authority.

  • Delegate: Delegate function access to third parties
  • Verify: Verify (update) the XID document
  • Update: Update service endpoints
  • Transfer: Remove the inception key
  • Elect: Add or remove other verifiers (rotate keys)
  • Burn: Transition to a new provenance mark chain (see below)
  • Revoke: Revoke the XID entirely

To accept a revised XID document for publication, the resolver network must validate that changes being made are signed by a verifier that has permission to make those changes in the previous version of the XID document.

❇️ Note: Future work could involve defining a system for refining the granularity of permissions by adding assertions to given functions.

Permissions

A function may exist, but to use it an entity must be granted permission to do so.

XID documents have a deny-first permission structure, so any and all permissions are denied unless specifically granted with an allow assertion, and a deny assertion overrides any conflicting allow. The universal permission All may be granted, and then additional deny rules can be added to remove specific permissions.

Delegates may be assigned a subset of the permissions of their parent XID, so permissions can only narrow as you go down the delegation tree.

A minimal, completely self-sovereign XID document that grants all permissions to its inception controller might look like this:

XID(2d9296d0) [
    'key': PublicKeyBase [
        'allow': 'All'
    ]
]

Delegate Permissions

In this example, the XID document declares that all management functions are exclusively held by the inception controller, but operational functions are shared between the inception controller and another controller:

XID(2d9296d0) [
    'delegate': {
        XID(7c30cafe) [
            'key': PublicKeyBase [
                'allow': 'All'
            ]
        ]
    } [
        'allow': 'auth'
        'allow': 'sign'
        'allow': 'elide'
        'allow': 'issue'
        'allow': 'access'
        'allow': 'encrypt'
        'allow': 'decrypt'
    ]
    'key': PublicKeyBase [
        'allow': 'All'
    ]
]

In this example the inception controller retains all authority, and grants a group of three keys access various operational functions. One of the keys is also nor granted the auth and access functions:

XID(2d9296d0) [
    'delegate': {
        XID(0f7b34f2) [
            'key': PublicKeyBase [
                'allow': 'All'
            ]
        ]
    } [
        'allow': 'auth'
        'allow': 'sign'
        'allow': 'elide'
        'allow': 'issue'
        'allow': 'access'
        'allow': 'encrypt'
        'allow': 'decrypt'
    ]
    'delegate': {
        XID(f520960d) [
            'key': PublicKeyBase [
                'allow': 'All'
            ]
        ]
    } [
        'allow': 'auth'
        'allow': 'sign'
        'allow': 'elide'
        'allow': 'issue'
        'allow': 'access'
        'allow': 'encrypt'
        'allow': 'decrypt'
    ]
    'delegate': {
        XID(763a2eba) [
            'key': PublicKeyBase [
                'allow': 'All'
            ]
        ]
    } [
        'allow': 'sign'
        'allow': 'elide'
        'allow': 'issue'
        'allow': 'encrypt'
        'allow': 'decrypt'
    ]
    'key': PublicKeyBase [
        'allow': 'All'
    ]
]

Revisions with Provenance Marks

Although a XID remains stable throughout its lifecycle, the key(s) it vends, the permissions it grants, and the endpoints it uses may change considerably over time. Valid XIDs MUST be created from a inception key, which gives a XID its identity, including verifying that the XID is not formed from arbitrarily chosen numbers.

As long as the inception key remains in the XID document as a verifier, then revisions to the document signed by the same key can be considered authentic.

But control of a XID may be entirely transferred at some point, including entirely removing the inception key. This may be due to possible key compromise, or because policy may simply dictate periodic key rotation.

In addition, there are challenges around the sequencing of published revisions to XID documents in a decentralized, distributed, and concurrent environment. Between two revisions, which is more current? Timestamps can be spoofed.

So, since a XID document may routinely become detached from the cryptographic material used to incept it, how do we authenticate a given version of a XID document we may receive from some source?

Part of that authentication depends on resolving the XIDs of the document's current controller(s), and deciding whether to trust those entities.

However, an additional and complementary path to authentication becomes available if we provide a mechanism for establishing the provenance of a XID document; that is, whether we can establish a XID document as a verifiable part of a chain of revisions going back to its inception.

Therefore, XID documents support the inclusion of a provenance mark. This means our minimal, fully self-sovereign XID document signed and ready for publication now looks like this:

{
    XID(2d9296d0) [
        'key': PublicKeyBase [
            'allow': 'all'
        ]
        'provenance': ProvenanceMark
    ]
} [
    'verifiedBy': Signature
]

A provenance mark is a small binary structure that, like a block of transactions on the Bitcoin blockchain, links a given revision of a XID document to all previous revisions and makes the history of a XID increasingly hard to alter.

However, provenance marks have several additional functions that multiply a XID's security and verifiability. The provenance mark:

  • confirms the cryptographic commitment from the previous revision
  • "seals" the history of previous revision(s),
  • proves that the revision belongs to a specific chain,
  • contains a monotonically increasing integer revision number,
  • contains a timestamp which must never decrease,
  • provides a cryptographic pre-commitment to the next revision.

When first published with a provenance mark (recommended, perhaps mandatory depending on policy and the resolver method) every successive revision to a XID document MUST contain the next mark in the chain. This allows resolvers to independently verify its place in the timeline of the XID's lifecycle as well as detect anomalies that may be the result of data corruption, loss, or attempted forgery.

The technical prerequisite for supporting provenance marks is the generation and secure storage of a 32-byte cryptographic seed. This seed is generated at XID inception along with the inception key, but is not cryptographically linked to it in any way. This means it can be stored together with the inception key or managed separately from it. It can be given to every verifier or held by a completely separate agent whose function is generating the next provenance mark when needed.

To publish a revised document, the seed is used to generate the next provenance mark, which is included in the revised document, and then the entire document is signed by a key with verifier permission. Before being accepted for publication, resolver networks must validate the XID's provenance chain as well as the other XIDs the document references and the verifier's permissions.

Chain Rotation

Having a new piece of cryptographic material to manage raises the question of how to rotate it, if and when the need arises.

The solution is to publish a XID document revision with a "burn mark" that definitively marks the end of the current chain, and links it to the start of a new chain. The process for creating a provenance mark with a burn mark is described in detail in the Provenance Mark whitepaper.

Before accepting a XID document with a burn mark, resolver networks MUST verify that the signer of the document has the burn permission, which is deliberately separate from the verify permission.

When the next revision of the XID document appears, it will contain the genesis mark of the new chain, now cryptographically linked to the burn mark in the previous revision.

IANA Considerations

This document requests the assignment of a new CBOR tag for XIDs: #6.40024.