# Web4 Data Formats

**Version**: 1
**Status**: Draft — single source of truth for Web4 identifier and credential formats (`core-protocol.md` §designation).
**Last-Updated**: 2026-06-03

---

This document specifies the data formats used in the Web4 protocol. These formats are designed to be flexible, extensible, and interoperable, leveraging existing open standards where possible.

## 1. Web4 Identifier (W4ID)

A Web4 Identifier (W4ID) is a globally unique identifier for a Web4 entity, compliant with the W3C Decentralized Identifier (DID) specification [1]. It provides a standard way to identify and locate Web4 entities in a decentralized manner.

### 1.1. Syntax

The W4ID has the following ABNF syntax:

`w4id = "did:web4:" method-name ":" method-specific-id`

- **`did:web4`**: The scheme and method prefix for Web4 Identifiers.
- **`method-name`**: The name of the method used to create and manage the identifier (e.g., `key`, `web`, `device`).
- **`method-specific-id`**: A method-specific identifier string.

### 1.2. Methods

Web4 defines the following methods for creating and managing W4IDs. This list is **non-exhaustive and extensible**: additional methods MAY be registered as the corpus evolves, and an implementation MUST treat an unrecognized `method-name` as a method it does not support rather than a malformed identifier.

- **`key` method:** The `method-specific-id` is a public key, providing a simple and self-certifying identifier.
- **`web` method:** The `method-specific-id` is a domain name, allowing for the use of existing web infrastructure to host the W4ID document.
- **`device` method:** The `method-specific-id` identifies a hardware-bound device key (see `multi-device-lct-binding.md`), used when an identifier is anchored to a specific physical device.

### 1.3. Relationship to the LCT identifier (`lct:web4:`)

A W4ID identifies a Web4 **entity** (the subject). It is distinct from an **LCT identifier**, which uses the `lct:web4:` prefix and identifies a specific Linked Context Token *instance* — the reified presence record — rather than the entity that is its subject. The two are different namespaces serving different referents: an entity has a `did:web4:` W4ID, and each LCT bound to that entity has its own `lct:web4:` identifier. (The canonical surface form of the `lct:web4:` identifier is specified by the LCT documents; reconciling it with the open identifier-scheme decision is out of scope for this section.)

## 2. Verifiable Credentials (VCs)

Web4 uses Verifiable Credentials (VCs) as defined by the W3C [2] to represent claims and attestations. VCs are a standard way to create and verify digital credentials that are tamper-evident and cryptographically verifiable.

### 2.1. VC Structure

A Web4 VC is a JSON object that includes the following properties:

- **`@context`**: The JSON-LD context, which defines the vocabulary used in the credential.
- **`id`**: A unique identifier for the credential.
- **`type`**: The type of the credential (e.g., `VerifiableCredential`, `Web4Credential`).
- **`issuer`**: The W4ID of the entity that issued the credential.
- **`issuanceDate`**: The date and time when the credential was issued.
- **`credentialSubject`**: The subject of the credential, which is the entity that the claims are about.
- **`proof`**: A digital signature that proves the authenticity and integrity of the credential.

## 3. JSON-LD

Web4 uses JSON-LD (JSON for Linked Data) [3] to represent data in a structured and interoperable way. JSON-LD allows for the use of semantic vocabularies, such as Schema.org [4], to describe the meaning of the data, making it machine-readable and easy to process.

### 3.1. Context

Every Web4 message and credential that uses JSON-LD MUST include a `@context` property. The context can be a URL pointing to a JSON-LD context file, or an inline JSON object.

## References

[1] Sporny, M., Longley, D., Sabadello, M., Reed, D., and O. Steele, "Decentralized Identifiers (DIDs) v1.0", W3C Recommendation, July 2022, <https://www.w3.org/TR/did-core/>.

[2] Sporny, M., Longley, D., and D. Chadwick, "Verifiable Credentials Data Model v1.1", W3C Recommendation, March 2022, <https://www.w3.org/TR/vc-data-model/>.

[3] Sporny, M., Kellogg, G., and M. Lanthaler, "JSON-LD 1.1", W3C Recommendation, July 2020, <https://www.w3.org/TR/json-ld11/>.

[4] Guha, R.V., Brickley, D., and S. Macbeth, "Schema.org", <https://schema.org/>.

[5] Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, June 2020, <https://www.rfc-editor.org/info/rfc8785>.

[6] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", RFC 8949, December 2020, <https://www.rfc-editor.org/info/rfc8949>.

[7] Krawczyk, H. and P. Eronen, "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)", RFC 5869, May 2010, <https://www.rfc-editor.org/info/rfc5869>.

## 4. Pairwise W4ID Derivation

To enhance privacy, Web4 supports the derivation of pairwise, pseudonymous W4IDs. This allows an entity to use a different identifier for each of its relationships, preventing correlation and tracking.

