diff --git a/ovc-brand-owner/index.md b/ovc-brand-owner/index.md index 404e4e2..c592282 100644 --- a/ovc-brand-owner/index.md +++ b/ovc-brand-owner/index.md @@ -1,5 +1,79 @@ -## Brand Owner Credentials +## OVC Brand Owner Credential -#### Purpose +### Purpose -These credentials document the issuee's right to use certain elements of a brand, either because the brand is owned by the issuee, or because it is licensed to them. \ No newline at end of file +This credential is issued to a legal entity that has the **right to use a brand** because it is either the direct owner of the brand or a licensee authorized to act under it. It establishes that a specific organization is the legitimate operator of a brand identity — including its name, logo, contact information, and communications channels. + +In voice and messaging ecosystems, the OVC Brand Owner Credential is the mechanism by which a verifier can answer the question: *"Is this call or message legitimately coming from the organization it claims to represent?"* By chaining the brand credential back to both an identity credential (proving the legal entity exists) and a brand authority credential (proving the right to use the brand), a verifier gets cryptographic assurance that the brand presentation is authentic. + +### Schema + +See [ovc-brand-owner.schema.json](ovc-brand-owner.schema.json). + +### Required and optional attributes + +The attributes block requires `d` (attributes SAID), `i` (issuee AID), and `dt` (issuance datetime). `vcard` and `goals` are both optional, though in practice a brand owner credential without a `vcard` is of limited use. Both fields may be selectively disclosed. + +### Brand attributes (`vcard`) + +The `vcard` field is an ordered array of unfolded VCard content lines (RFC 6350). This is the canonical representation of the brand's identity — the information a verifier would present to a call recipient or SMS recipient to describe who is contacting them. + +Key conventions: + +- Property and parameter names are **upper case**. +- Parameter names appear in **lexicographic order**. +- Telephone number values MUST be in **strict E.164 format** (leading `+`, no spaces or punctuation). +- The `CHATBOT` property is standard and takes a URI value. +- For `LOGO` and other static media URIs, the `HASH` parameter SHOULD be included and MUST be the CESR-encoded Blake3-256 digest of the content at the URI. This prevents a logo from being silently swapped after issuance. Alternatively, a data URI may be used to embed the media directly. +- URIs pointing to mutable content SHOULD NOT be used — if present, the credential asserts only the location, not the content. + +Example vcard entries: + +``` +ORG:Acme Space Travel, Ltd. +NICKNAME:Acme Rockets +CHATBOT:https://acmespacetravel.biz/chat +LOGO;HASH=EK2r6EnDXre2pecTBO8s99j4OtNaaDIhVyr7uGugDhmp;VALUE=URI:https://acmespacetravel.biz/logo64x48.png +TEL;TYPE=support:+14155550199 +EMAIL:support@acmespacetravel.biz +URL:https://www.acmespacetravel.biz +ADR;TYPE=work:;;1 Rocket Road;Hawthorne;CA;90250;United States +TZ:America/Los_Angeles +LANG:en-US +``` + +### Goal codes (`goals`) + +The optional `goals` field lists [Hyperledger Aries goal codes](https://bit.ly/49V8YqV) that enumerate the formally-defined activities in which this brand may legitimately engage using the asserted brand attributes. If specified, any activity **not** covered by these goal codes is considered a context in which legitimate use of the brand is not asserted by this credential. + +This field is the primary mechanism for **constraining channel and purpose**. For example: +- A brand that only does outbound voice calls would include goal codes for voice. +- A brand that only does A2P SMS marketing would include goal codes for SMS campaigns. +- A brand operating in both channels would include goal codes for both. + +This allows a single OVC Brand Owner Credential to serve multiple channels without schema proliferation. + +### Edge structure + +The `e` (edges) block is optional. When present, it may contain: + +| Edge | Required in block? | Purpose | +|---|---|---| +| `issuer` | No | Links to an identity credential (e.g., OVC Org Identity, vLEI) proving the identity of the issuer. Defaults to `I2I` operator. | +| `brandauth` | No | Links to a credential proving brand authority — e.g., a trademark registration or license agreement. Defaults to `I2I` operator. | + +### Multichannel readiness + +A single OVC Brand Owner Credential is designed to work across voice, SMS, and other channels. The `vcard` field captures the brand's full contact profile; the `goals` field constrains which channels and activities the credential covers. This avoids the need for separate brand credentials per channel. + +If a brand's voice and SMS operations have materially different contact information (e.g., different numbers or chatbot endpoints), separate credentials can be issued — but in the common case, one credential is sufficient. + +### Rules and governance + +The `r` (rules) block must contain: + +- **`governance`** — A statement identifying the governance framework under which this credential was issued. Issuers must populate this field with the URI of their applicable governance document. + +Additional rules may be present and are governed by the issuer's governance framework. + +The act of issuing or accepting this credential constitutes binding acceptance of those rules. diff --git a/ovc-brand-owner/ovc-brand-owner.schema.json b/ovc-brand-owner/ovc-brand-owner.schema.json index 1f168bd..b95ea67 100644 --- a/ovc-brand-owner/ovc-brand-owner.schema.json +++ b/ovc-brand-owner/ovc-brand-owner.schema.json @@ -1,35 +1,67 @@ { - "$id": "EAoRVmgPyacjhUxaV0nPwiuUuHMjKDpNZrj7ClofZ-3Z", - "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "EImfvpfRx4YKhTzAzdZzCCjSNmwtY5yw9QlpZirG6OUa", + "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "OVC Brand Owner Credential", "description": "Issued to a legal entity that has the right to use a brand because it is the direct owner or a licensee of that brand.", "type": "object", - "credentialType": "BrandOwnerCredential", - "version": "1.0.0", + "version": "2.0.0", + "required": [ + "v", + "d", + "i", + "ri", + "s", + "a", + "r" + ], "properties": { "v": { - "description": "Version", - "type": "string" + "description": "Version string using ACDC conventions, encoding protocol, serialization, and size.", + "type": "string", + "pattern": "^ACDC[0-9]{2}[A-Z]{4}[0-9a-f]{6}_$", + "examples": [ + "ACDC10JSON000345_" + ] }, "d": { - "description": "Credential SAID", - "type": "string" + "description": "SAID of the credential (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EBwNam2e0mYdTx0i9xv78AIm16g1XCkQO8f8yJXaxmJC" + ] }, "u": { - "description": "One time use nonce", - "type": "string" + "description": "A salty nonce (high-entropy random value) used to prevent rainbow-table attacks on the credential SAID.", + "type": "string", + "examples": [ + "0AHcgNghkDaG7ts1Bv8wkv3b" + ] }, "i": { - "description": "Issuer AID", - "type": "string" + "description": "AID of the issuer (the party certifying the brand ownership right).", + "type": "string", + "pattern": "^[A-Za-z0-9_-]{44}$", + "examples": [ + "EDC0Sj0CPYd70zUSY2ehvm7Z4kwZigugiA84wuS7lK2H", + "BCmx-dBiozRlK5MfRnznAHl9kmXjB3t-zxrE3hIIYkeS" + ] }, "ri": { - "description": "Credential status registry", - "type": "string" + "description": "SAID of the issuer's ACDC credential status registry.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EOkdwKgeEF-Ww2d61uhHjAo13rjJROdbdIaxORQJRV2G" + ] }, "s": { - "description": "Schema SAID", - "type": "string" + "description": "SAID of this schema (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EAoRVmgPyacjhUxaV0nPwiuUuHMjKDpNZrj7ClofZ-3Z" + ] }, "a": { "oneOf": [ @@ -38,22 +70,45 @@ "type": "string" }, { - "$id": "EIDYFHkBOgNVWGFRcN1cEXNvRV47-nrNJGx6mKHBA7ia", + "$id": "ENyK4LC9nT4w86rqvwwQ5iQxbISJzTDsSyfeNyX8NbCB", "description": "Attributes block", "type": "object", + "required": [ + "d", + "i", + "dt" + ], "properties": { "d": { - "description": "Attributes block SAID", - "type": "string" + "description": "SAID of the attributes block (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EIDYFHkBOgNVWGFRcN1cEXNvRV47-nrNJGx6mKHBA7ia" + ] + }, + "u": { + "description": "A salty nonce for the attributes block, enabling selective disclosure.", + "type": "string", + "examples": [ + "0AHcgNghkDaG7ts1Bv8wkv3b" + ] }, "i": { - "description": "AID of the legal entity that is the direct owner or a licensee of the brand", - "type": "string" + "description": "AID of the legal entity that is the direct owner or licensee of the brand.", + "type": "string", + "pattern": "^[A-Za-z0-9_-]{44}$", + "examples": [ + "EAZz0-cvLBLfqw3TRo-J0kBzM1TEwQ6a_v_892uH3Yjz" + ] }, "dt": { - "description": "Issuance date time", + "description": "Issuance date-time (when the ACDC was signed), as an ISO-8601 datetime string with timezone.", + "type": "string", "format": "date-time", - "type": "string" + "examples": [ + "2024-01-15T10:30:00.000000+00:00" + ] }, "vcard": { "description": "An ordered list of unfolded, VCard content lines (properties) per RFC 6350, where property and parameter names are upper case, and parameter names appear in lexicographic order. Values that are telephone numbers MUST be in strict E164 format with a leading + but no other spaces or punctuation. The CHATBOT property is standard and is of type URI. If the type of a particular value is URI and refers to static media files (as, for example, with LOGO), the HASH parameter SHOULD be included and MUST be the CESR-encoded value of the content at the URI. Alternatively, data URIs MAY be used. A URI that refers to mutable content SHOULD NOT be used, as it is insecure; if present, the credential is asserting only the location, not the content of the logo.", @@ -89,11 +144,7 @@ } } }, - "additionalProperties": true, - "required": [ - "i", - "dt" - ] + "additionalProperties": true } ] }, @@ -104,34 +155,51 @@ "type": "string" }, { - "$id": "EGt3Q1rQJweeryWfJGBYlKCFsYbNrYGYc6AaTRBzwzHG", + "$id": "EFJV3CKaX9-_cbp7x1RWxhWQrlbo-Qe6r4HL2gUeTvx7", "description": "Edges detail", "type": "object", "required": [ - "d", - "issuer" + "d" ], "properties": { "d": { - "description": "Edges block SAID", - "type": "string" + "description": "SAID of the edges block (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EGt3Q1rQJweeryWfJGBYlKCFsYbNrYGYc6AaTRBzwzHG" + ] }, "issuer": { "description": "Edge credential that proves the identity of the issuer.", "type": "object", "properties": { "n": { - "description": "SAID of a credential that proves the identity of the issuer", - "type": "string" + "description": "SAID of a credential that proves the identity of the issuer.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EBwNam2e0mYdTx0i9xv78AIm16g1XCkQO8f8yJXaxmJC" + ] }, "s": { - "description": "SAID of credential schema that proves the identity of the issuer", - "type": "string" + "description": "SAID of the schema that the issuer identity credential must satisfy.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "ENPE4hUQ8Peu84tEcCni3koOQFOnBrDB0rg_at2NRhV9" + ] }, "o": { - "description": "Operator indicating issuer AID of this ACDC MUST be the Issuee AID of the node this Edge points to.", + "description": "Edge operator. I2I: issuer AID must be the issuee AID of the far node. NI2I: no such requirement. DI2I: delegated issuer AID must be issuee AID of the far node. NOT: inverts the validity of the edge.", "type": "string", - "const": "I2I" + "default": "I2I", + "enum": [ + "I2I", + "NI2I", + "DI2I", + "NOT" + ] } }, "additionalProperties": false, @@ -142,21 +210,35 @@ ] }, "brandauth": { - "description": "Edge credential that proves the brand authority.", + "description": "Edge credential that proves the brand authority (e.g., a trademark registration or license agreement).", "type": "object", "properties": { "n": { - "description": "SAID of a credential that proves the brand authority", - "type": "string" + "description": "SAID of a credential that proves the brand authority.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EBwNam2e0mYdTx0i9xv78AIm16g1XCkQO8f8yJXaxmJC" + ] }, "s": { - "description": "SAID of credential schema that proves the brand authority", - "type": "string" + "description": "SAID of the schema that the brand authority credential must satisfy.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EAoRVmgPyacjhUxaV0nPwiuUuHMjKDpNZrj7ClofZ-3Z" + ] }, "o": { - "description": "Operator indicating issuer AID of this ACDC MUST be the Issuee AID of the node this Edge points to.", + "description": "Edge operator. I2I: issuer AID must be the issuee AID of the far node. NI2I: no such requirement. DI2I: delegated issuer AID must be issuee AID of the far node. NOT: inverts the validity of the edge.", "type": "string", - "const": "I2I" + "default": "I2I", + "enum": [ + "I2I", + "NI2I", + "DI2I", + "NOT" + ] } }, "additionalProperties": false, @@ -167,40 +249,43 @@ ] } }, - "additionalProperties": false + "additionalProperties": true } ] }, "r": { "oneOf": [ { - "description": "Rules section SAID", - "type": "string" + "description": "SAID of rules block (Blake3-256 digest in CESR compact encoding)", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$" }, { - "$id": "EGFgHT7Xrzy9YLdQNXnNTYVBu9_Q0O7K5A2VCWjg93t3", + "$id": "EBap4YrLFX2JOBZkCIbHiC2pi5xb5I90Plq3089vM9cx", "description": "Rules detail", "type": "object", "properties": { "d": { - "description": "Rule section SAID", - "type": "string" + "description": "SAID of the rules block (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$" + }, + "governance": { + "description": "Statement identifying the governance framework under which this credential was issued.", + "type": "string", + "examples": [ + "Issued under governance published at https://provenant.net/governance/ovc-brand-owner/" + ] } }, "additionalProperties": true, "required": [ - "d" + "d", + "governance" ] } ] } }, - "additionalProperties": false, - "required": [ - "i", - "ri", - "s", - "d", - "r" - ] + "additionalProperties": false } \ No newline at end of file diff --git a/ovc-org-vet/index.md b/ovc-org-vet/index.md index 863f55a..fc9e516 100644 --- a/ovc-org-vet/index.md +++ b/ovc-org-vet/index.md @@ -1,8 +1,12 @@ -## Org Vet Credentials +## OVC Org Identity Credential ### Purpose -This credential asserts with an explicit level of assurance the existence and attributes of an organization. It is issued to a cryptographic identifier controlled by the org, allowing the org to authenticate itself on the basis of the credential. (The [LE vLEI](https://docs.origincloud.net/start/concepts/creds/vleis) is essentially an org vet credential at LoA 3, but its schema varies slightly to express some GLEIF governance requirements.) +This credential **connects different identifiers for the same organization**, binding legal entity identity to a cryptographic identifier (AID). It is issued to an AID that is provably controlled by the named legal entity, allowing verifiers to confirm that the AID belongs to a real, legally-recognized organization. + +This is the foundational trust anchor for the OVC ecosystem. Brand owner credentials, telephone number allocation credentials, and campaign credentials all trace back to an org identity credential as proof that the parties involved are real, accountable legal entities — not anonymous actors. + +The OVC Org Identity Credential is analogous in intent to the [LE vLEI](https://docs.origincloud.net/start/concepts/creds/vleis) defined by GLEIF (which maps to LoA 3), but its schema is designed to be simpler and to accommodate a wider range of national registry sources. ![suggested org vet visual](org-vet-256.png)
Suggested visual: [svg](org-vet.svg) | [256 px](org-vet-256.png) | [128 px](org-vet-128.png) | [64 px](org-vet-64.png) | [32 px](org-vet-32.png) @@ -25,9 +29,57 @@ LoA | intended meaning | verification procedures | mappings ### Schema -See [org-vet.schema.json](org-vet.schema.json) and also [rules.json](rules.json). +See [ovc-org-vet.schema.json](ovc-org-vet.schema.json). + +### Legal identifiers (`legalIdentifiers`) + +The `legalIdentifiers` field lists the external identifiers the vetter used to confirm the organization's existence and attributes at the time of issuance. Each entry has a `type` (the registry or source) and a `value` (the identifier within that registry). + +**At least one identifier should be globally unambiguous and portable across jurisdictions** — typically an LEI. National registry IDs (like UK Companies House `gb` or Swiss `che` numbers) are also valid and can coexist with the LEI. + +Domain names and social media handles are intentionally excluded: they do not unambiguously identify a legal entity across jurisdictions. + +Examples of valid types: + +| type | example value | source | +|---|---|---| +| `lei` | `5493001KJTIIGC8Y1R12` | GLEIF (ISO 17442) | +| `uk-crn` | `01234567` | UK Companies House | +| `che` | `CHE-123.456.789` | Swiss UID Register | +| `us-ein` | `12-3456789` | US IRS EIN | +| `duns` | `123456789` | Dun & Bradstreet | +| `edgar` | `0001234567` | US SEC EDGAR | + +### Levels of Assurance (`LOA`) + +The `LOA` field is a positive number where larger values denote higher assurance. Integer values represent defined tiers; decimal sub-values (e.g., 2.1) allow nuance within a tier. Verifiers should accept any credential where `LOA >= their required threshold`. + +| LOA | Informal name | Intended meaning | +|---|---|---| +| 1 | Bronze | Basic proof of control + authorization of requester; no claim about legalities, tools, or governance. | +| 2 | Silver | Cryptographic proof of control + legal accountability and tooling; no claim about governance or competence. | +| 3 | Gold | Full legal signing authority proven; multisig signing committee; ceremony with no MITM. Equivalent to LE vLEI (GLEIF). | +| 4 | Platinum | TBD — reserved for hardware security or specialized org attributes (e.g., security clearance). | + +### Edge structure + +The `e` (edges) block is optional. When present, it may contain: + +| Edge | Required in block? | Purpose | +|---|---|---| +| `issuer` | No | Links to an identity credential proving the identity of the issuing vetter (OVC). Uses `I2I` operator — the issuer AID of this credential must be the issuee AID of the referenced credential. | + +### Rules and governance + +The `r` (rules) block uses citation-style rules inherited from the credential design: the listed legal identifiers are citations — they point to external registry records. When the rules block is expanded (object form), it MUST contain `governance` and MAY include: + +- `onlyCommitToPoint` — Pointing to an identifier does **not** imply endorsement of or agreement with the cited content. +- `useViaEdges` — The credential is not meant to be used in isolation; its semantics are communicated via referencing ACDCs. +- `undefinedVerification` — Verifying the authenticity of the cited external data is the verifier's responsibility. +- `undefinedRevocation` — Revocation of the credential and revocation of the cited data are independent events. +- `governance` — Identifies the governance framework under which the credential was issued. -### Governance Framework +### Multichannel readiness -These credentials are governed by rules to enhance assurance, discourage abuse, and keep use cases crisp. The current rules are stated in [rules.json](rules.json) and are identified by SAID `EFthNcTE20MLMaCOoXlSmNtdooGEbZF8uGmO5G85eMSF`. New governance frameworks can be written that supplement these rules; see the `gfw` field in the schema. It is also possible to modify or override these rules, by placing a different value in the `r` field. The act of issuing or receiving a GCD credential constitutes binding acceptance of the rules. +This credential is entirely channel-agnostic. It asserts the legal identity of an organization, regardless of how that organization communicates (voice, SMS, web, etc.). It is a building block used by channel-specific credentials, not a channel-specific credential itself. diff --git a/ovc-org-vet/ovc-org-vet.schema.json b/ovc-org-vet/ovc-org-vet.schema.json index 06f0b3c..8f63887 100644 --- a/ovc-org-vet/ovc-org-vet.schema.json +++ b/ovc-org-vet/ovc-org-vet.schema.json @@ -1,11 +1,10 @@ { - "$id": "EHFdm3U_4nML6lo-q_xDTO8183hC9HlWif2l4ycNo8TW", + "$id": "EBO8BH1epA3PnVEotSgU2bn2eAY2AI9jXFQZ6mr5P5rA", "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "OVC Identity Credential", - "description": "Authenticate an org with an explicit level of assurance.", + "title": "OVC Org Identity Credential", + "description": "Connects different identifiers for the same organization, binding legal entity identity to a cryptographic identifier.", "type": "object", - "credentialType": "orgVet", - "version": "1.0.0", + "version": "2.0.0", "required": [ "v", "d", @@ -17,89 +16,194 @@ ], "properties": { "v": { - "description": "Version string using ACDC conventions", - "type": "string" + "description": "Version string using ACDC conventions, encoding protocol, serialization, and size.", + "type": "string", + "pattern": "^ACDC[0-9]{2}[A-Z]{4}[0-9a-f]{6}_$", + "examples": [ + "ACDC10JSON000345_" + ] }, "d": { - "description": "SAID of the credential", - "type": "string" + "description": "SAID of the credential (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EBwNam2e0mYdTx0i9xv78AIm16g1XCkQO8f8yJXaxmJC" + ] + }, + "u": { + "description": "A salty nonce (high-entropy random value) used to prevent rainbow-table attacks on the credential SAID.", + "type": "string", + "examples": [ + "0AHcgNghkDaG7ts1Bv8wkv3b" + ] }, "i": { - "description": "Identifier of the issuer", - "type": "string" + "description": "AID of the issuer (the party asserting the org identity vetting).", + "type": "string", + "pattern": "^[A-Za-z0-9_-]{44}$", + "examples": [ + "EDC0Sj0CPYd70zUSY2ehvm7Z4kwZigugiA84wuS7lK2H", + "BCmx-dBiozRlK5MfRnznAHl9kmXjB3t-zxrE3hIIYkeS" + ] }, "ri": { - "description": "Issuer's ACDC status registry", - "type": "string" + "description": "SAID of the issuer's ACDC credential status registry.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EOkdwKgeEF-Ww2d61uhHjAo13rjJROdbdIaxORQJRV2G" + ] }, "s": { - "description": "SAID of this schema", - "type": "string" + "description": "SAID of this schema (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "ENPE4hUQ8Peu84tEcCni3koOQFOnBrDB0rg_at2NRhV9" + ] }, "a": { - "$id": "ELtdYgSHM9VElQtjd4P19IB24HH8PQZGbEctOjmP69QE", - "description": "Attributes block", - "type": "object", - "required": [ - "d", - "dt" - ], - "properties": { - "d": { - "description": "SAID of attributes block", - "type": "string" - }, - "dt": { - "description": "Issuance date (when the ACDC was signed).", - "format": "date-time", + "oneOf": [ + { + "description": "Attributes block SAID", "type": "string" }, - "loa": { - "description": "Level of assurance.", - "type": "number" - }, - "lids": { - "description": "Array of linked identifiers (LIDs) that vetter claims were able to act as references for this legal entity when the org was vetted. At least one item in this list should be globally unambigious and portable across jurisdictions (e.g., an LEI). Others may come from national registries, OpenCorporates, EDGAR, Dun & Bradstreet, a stock exchange, a LinkedIn profile, a social media handle, a domain name, etc. The nature of individual item is detectable by regex match.", - "type": "array", - "uniqueItems": true, - "minItems": 1, - "items": { - "examples": [ - "5493001KJTIIGC8Y1R12", - "gb/01234567", - "CHE-123.456.789", - "12-345-6789", - "acmespacetravel.biz" - ], - "type": "string" - } + { + "$id": "EOabMjwOpHWrJ5vJU0QNLoIfTKHpAviw547Cbl947swq", + "description": "Attributes block", + "type": "object", + "required": [ + "d", + "i", + "dt" + ], + "properties": { + "d": { + "description": "SAID of the attributes block (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "ELtdYgSHM9VElQtjd4P19IB24HH8PQZGbEctOjmP69QE" + ] + }, + "u": { + "description": "A salty nonce for the attributes block, enabling selective disclosure.", + "type": "string", + "examples": [ + "0AHcgNghkDaG7ts1Bv8wkv3b" + ] + }, + "i": { + "description": "AID of the legal entity (issuee) whose identity was vetted.", + "type": "string", + "pattern": "^[A-Za-z0-9_-]{44}$", + "examples": [ + "EAZz0-cvLBLfqw3TRo-J0kBzM1TEwQ6a_v_892uH3Yjz" + ] + }, + "dt": { + "description": "Issuance date-time (when the ACDC was signed), as an ISO-8601 datetime string with timezone.", + "type": "string", + "format": "date-time", + "examples": [ + "2024-01-15T10:30:00.000000+00:00" + ] + }, + "LOA": { + "description": "Level of Assurance \u2014 a positive number where larger values denote higher assurance (1=bronze, 2=silver, 3=gold). Integer values represent defined tiers; decimal sub-values (e.g., 2.1) allow nuance within a tier. Verifiers should accept any credential where LOA is >= their required threshold.", + "type": "number", + "minimum": 0, + "exclusiveMinimum": 0, + "examples": [ + 1, + 2, + 3 + ] + }, + "LEI": { + "description": "Legal Entity Identifier (LEI) \u2014 a globally unique 20-character alphanumeric code conforming to ISO 17442.", + "type": "string", + "pattern": "^[A-Z0-9]{20}$", + "examples": [ + "5493001KJTIIGC8Y1R12" + ] + }, + "legalIdentifiers": { + "description": "Array of legal identifiers associated with this organization, as referenced during vetting. Each item has a type and value, making the identity source explicit. Sources may include national registries, OpenCorporates, EDGAR, Dun & Bradstreet, or a stock exchange. At least one identifier should be globally unambiguous and portable across jurisdictions.", + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "object", + "properties": { + "type": { + "description": "Category or source of the identifier (e.g., lei, gleif, gb, che, duns, edgar, domain, linkedin, etc.)", + "type": "string" + }, + "value": { + "description": "The identifier value", + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "additionalProperties": true, + "examples": [ + { + "type": "lei", + "value": "5493001KJTIIGC8Y1R12" + }, + { + "type": "uk-crn", + "value": "01234567" + }, + { + "type": "che", + "value": "CHE-123.456.789" + }, + { + "type": "us-ein", + "value": "12-3456789" + } + ] + } + } + }, + "additionalProperties": true } - }, - "additionalProperties": true + ] }, "r": { "oneOf": [ { - "description": "SAID of rules block", + "description": "SAID of rules block (Blake3-256 digest in CESR compact encoding)", "type": "string", - "const": "EM6kWxMNL9BFm0ReegqQfNJLw8OZAfn2ZxcjWs4Ceifh", - "format": "cesr" + "format": "cesr", + "pattern": "^E[A-Za-z0-9_-]{43}$" }, { - "$id": "EADZYJg0S3xZEKlhAChF8smXRFtVmer5ocBXQ3uuQt_h", + "$id": "EM45oGHaEdd_YIyGIFtNy5RVXRtsDSyj4SaOokXW6Qrr", "description": "Rules detail", "type": "object", "required": [ "d", - "onlyCommitToPoint", - "useViaEdges", - "undefinedVerification", - "undefinedRevocation" + "governance" ], "properties": { "d": { - "description": "SAID of rules block", - "type": "string" + "description": "SAID of the rules block (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$" + }, + "governance": { + "description": "Statement identifying the governance framework under which this credential was issued.", + "type": "string", + "examples": [ + "Issued under governance published at https://provenant.net/governance/ovc-org-identity/" + ] }, "onlyCommitToPoint": { "description": "All parties agree that the citation, in and of itself, only commits the issuer to point at content in a way that makes the issuer and the target verifiable. Unless or until context, governance, or other actions prove intent, the citation does NOT imply that the issuer owns, endorses, or agrees with the content.", @@ -117,7 +221,8 @@ "description": "Unless or until governance specifies otherwise, all parties agree that there is no defined relationship between the revocation status of a citation and that of cited data. Cited data may be disavowed or revoked by its creator without a citation being revoked, and vice versa.", "type": "string" } - } + }, + "additionalProperties": true } ] }, @@ -128,34 +233,51 @@ "type": "string" }, { - "$id": "EKk5ejftEjNwjRhw2lYQAwKwvRWapqCNEOx3gUR7WW7n", + "$id": "EJh-O6xFidE8dcOakW95WVIC0n5oqVVkuwXDNr5PZcPU", "description": "Edges detail", "type": "object", "required": [ - "d", - "issuer" + "d" ], "properties": { "d": { - "description": "Edges block SAID", - "type": "string" + "description": "SAID of the edges block (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EKk5ejftEjNwjRhw2lYQAwKwvRWapqCNEOx3gUR7WW7n" + ] }, "issuer": { "description": "Edge credential that proves the identity of the issuer.", "type": "object", "properties": { "n": { - "description": "SAID of a credential that proves the identity of the issuer", - "type": "string" + "description": "SAID of a credential that proves the identity of the issuer.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EBwNam2e0mYdTx0i9xv78AIm16g1XCkQO8f8yJXaxmJC" + ] }, "s": { - "description": "SAID of credential schema that proves the identity of the issuer", - "type": "string" + "description": "SAID of the schema that the issuer identity credential must satisfy.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "ENPE4hUQ8Peu84tEcCni3koOQFOnBrDB0rg_at2NRhV9" + ] }, "o": { - "description": "Operator indicating issuer AID of this ACDC MUST be the Issuee AID of the node this Edge points to.", + "description": "Edge operator. I2I: issuer AID must be the issuee AID of the far node. NI2I: no such requirement. DI2I: delegated issuer AID must be issuee AID of the far node. NOT: inverts the validity of the edge.", "type": "string", - "const": "I2I" + "default": "I2I", + "enum": [ + "I2I", + "NI2I", + "DI2I", + "NOT" + ] } }, "additionalProperties": false, @@ -166,10 +288,10 @@ ] } }, - "additionalProperties": false + "additionalProperties": true } ] } }, - "additionalProperties": true + "additionalProperties": false } \ No newline at end of file diff --git a/ovc-org-vet/rules.json b/ovc-org-vet/rules.json deleted file mode 100644 index 135f063..0000000 --- a/ovc-org-vet/rules.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "d": "EM6kWxMNL9BFm0ReegqQfNJLw8OZAfn2ZxcjWs4Ceifh", - "onlyCommitToPoint": "All parties agree that the citation, in and of itself, only commits the issuer to point at content in a way that makes the issuer and the target verifiable. Unless or until context, governance, or other actions prove intent, the citation does NOT imply that the issuer owns, endorses, or agrees with the content.", - "useViaEdges": "All parties acknowledge that the citation is not intended to be used in isolation. Rather, the intended semantics for the citation should be communicated via a referencing ACDC that clarifies its issuer's intention.", - "undefinedVerification": "All parties agree that procedures for evaluating the authenticity and/or veracity of the referenced content are beyond the scope of standard ACDC verification, and that the verifier is responsible for evaluating in whatever way satisfies their requirements.", - "undefinedRevocation": "Unless or until governance specifies otherwise, all parties agree that there is no defined relationship between the revocation status of a citation and that of cited data. Cited data may be disavowed or revoked by its creator without a citation being revoked, and vice versa." -} \ No newline at end of file diff --git a/registry.json b/registry.json index 14f952d..79a927f 100644 --- a/registry.json +++ b/registry.json @@ -12,11 +12,11 @@ "EKrv2S0OVc8SeKCzIAOSE-y4j5ybLOOgB69y12Lzxh6Y": "face-to-face/face-to-face.schema.json", "EL7irIKYJL9Io0hhKSGWI4OznhwC7qgJG5Qf4aEs6j0o": "gcd/gcd.schema.json", "EJvwY9n7EsJ4ZejUBHFrnrNammC8BkGI9YaW1Wnp5c22": "org-vet/org-vet.schema.json", - "EAoRVmgPyacjhUxaV0nPwiuUuHMjKDpNZrj7ClofZ-3Z": "ovc-brand-owner/ovc-brand-owner.schema.json", - "EHFdm3U_4nML6lo-q_xDTO8183hC9HlWif2l4ycNo8TW": "ovc-org-vet/ovc-org-vet.schema.json", + "EImfvpfRx4YKhTzAzdZzCCjSNmwtY5yw9QlpZirG6OUa": "ovc-brand-owner/ovc-brand-owner.schema.json", + "EBO8BH1epA3PnVEotSgU2bn2eAY2AI9jXFQZ6mr5P5rA": "ovc-org-vet/ovc-org-vet.schema.json", "EG68irpfVX667KCLwG85Cn1Mp3sCe38ftARyQJrxP2kF": "proof-of-control/proof-of-control.schema.json", "EPy_7LE3tVdl8qEKN5i4L8eAgIM-1I51-DNiewmcq-fe": "tcr-vetting/tcr-vetting.schema.json", - "EFvnoHDY7I-kaBBeKlbDbkjG4BaI0nKLGadxBdjMGgSQ": "tn-alloc/tn-alloc.schema.json", + "EJ9YoTJ81TcQ_pS9GmU2UbVURRm3ylnx_Wr1GbKjg0QP": "tn-alloc/tn-alloc.schema.json", "EGEebb1pVRcZ6OXHlYitl5DNh-LDrMWPwRtstiKiDhRy": "tn/tn.schema.json", "EH6ekLjSr8V32WyFbGe1zXjTzFs9PkTYmupJ9H65O14g": "vLEI/acdc/ecr-authorization-vlei-credential.json", "EEy9PkikFcANV1l7EHukCeXqrzT1hNZjGlUk7wuMO5jw": "vLEI/acdc/legal-entity-engagement-context-role-vLEI-credential.json", diff --git a/tn-alloc/example-tn-alloc.json b/tn-alloc/example-tn-alloc.json index dbe32ea..024c2e7 100644 --- a/tn-alloc/example-tn-alloc.json +++ b/tn-alloc/example-tn-alloc.json @@ -1,32 +1,34 @@ { - "v": "ACDC10JSON0003cd_", - "d": "EEeg55Yr01gDyCScFUaE2QgzC7IOjQRpX2sTckFZp1RP", + "v": "ACDC10JSON00040b_", + "d": "EEPb0h9ClyxqrgiLt6hzhEmfEjv7FpVC4utFO09ZHsR9", "u": "0AC8kpfo-uHQvxkuGZdlSjGy", "i": "EANghOmfYKURt3rufd9JNzQDw_7sQFxnDlIew4C3YCnM", "ri": "EDoSO5PEPLsstDr_XXa8aHAf0YKfPlJQcxZvkpMSzQDB", - "s": "EFvnoHDY7I-kaBBeKlbDbkjG4BaI0nKLGadxBdjMGgSQ", + "s": "EJ9YoTJ81TcQ_pS9GmU2UbVURRm3ylnx_Wr1GbKjg0QP", "a": { - "d": "ECFFejktQA0ThTqLtAUTmW46unVGf28I_arbBFnIwnWB", - "u": "0ADSLntzn8x8eNU6PhUF26hk", - "i": "EERawEn-XgvmDR_-2ESVUVC6pW-rkqBkxMTsL36HosAz", - "dt": "2024-12-20T20:40:57.888000+00:00", - "numbers": { - "rangeStart": "+1801361002", - "rangeEnd": "+1801361009" - }, - "channel": "voice", - "doNotOriginate": false + "d": "EGSM6KZWVOXxmoNHlNNYBllu4DXs9Xx5-UhOnpTnDCO7", + "u": "0ADSLntzn8x8eNU6PhUF26hk", + "i": "EERawEn-XgvmDR_-2ESVUVC6pW-rkqBkxMTsL36HosAz", + "dt": "2024-12-20T20:40:57.888000+00:00", + "numbers": [ + "+1801361001-+1801361002", + "+1801361005" + ], + "channel": [ + "voice" + ] }, "e": { - "d": "EI9qlgiDbMeJ7JTZTJfVanUFAoa0TMz281loi63nCSAH", - "tnalloc": { - "n": "EG16t8CpJROovnGpgEW1_pLxH5nSBs1xQCbRexINYJgz", - "s": "EFvnoHDY7I-kaBBeKlbDbkjG4BaI0nKLGadxBdjMGgSQ", - "o": "I2I" - } + "d": "EHVafjATXqFvLkccHwmvjgNh-Yf-CoXoBCV35XVfa-EF", + "tnalloc": { + "n": "EG16t8CpJROovnGpgEW1_pLxH5nSBs1xQCbRexINYJgz", + "s": "EJ9YoTJ81TcQ_pS9GmU2UbVURRm3ylnx_Wr1GbKjg0QP", + "o": "I2I" + } }, "r": { - "d": "EJFhpp0uU7D7PKooYM5QIO1hhPKTjHE18sR4Dn0GFscR", - "perBrand": "Issuees agree not to share the phone number with other brands which may have a common owner but which will make it difficult to consistently identify the originator of traffic." + "d": "EFC5aL2PUkGzu0BdKxWwL-jGkdqzKH8UQMrJg8T0HeYW", + "governance": "Issued under governance published at https://provenant.net/governance/tn-alloc/", + "noSharing": "Issuees agree not to share or lend the allocated telephone number(s) to other parties in a way that would make it difficult to consistently identify the originator of traffic." } } \ No newline at end of file diff --git a/tn-alloc/index.md b/tn-alloc/index.md index 7992f6c..eb5a718 100644 --- a/tn-alloc/index.md +++ b/tn-alloc/index.md @@ -1,5 +1,70 @@ -## Telephone Number (TN) Allocation Credentials +## Telephone Number Allocation Credential -#### Purpose +### Purpose -These credentials document the issuee's right to use a phone number to make phone calls. \ No newline at end of file +This credential proves that an enterprise or individual holds the **right to use (RTU)** one or more specific telephone numbers. The right-to-use may come directly from a telecommunications regulator or may be sub-allocated through a telephone number provider. The credential is channel-agnostic: the same number can carry voice calls, SMS messages, or both, and a single Telephone Number Allocation Credential covers the number regardless of channel. + +### Why this credential matters + +In telephony fraud and spam ecosystems, a caller or sender can trivially spoof any number they choose. Downstream recipients — call analytics platforms, carriers, campaign registries — have no way to distinguish a legitimate originator from a bad actor by looking at the calling number alone. The Telephone Number Allocation Credential establishes a cryptographic chain of custody from the regulator (who originally assigned the number block) to the enterprise that legitimately operates the number today. + +A verifier who holds this credential, together with the edges that chain back to the regulating authority, has a strong basis to assert that a call or message from the claimed number was originated by the holder of this credential — and only that holder. + +### Schema + +See [tn-alloc.schema.json](tn-alloc.schema.json). + +### Number expressions + +The `numbers` attribute is an array of **number expressions**. Each expression is either: + +- A **single E.164 number** — e.g., `+15551234567` +- An **inclusive range** — two E.164 numbers joined by a hyphen, e.g., `+15551230000-+15551239999` + +All numbers in a single credential must share the **same granting authority** — the issuer uses a single edge to point to the party that granted the right to use those numbers. If a holder has numbers from two different source authorities, they must hold two separate credentials. + +Verifiers evaluate each expression in the array. For a single number, it must match exactly. For a range, the number under test must be numerically between the start and end values, inclusive. + +### Multichannel readiness + +This schema supports both **voice** and **SMS** use cases without modification: + +- For **voice**, the holder uses the credential to assert origin identity when initiating a call. +- For **SMS / A2P campaigns**, the holder presents this credential to a campaign registry (e.g., The Campaign Registry) as proof of number ownership before campaign provisioning. The credential does not carry a campaign ID — campaign-level attributes belong in a separate campaign credential that references this one. + +The optional `channel` field can narrow the scope of the credential to a specific channel or set of channels. If omitted, no channel restriction is implied — the credential is valid for any use of the allocated numbers. If present, it is an array of one or both of `"sms"` and `"voice"`. + +| `channel` value | Meaning | +|---|---| +| `["voice"]` | Numbers are allocated for voice use only. | +| `["sms"]` | Numbers are allocated for SMS use only. | +| `["sms", "voice"]` | Numbers are allocated for both channels. | +| *(omitted)* | No channel restriction; allocation is channel-agnostic. | + +This design keeps number ownership and campaign intent cleanly separated, avoiding schema proliferation and making it easy to reuse the same number credential across multiple campaigns or channels over time. + +### Optional fields + +| Field | Type | Purpose | +|---|---|---| +| `channel` | array of `"sms"` / `"voice"` | Restricts the credential to specific channels. Omit for channel-agnostic allocation. | +| `startDate` | ISO-8601 datetime | Earliest date from which the allocation is valid. Useful for proving long-term continuous ownership. | +| `endDate` | ISO-8601 datetime | Expiry date of the allocation. If absent, the allocation is open-ended and governed solely by credential revocation. | + +### Edge structure + +The `e` (edges) block is optional to accommodate **regulators** who originate numbers directly and have no parent issuer. When present, the edges block may contain: + +| Edge | Required in block? | Purpose | +|---|---|---| +| `tnalloc` | No | Chain to a parent Telephone Number Allocation Credential, proving sub-allocation authority all the way back to the regulator. | +| `issuer` | No | Links to an identity credential (e.g., OVC Org Identity, vLEI) that proves who the issuer is. Intentionally generic — does not constrain the schema of the identity credential. | + +### Rules and governance + +The `r` (rules) block must contain: + +- **`noSharing`** — The credential holder agrees not to share or lend the allocated numbers to other parties in a way that would obscure traffic origin. This rule exists because phone numbers are the accountability anchor for calls and messages: if a number is informally lent, regulators and recipients lose the ability to trace bad traffic back to a responsible party. +- **`governance`** — A statement identifying the governance framework under which this credential was issued. Issuers must populate this field with the URI of their applicable governance document. + +The act of issuing or accepting this credential constitutes binding acceptance of these rules. \ No newline at end of file diff --git a/tn-alloc/tn-alloc.schema.json b/tn-alloc/tn-alloc.schema.json index f540ea4..c7a9864 100644 --- a/tn-alloc/tn-alloc.schema.json +++ b/tn-alloc/tn-alloc.schema.json @@ -1,11 +1,10 @@ { - "$id": "EFvnoHDY7I-kaBBeKlbDbkjG4BaI0nKLGadxBdjMGgSQ", - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TN Allocation Credential", - "description": "TN Allocation credential proves an enterpise has the right to use(RTU) specific telephone numbers, either directly from a regulator or through a telephone number provider.", + "$id": "EJ9YoTJ81TcQ_pS9GmU2UbVURRm3ylnx_Wr1GbKjg0QP", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Telephone Number Allocation Credential", + "description": "Telephone Number Allocation credential proves an enterprise has the right to use (RTU) specific telephone numbers, either directly from a regulator or through a telephone number provider.", "type": "object", - "credentialType": "TNAllocationCredential", - "version": "1.0.0", + "version": "2.0.0", "required": [ "v", "d", @@ -18,28 +17,52 @@ ], "properties": { "v": { - "description": "Version", - "type": "string" + "description": "Version string using ACDC conventions, encoding protocol, serialization, and size.", + "type": "string", + "pattern": "^ACDC[0-9]{2}[A-Z]{4}[0-9a-f]{6}_$", + "examples": [ + "ACDC10JSON000345_" + ] }, "d": { - "description": "Credential SAID", - "type": "string" + "description": "SAID of the credential (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EBwNam2e0mYdTx0i9xv78AIm16g1XCkQO8f8yJXaxmJC" + ] }, "u": { - "description": "A salty nonce", - "type": "string" + "description": "A salty nonce (high-entropy random value) used to prevent rainbow-table attacks on the credential SAID.", + "type": "string", + "examples": [ + "0AHcgNghkDaG7ts1Bv8wkv3b" + ] }, "i": { - "description": "Issuer AID", - "type": "string" + "description": "AID of the issuer (the party asserting the telephone number allocation right).", + "type": "string", + "pattern": "^[A-Za-z0-9_-]{44}$", + "examples": [ + "EDC0Sj0CPYd70zUSY2ehvm7Z4kwZigugiA84wuS7lK2H", + "BCmx-dBiozRlK5MfRnznAHl9kmXjB3t-zxrE3hIIYkeS" + ] }, "ri": { - "description": "Credential status registry", - "type": "string" + "description": "SAID of the issuer's ACDC credential status registry.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EOkdwKgeEF-Ww2d61uhHjAo13rjJROdbdIaxORQJRV2G" + ] }, "s": { - "description": "Schema SAID", - "type": "string" + "description": "SAID of this schema (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EI8g4_JZ0zA50yihhsb-RXvOEcsI8TSN7PJrNgIbAUH1" + ] }, "a": { "oneOf": [ @@ -48,7 +71,7 @@ "type": "string" }, { - "$id": "EGgYbtyoE0qGfYfZWZ1lAd-UoWu_2OjqMcms_75s4atv", + "$id": "EFC0ZCw01iPYBFdHHK3EaR_YZYOewvcf3GASJHd5MFBp", "description": "Attributes block", "type": "object", "required": [ @@ -56,75 +79,116 @@ "u", "i", "dt", - "numbers", - "channel", - "doNotOriginate" + "numbers" ], "properties": { "d": { - "description": "Attributes block SAID", - "type": "string" + "description": "SAID of the attributes block (Blake3-256 digest in CESR compact encoding).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EGgYbtyoE0qGfYfZWZ1lAd-UoWu_2OjqMcms_75s4atv" + ] }, "u": { - "description": "A salty nonce", - "type": "string" + "description": "A salty nonce for the attributes block, enabling selective disclosure.", + "type": "string", + "examples": [ + "0AHcgNghkDaG7ts1Bv8wkv3b" + ] }, "i": { - "description": "Recipient Brand AID", - "type": "string" + "description": "AID of the credential recipient \u2014 the enterprise or individual that holds the right to use the allocated telephone numbers.", + "type": "string", + "pattern": "^[A-Za-z0-9_-]{44}$", + "examples": [ + "EAZz0-cvLBLfqw3TRo-J0kBzM1TEwQ6a_v_892uH3Yjz" + ] }, "dt": { - "description": "Issuance date time", + "description": "Issuance date-time (when the ACDC was signed), as an ISO-8601 datetime string with timezone.", + "type": "string", "format": "date-time", - "type": "string" + "examples": [ + "2024-01-15T10:30:00.000000+00:00" + ] }, "numbers": { - "description": "Telephone Numbers allocated to enterpise either as a list of specific numbers or a range of numbers", - "type": "object", - "properties": { - "tn": { - "description": "Specific telephone numbers list", - "type": "array", - "uniqueItems": true, - "minItems": 1, - "items": { - "type": "string", - "description": "Telephone number in E164 format", - "pattern": "[+][0-9]{7,15}" - } - }, - "rangeStart": { - "description": "Range start number in E164 format, inclusive of this number. If provided, rangeEnd must also be provided", - "type": "string" - }, - "rangeEnd": { - "description": "Range end number in E164 format, inclusive of this number. If provided, rangeStart must also be provided", - "type": "string" - } + "description": "Array of number expressions representing telephone numbers allocated to the enterprise. Each expression is either a single E164 number (e.g., '+15551234567') or an inclusive range denoted by a hyphen between two E164 numbers (e.g., '+15551230000-+15551239999'). All numbers in a single credential must share the same granting authority.", + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "string", + "description": "A single E164 telephone number or an inclusive range. Single number: '+' followed by 7-15 digits. Range: two E164 numbers separated by a hyphen (e.g., '+15551230000-+15551239999').", + "pattern": "^\\+[0-9]{7,15}(-\\+[0-9]{7,15})?$" }, - "additionalProperties": false + "examples": [ + [ + "+15551234567" + ], + [ + "+15551230000-+15551239999" + ], + [ + "+15551234567", + "+442071234567" + ], + [ + "+15551230000-+15551239999", + "+15558880000-+15558889999" + ], + [ + "+15551234567", + "+15559876543", + "+442071234567", + "+81312345678" + ] + ] }, "channel": { - "description": "Communication channel for which number will be used (e.g., sms, voice, etc.)", - "type": "string", - "pattern": "sms|voice" - }, - "doNotOriginate": { - "description": "True or False based on condition if telephone number is a 'do not originate' number (inbound only)", - "type": "boolean" + "description": "Optional list of communication channels for which these numbers are allocated. If omitted, no channel restriction is implied. Use 'sms' for A2P/P2P messaging, 'voice' for voice calls, or both to indicate dual-channel use.", + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "string", + "enum": [ + "sms", + "voice" + ] + }, + "examples": [ + [ + "voice" + ], + [ + "sms" + ], + [ + "sms", + "voice" + ] + ] }, "startDate": { - "description": "Start date", + "description": "Optional start date from which the telephone number allocation is valid (ISO-8601). Useful for proving long-term continuous ownership of a number.", + "type": "string", "format": "date-time", - "type": "string" + "examples": [ + "2020-06-01T00:00:00.000000+00:00" + ] }, "endDate": { - "description": "Expiration date", + "description": "Optional expiration date of the telephone number allocation (ISO-8601). If omitted, the allocation is considered open-ended and subject only to credential revocation.", + "type": "string", "format": "date-time", - "type": "string" + "examples": [ + "2026-06-01T00:00:00.000000+00:00" + ] } }, - "additionalProperties": false + "additionalProperties": true } ] }, @@ -135,16 +199,20 @@ "type": "string" }, { - "$id": "ED-ETRO9FOiEgvK8P66Rut-Cun-0aZ5FbgTlngPf9yVT", + "$id": "EAEskU02OaJCo5mJ43PaxSkl7WmDmMimvT5PiDUVkQe-", "description": "Edges block", "type": "object", "properties": { "d": { - "description": "Edges block SAID", - "type": "string" + "description": "SAID of the edges block.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "ED-ETRO9FOiEgvK8P66Rut-Cun-0aZ5FbgTlngPf9yVT" + ] }, "tnalloc": { - "description": "Chain to a TN allocation (RTU) credential that proves with a valid chain back to the regulator", + "description": "Chain to a telephone number allocation (RTU) credential that proves with a valid chain back to the regulator", "type": "object", "required": [ "n", @@ -153,15 +221,23 @@ ], "properties": { "n": { - "description": "SAID of TN allocation credential", - "type": "string" + "description": "SAID of a parent telephone number allocation credential that grants the issuer the right to sub-allocate.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EBwNam2e0mYdTx0i9xv78AIm16g1XCkQO8f8yJXaxmJC" + ] }, "s": { - "description": "SAID of TN allocation schema", - "type": "string" + "description": "SAID of the telephone number allocation schema that the chained credential must satisfy.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EI8g4_JZ0zA50yihhsb-RXvOEcsI8TSN7PJrNgIbAUH1" + ] }, "o": { - "description": "Operator indicating issuer AID of this ACDC MUST be the Issuee AID of the node this Edge points to.", + "description": "Issuer-To-Issuee, operator indicating issuer AID of this ACDC MUST be the Issuee AID of the node this Edge points to.", "type": "string", "const": "I2I" } @@ -173,17 +249,31 @@ "type": "object", "properties": { "n": { - "description": "SAID of a credential that proves the identity of the issuer", - "type": "string" + "description": "SAID of a credential that proves the identity of the issuer (e.g., an OVC Org Identity or vLEI credential).", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "EG_rp79RWfT97mfVCiptp73PVKr26QHa-kAbMkTPqAno" + ] }, "s": { - "description": "SAID of credential schema that proves the identity of the issuer", - "type": "string" + "description": "SAID of the schema that the issuer identity credential must satisfy.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$", + "examples": [ + "ENPE4hUQ8Peu84tEcCni3koOQFOnBrDB0rg_at2NRhV9" + ] }, "o": { - "description": "Operator indicating issuer AID of this ACDC MUST be the Issuee AID of the node this Edge points to.", + "description": "Edge operator. I2I: issuer AID must be the issuee AID of the far node. NI2I: no such requirement. DI2I: delegated issuer AID must be issuee AID of the far node. NOT: inverts the validity of the edge.", "type": "string", - "const": "NI2I" + "enum": [ + "I2I", + "NI2I", + "DI2I", + "NOT" + ], + "default": "NI2I" } }, "additionalProperties": false, @@ -194,10 +284,9 @@ ] } }, - "additionalProperties": false, + "additionalProperties": true, "required": [ - "d", - "tnalloc" + "d" ] } ] @@ -209,25 +298,34 @@ "type": "string" }, { - "$id": "EHIN5MfIpe7_by-Rl7oVK6dDg1o096wds_gwtcsZInzj", + "$id": "EAmHGceHi6XHAXzbT1jwkgxd8_2k8QzlOE-VePPPFRal", "description": "Rules detail", "type": "object", "required": [ "d", - "perBrand" + "noSharing", + "governance" ], "properties": { "d": { - "description": "Rule section SAID", - "type": "string" + "description": "SAID of the rules block.", + "type": "string", + "pattern": "^E[A-Za-z0-9_-]{43}$" + }, + "governance": { + "description": "Statement identifying the governance framework under which this credential was issued.", + "type": "string", + "examples": [ + "Issued under governance published at https://provenant.net/governance/tn-alloc/" + ] }, - "perBrand": { - "description": "perBrand Disclaimer", + "noSharing": { + "description": "No Sharing Disclaimer", "oneOf": [ { "description": "simple compact rule form", "type": "string", - "const": "Issuees agree not to share the phone number with other brands which may have a common owner but which will make it difficult to consistently identify the originator of traffic." + "default": "Issuees agree not to share or lend the allocated telephone number(s) to other parties in a way that would make it difficult to consistently identify the originator of traffic." }, { "description": "Rule detail", @@ -236,7 +334,7 @@ "l": { "description": "Associated legal language", "type": "string", - "const": "Issuees agree not to share the phone number with other brands which may have a common owner but which will make it difficult to consistently identify the originator of traffic." + "default": "Issuees agree not to share or lend the allocated telephone number(s) to other parties in a way that would make it difficult to consistently identify the originator of traffic." } }, "required": [ @@ -247,7 +345,7 @@ ] } }, - "additionalProperties": false + "additionalProperties": true } ] }