### 4.1. Derivation Function

The following Python code demonstrates the derivation of a pairwise W4ID:

```python
def derive_pairwise_w4id(master_secret: bytes, peer_identifier: str) -> str:
    """Derive a pairwise pseudonymous W4ID for privacy"""
    salt = sha256(peer_identifier.encode()).digest()
    pairwise_key = hkdf(
        master_secret,
        salt=salt,
        info=b"web4-pairwise-id",
        length=32
    )
    return f"w4id:pair:{base32_encode(pairwise_key[:16])}"
```

### 4.2. Derivation Process

1.  **`master_secret`**: A secret key known only to the entity.
2.  **`peer_identifier`**: The unique identifier of the peer entity.
3.  **`salt`**: The salt is derived from the peer's identifier to ensure that a different key is generated for each peer.
4.  **`hkdf`**: The HMAC-based Key Derivation Function (HKDF) [7] is used to derive a new key from the master secret and the salt.
5.  **`pairwise_key`**: The derived key is used to generate the pairwise W4ID.
6.  **`base32_encode`**: The resulting key is encoded using Base32 to create a URL-safe identifier.

## 5. Message Canonicalization

To ensure that digital signatures are consistent and verifiable, Web4 messages MUST be canonicalized before signing. Web4 supports two canonicalization schemes:

### 5.1. JSON Canonicalization Scheme (JCS)

When using JSON, messages MUST be canonicalized using the JSON Canonicalization Scheme (JCS) as specified in RFC 8785 [5]. Conformance REQUIRES a complete RFC 8785 implementation — including recursive sorting of nested object keys, the RFC's number-serialization rules, and its string-escaping rules.

The following JavaScript is a **non-normative sketch** intended only to convey intent. It is **not** a conforming JCS implementation: `JSON.stringify(obj, replacerArray)` whitelists only top-level keys, does not recursively sort nested object keys, and does not apply RFC 8785's number/string rules. Do not use it for signing.

```javascript
// NON-NORMATIVE SKETCH — not a conforming JCS implementation.
// A conforming implementation MUST follow RFC 8785 [5] in full.
function canonicalizeJSON(obj) {
  return JSON.stringify(obj, Object.keys(obj).sort());
}
```

### 5.2. CBOR Deterministic Encoding

When using CBOR, messages MUST be encoded using the Core Deterministic Encoding rules specified in RFC 8949 §4.2 [6]. (RFC 7049, the original CBOR specification, was obsoleted by RFC 8949 in December 2020.) The following rules MUST be followed:

1.  Integers use the smallest possible encoding.
2.  Maps are sorted by key encoding.
3.  Indefinite-length items use definite-length.
4.  No duplicate keys in maps.

```javascript
// CBOR Deterministic Encoding
function canonicalizeCBOR(obj) {
  // 1. Integers use smallest possible encoding
  // 2. Maps sorted by key encoding
  // 3. Indefinite-length items use definite-length
  // 4. No duplicate keys in maps
  return cbor.encode(obj, {canonical: true});
}
```

## 6. Web4 URI Scheme (`web4://`)

The `web4://` URI scheme provides a way to identify and locate a resource owned by a Web4 entity. This section is the **single source of truth** for the scheme's structure; other documents (e.g., [`core-protocol.md`](core-protocol.md) §6 and [`architecture/grammar_and_notation.md`](../architecture/grammar_and_notation.md) §4.1) describe the same scheme for orientation and defer to this definition.

### 6.1. Structure

A `web4://` URI is built on the generic URI syntax of RFC 3986 and has the structure:

`web4://<authority>/<path-abempty>[?query][#fragment]`

- **`web4://`**: The scheme identifier.
- **`<authority>`**: Identifies the Web4 entity that owns the resource. **The surface form of this authority is not resolved here** — see §6.2.
- **`<path-abempty>`**: An optional path to the resource within the entity's namespace, per RFC 3986.
- **`[?query]`** and **`[#fragment]`**: Optional query and fragment components, per RFC 3986.

### 6.2. Authority form (open identifier-scheme decision)

The exact surface form of the `<authority>` component — for example a full Web4 Identifier versus a base32-encoded label — is **subject to the same open repo-wide identifier-scheme decision** that governs the W4ID prefix form (§1.1) and pairwise-identifier derivation (§4). It is **intentionally not resolved here**. Existing documents currently illustrate more than one form (a full W4ID in [`core-protocol.md`](core-protocol.md) §6.1; a `w4id-label` in [`architecture/grammar_and_notation.md`](../architecture/grammar_and_notation.md) §4.1); reconciling them to a single canonical form is deferred to that decision. Implementations MUST NOT assume the authority form is settled until this decision is recorded here.

### 6.3. Resolution

To resolve a `web4://` URI, a client first resolves the authority to the owning entity's service endpoint, then issues a request to that endpoint carrying the path, query, and fragment from the URI.
