From e1b50794db7ddcf4b6adb4da67a5d4e5a1ce3c48 Mon Sep 17 00:00:00 2001
From: Stephen Curran
Date: Fri, 20 Dec 2024 15:25:55 -0800
Subject: [PATCH] Initial version of the specification
Signed-off-by: Stephen Curran
---
.github/workflows/render-specs.yml | 9 +-
.gitignore | 2 +
README.md | 152 +++++
index.html | 878 +++++++----------------------
index.js | 366 ------------
multi-file-test/abstract.md | 3 -
multi-file-test/features.md | 132 -----
multi-file-test/getting-started.md | 21 -
multi-file-test/header.md | 17 -
multi-file-test/index.html | 289 ----------
package-lock.json | 78 +--
package.json | 64 +--
readme.md | 150 -----
single-file-test/assets/test.json | 5 -
single-file-test/assets/test.text | 1 -
single-file-test/spec.md | 536 ------------------
spec/abstract.md | 3 +
spec/definitions.md | 14 +
spec/header.md | 19 +
spec/references.md | 6 +
spec/security_and_privacy.md | 0
spec/specification.md | 166 ++++++
spec/version.md | 0
specs.json | 81 +--
specup_logo.png | Bin 3194 -> 0 bytes
25 files changed, 669 insertions(+), 2323 deletions(-)
create mode 100644 README.md
delete mode 100644 index.js
delete mode 100644 multi-file-test/abstract.md
delete mode 100644 multi-file-test/features.md
delete mode 100644 multi-file-test/getting-started.md
delete mode 100644 multi-file-test/header.md
delete mode 100644 multi-file-test/index.html
delete mode 100644 readme.md
delete mode 100644 single-file-test/assets/test.json
delete mode 100644 single-file-test/assets/test.text
delete mode 100644 single-file-test/spec.md
create mode 100644 spec/abstract.md
create mode 100644 spec/definitions.md
create mode 100644 spec/header.md
create mode 100644 spec/references.md
create mode 100644 spec/security_and_privacy.md
create mode 100644 spec/specification.md
create mode 100644 spec/version.md
delete mode 100644 specup_logo.png
diff --git a/.github/workflows/render-specs.yml b/.github/workflows/render-specs.yml
index 938d5d0..afb7c3e 100644
--- a/.github/workflows/render-specs.yml
+++ b/.github/workflows/render-specs.yml
@@ -4,7 +4,7 @@ name: spec-up-render
on:
push:
branches:
- - master
+ - main
jobs:
build-and-deploy-spec:
@@ -13,18 +13,19 @@ jobs:
contents: write
steps:
- name: Checkout 🛎️
- uses: actions/checkout@v2 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly.
+ uses: actions/checkout@v4 # If you're using actions/checkout@v4 you must set persist-credentials to false in most cases for the deployment to work correctly.
with:
persist-credentials: false
- name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
run: |
npm install
- node -e "require('./index')({ nowatch: true })"
+ node -e "require('spec-up')({ nowatch: true })"
+ rm -rf .gitignore
rm -rf node_modules
- name: Deploy
- uses: peaceiris/actions-gh-pages@v3.7.3
+ uses: peaceiris/actions-gh-pages@v4.0.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./
diff --git a/.gitignore b/.gitignore
index 3546bd5..7053e8f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+package-lock.json
+index.html
fonts
# Logs
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5757de6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,152 @@
+# The `did:webvh` DID Method -- `did:web` + Verifiable History
+
+The spec repository for the `did:webvh` DID Method. `did:webvh` is `did:web`
+extended to include the Verifiable History of the DID.
+
+Read the spec: [https://identity.foundation/didwebvh](https://identity.foundation/didwebvh/next)
+
+Proof of concept implementations available:
+
+- Typescript: [https://github.com/decentralized-identity/trustdidweb-ts](https://github.com/decentralized-identity/trustdidweb-ts)
+- Python: [https://github.com/decentralized-identity/trustdidweb-py](https://github.com/decentralized-identity/trustdidweb-py)
+- Go: [https://github.com/nuts-foundation/trustdidweb-go](https://github.com/nuts-foundation/trustdidweb-go)
+- Python Web Server: [https://github.com/decentralized-identity/trustdidweb-server-py](https://github.com/decentralized-identity/trustdidweb-server-py)
+
+## Current Status of the Specification
+
+The current stable version of the specification can be found at
+[https://identity.foundation/didwebvh](https://identity.foundation/didwebvh).
+See any guidance there about the status of the specification -- past versions,
+upcoming changes, etc.
+
+## Abstract
+
+The `did:webvh` DID Method is an enhancement to the well-known `did:web` DID
+method, providing a complementary web-based DID method that addresses
+limitations of `did:web`, most notability, the verifiable history for which it
+is name. `did:webvh` features include the following.
+
+- Ongoing publishing of all DID Document (DIDDoc) versions for a DID instead of,
+ or alongside a `did:web` DID/DIDDoc.
+- Uses the same DID-to-HTTPS transformation as `did:web`.
+- Provides resolvers the full history of the DID using a verifiable chain of
+ updates to the DIDDoc from genesis to deactivation.
+- A self-certifying identifier (SCID) for the DID that is globally
+ unique and derived from the initial DIDDoc that enables DID portability, such
+ as moving the DIDs web location (and so the DID string itself) while retaining
+ the DID's history.
+- DIDDoc updates include a proof signed by the DID Controller(s) *authorized* to
+ update the DID.
+- An optional mechanism for publishing "pre-rotation" keys to prevent loss of
+ control of the DID in cases where an active private key is compromised.
+- An optional mechanism for having collaborating "witnesses"
+ that approve updates to the DID by the DID Controller before publication.
+- DID URL path handling that defaults (but can be overridden) to automatically
+ resolving `/path/to/file` by using a comparable DID-to-HTTPS translation
+ as for the DIDDoc.
+- A DID URL path `/whois` that defaults to automatically returning (if
+ published by the DID controller) a Verifiable Presentation containing
+ Verifiable Credentials with the DID as the `credentialSubject`,
+ signed by the DID.
+
+Combined, the additional features enable greater trust, security and
+verifiability without compromising the simplicity of `did:web`. The incorporation
+of the DID Core compatible "/whois" path, drawing inspiration from the
+traditional WHOIS protocol, offers an easy to use, decentralized, trust
+registry. `did:webvh` aims to establish a more trusted and secure web
+environment by providing robust verification processes and enabling transparency
+and authenticity in the management of decentralized digital identities.
+
+## Contributing to the Specification
+
+Pull requests (PRs) to this repository may be accepted. Each commit of a PR must
+have a DCO (Developer Certificate of Origin -
+[https://github.com/apps/dco](https://github.com/apps/dco)) sign-off. This can
+be done from the command line by adding the `-s` (lower case) option on the `git
+commit` command (e.g., `git commit -s -m "Comment about the commit"`).
+
+Rendering and reviewing the spec locally for testing requires `npm` and `node`
+installed. Follow these steps:
+
+- Fork and locally clone the repository.
+- Install `node` and `npm`.
+- Run `npm install` from the root of your local repository.
+- Edit the spec documents (in the `/spec` folder).
+- Run `npm run render`'
+ - Use `npm run edit` to interactively edit, render and review the spec.
+- Review the resulting `index.html` file in a browser.
+
+The specification is currently in [Spec-Up] format. See the
+[Spec-Up Documentation] for a list of Spec-Up features and functionality.
+
+[Spec-Up]: https://github.com/decentralized-identity/spec-up
+[Spec-Up Documentation]: https://identity.foundation/spec-up/
+
+## Publishing Previous Spec Versions
+
+[Spec-Up] allows for multiple versions of the spec to be rendered and accessed
+on the same site. We use that feature for the `did:webvh` DID Method spec to snapshot
+previous versions of the spec for reference.
+
+To create a snapshot of a version:
+
+- Make a new folder in the root of the repository for the new version, called `spec-v`. For example `v0.3`.
+- Copy the `spec` folder markdown files from the point of that version into the new folder. If you are doing this process as you are starting a new version, you can just copy the files from the `spec` folder of the main branch. Otherwise, you have to find the last commit of the version and get the files from that point in the GitHub history.
+- Update the `specs.json` file to include a new specification:
+ - Copy the primary spec entry text.
+ - Paste that text into a new spec entry in the `"specs"` array.
+ - Update the `"spec_directory"` property to be the name of the new folder you created.
+ - Update the `"output_path"` property to be `./v`. For example `"./v0.3"`.
+ - Append to the `"title"` property the version ` - Version `, For example ` - Version 0.3`.
+- Add a link to the versioned specification in the `Previous Drafts` bullet list, in the `header.md` file in the main spec, so that readers can click on it from the main specification.
+- Update the `header.md` file of the new version spec folder (e.g in `spec-v0.3`) to:
+ - Change the status to `HISTORICAL -- **THIS IS NOT THE CURRENT VERSION OF THE SPECIFICATION**`
+ - As appropriate, add guidance for readers **WITHOUT** altering the version of the specification itself.
+ - Remove the `Past Drafts` section and put a relative link back to the current spec -- such as:
+
+```text
+**Latest Version:**
+
+- Specification: [https://identity.foundation/didwebvh/](../)
+- Repository: [https://github.com/decentralized-identity/didwebvh](https://github.com/decentralized-identity/didwebvh)
+
+```
+
+## Handling Version Transitions
+
+In the lifecycle of the specification, there will be times when the latest version is
+stable, with clarifications being added, and other times when new versions are being defined
+with breaking changes. We use the Spec-Up multiple versions feature
+(as described above) to support that, but it can get a little tricky. Notably, we want
+the landing page for the specification to **always** be the current version of
+the specification, **and** we want all "in progress" work to be to made to the
+single, primary specification -- the files in the `spec` folder -- so that GitHub
+holds the full history of the specification. To enable that, we adjust as
+needed the `"output_path"` in the `specs.json` file to define what version of
+the spec is on the specification landing page -- the spec version whose
+`"output_path"` is set to `"./"`).
+
+Here's how we do that in different situations:
+
+- When the specification is stable, the `spec` folder is the landing page, and
+ past versions are linked in that folder's `header.md` file as "past versions".
+- When a new version of the specification with breaking changes is ready to be worked on:
+ - Snapshot the stable specification version by creating a new directory (e.g.,
+ `spec-v0.4`) and copying the files from the `spec` folder into the new
+ folder.
+ - Create a new entry in the `specs.json` file for that new snapshot version.
+ - Set the `output_path` of the new version (e.g., `spec-v0.4`) to be `"./"`,
+ so that it becomes the landing page.
+ - Change the `output_path` of the primary `spec` folder entry to `"./next"`.
+ - Update the `header.json` files in both the new folder and the `spec` folder
+ to link to one another, adding any notes to help readers understand the
+ status of the current and next versions of the specification.
+- When the "next" version of the specification stabilizes, revert to the
+ "normal" state of the `spec` folder being the landing page.
+ - Change the `output_path` of the primary `spec` folder to `"./"`.
+ - Change the `output_path` of the formerly "current" spec version to a path
+ that includes its version (e.g., `"./v0.4"`).
+ - Update the `header.json` files in both the (now past version) folder and the
+ `spec` folder to link to one another's new `output_path` values, remove any
+ clarification notes that no longer apply, and make the past version "just
+ another" past version (e.g., like `spec-v0.3`)
diff --git a/index.html b/index.html
index aa254de..68a5fbc 100644
--- a/index.html
+++ b/index.html
@@ -6,7 +6,7 @@
- Spec-Up Example
+ DID /whois
@@ -15,10 +15,10 @@
code[class*=language-],pre[class*=language-]{color:#ccc;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}pre[class*=language-].line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:0;font-size:100%;left:-3.8em;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.line-numbers-rows>span{display:block;counter-increment:linenumber}.line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}
@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}
:root{--base-theme-color:207,71%;--themed-element-bk:hsl(var(--base-theme-color), 40%);--themed-element-text:#fff;--themed-element-border:1px solid hsl(var(--base-theme-color), 26%);--themed-heading-text:hsl(var(--base-theme-color), 30%);--no-color:255,255,255;--faint-color:245,245,245;--dim-color:225,225,225;--low-color:200,200,200;--mid-color:100,100,100;--high-color:50,50,50;--full-color:0,0,0;--active-color:#3aaaff;--visited-color:rgb(188, 129, 255);--green-status:rgb(0, 123, 9);--light-green-status:rgb(0, 194, 13);--page-bk:rgb(var(--no-color));--page-text:rgb(var(--full-color));--page-text-hover:rgb(var(--full-color));--element-bk:rgb(var(--no-color));--element-bk-hover:rgba(var(--low-color), 0.5);--element-bk-transparent:rgba(var(--dim-color), 0.92);--element-border:rgba(var(--high-color), 0.4);--element-border-focus:rgb(var(--full-color), 0.75);--element-border-radius:3px;--element-shadow-low:0 1px 3px 0px rgba(0,0,0, 0.25);--element-shadow-mid:0 1px 3px 0px rgba(0,0,0, 0.35);--element-shadow-high:0 1px 5px 0px rgba(0,0,0, 0.45);--code-bk:#1a1e23;--input-bk:rgba(var(--dim-color), 0.6);--input-border:rgba(var(--high-color), 0.4);--header-height:48px;--header-bk:rgba(var(--low-color), 0.985);--header-text:rgb(var(--full-color));--header-border:rgba(var(--full-color), 0.1);--header-border-inverse:rgba(var(--no-color), 0.3);--text-shadow:0 1px 2px rgba(0,0,0,0.8);--svg-size:2vw;--font-size:14px}:target{scroll-margin:calc(var(--header-height)/ .75) 0 0}body:not([hashscroll]) :target{animation:highlight 1.5s .25s ease}body{margin:0;padding:0;font-family:Heebo,san-serif;line-height:1.5em;widows:2;orphans:2;word-wrap:break-word;overflow-wrap:break-word;color:#000;word-spacing:1px;counter-reset:h2 toc1}h1{font-size:2em;font-weight:700;line-height:1.2em}h2{margin:1.5em 0 1em}blockquote{position:relative;padding:0;margin:1.75em .75em;color:rgb(var(--mid-color));background:rgb(var(--faint-color))}blockquote:after,blockquote:before{content:"“";position:absolute;top:.065em;left:.065em;font-size:3em;height:.34em;line-height:100%;color:rgb(var(--low-color))}blockquote:after{content:"”";top:auto;left:auto;bottom:.065em;right:.065em;text-align:center}blockquote>p{padding:.6em 1.8em .5em 1.8em}strong strong{font-size:.9em;color:#b30032;font-weight:400;text-transform:uppercase}main article>ol,main article>ul{padding:0 0 0 2em}main article h1,main article h2,main article h3,main article h4,main article h5,main article h6{color:var(--themed-heading-text)}main article h2,main article h3,main article h4{display:flex;font-weight:500}main article h2{counter-reset:h3 h4}main article h3{counter-reset:h4}main article h2:after{counter-increment:h2;content:counter(h2) ".";padding:0 .4em 0 .2em;order:-1}main article h3:after{counter-increment:h3;content:counter(h2) "." counter(h3);padding:0 .45em 0 .2em;order:-1}main article h4:after{counter-increment:h4;content:counter(h2) "." counter(h3) "." counter(h4);padding:0 .5em 0 .2em;order:-1}h1 .toc-anchor{display:none}.toc-anchor{margin:-.1em 0 0;font-size:.875em;color:inherit;text-decoration:none;opacity:.35;order:-1;transition:opacity .3s ease}.toc-anchor:hover{opacity:1}pre{overflow:auto}code{padding:.085em .3em .1em;font-size:1.075em;color:#c7001c;vertical-align:middle;background:#f0f0f0;border-radius:4px}pre code{background:unset;padding:unset;border-radius:unset}h1 code,h2 code,h3 code,h4 code,h5 code,h6 code{font-size:1.25em;margin:-.11em .3em 0 0;border-radius:3px}ol,ul{margin:0;padding:0 0 0 1.2em}dt{font-weight:700;margin:1em 0 0}dd{margin-left:1.5em}main{box-sizing:border-box;float:right;width:75%;min-width:calc(100% - 325px);max-width:calc(100% - 275px);padding:.5em 2em 1.5em 2em;background:#fff;box-shadow:0 0 5px -1px rgba(0,0,0,.3)}main table{display:block;width:-webkit-fill-available;width:fit-content;max-width:100%;margin:1.5em 0 1.75em;border-spacing:0;border-collapse:collapse;overflow-x:auto;word-wrap:normal;overflow-wrap:normal;hyphens:manual}main thead tr th{color:var(--themed-element-text);background:var(--themed-element-bk);border:var(--themed-element-border);text-shadow:0 1px 1px rgba(0,0,0,.5)}main tr{border-top:1px solid #ccc;background-color:#fff;margin:0;padding:0}main tr:nth-child(2n){background-color:#f0f0f0}main tr th{font-weight:400;border:1px solid #ccc;text-align:left;margin:0;padding:6px 13px}main td,main th{padding:9px 13px;border:1px solid #d8d8d8}main tr td{border:1px solid #ccc;text-align:left;margin:0;padding:.55em .75em .55em}main tr td :first-child,main tr th :first-child{margin-top:0}main tr td :last-child,main tr th :last-child{margin-bottom:0}table pre[class*=language-]{border:none;border-radius:0}table pre[class*=language-]:before{display:none}svg[icon]{width:1.25em;height:1.25em;vertical-align:text-top;pointer-events:none}article p>img{max-width:100%;margin:0 auto}article li{margin-top:.4em}slide-panel>:not(header):not(footer){flex:1}:not(pre)>code[class*=language-],pre[class*=language-]{padding:.65em .8em .8em;background:var(--code-bk)}.tippy-box{box-shadow:var(--element-shadow-mid)}.tippy-box a{color:var(--active-color)}.tippy-box a:visited{color:var(--visited-color)}.tippy-content{padding:.55em .55em .5em}.tippy-content header{margin:0 0 .4em;padding:.15em .3em .1em;border-radius:2px;background:rgba(255,255,255,.1);text-shadow:0 1px rgba(0,0,0,.9)}.tippy-content table,.tippy-content tbody,.tippy-content td,.tippy-content tr{margin:0;padding:0;border:none;border-spacing:0;border-collapse:collapse;background:0 0!important;background-color:transparent!important}.tippy-content table{margin:0 .3em}.tippy-content td{font-size:.9em;padding:.2em 0 0}.tippy-content td:first-child{padding-right:.5em}a[path-0$="github.com"]:before{content:"\f09b";color:var(--page-text);margin:0 .25em 0 0;font-family:FontAwesome;text-decoration:none;display:inline-block;vertical-align:bottom}a[path-0$="github.com"][path-3=issues][path-4],a[path-0$="github.com"][path-3=projects],a[path-0$="github.com"][path-3=pull],a[path-0$="github.com"][path-3=releases]{text-decoration:none}a[path-0$="github.com"][path-3=issues][path-4] span,a[path-0$="github.com"][path-3=projects] span,a[path-0$="github.com"][path-3=pull] span,a[path-0$="github.com"][path-3=releases] span{display:none}a[path-0$="github.com"][path-3=issues][path-4]:after{content:"Issue #" attr(path-4)}a[path-0$="github.com"][path-3=pull]:after{content:"Pull Request #" attr(path-4)}a[path-0$="github.com"][path-3=releases][path-5]:after{content:"Release " attr(path-5)}a[path-0$="github.com"][path-3=projects]:after{content:"Project #" attr(path-4)}[issue-count]:after{content:"Issues (" attr(issue-count) ")";margin:0 0 0 .3em;padding:.1em 0 0}[issue-count=""][animate]{display:none;opacity:0}[issue-count][animate]:not([issue-count=""]){animation:display-show 1s}[panel-toggle]{cursor:pointer}.panel-header{display:flex;align-items:center;height:var(--header-height)}.panel-header>*{display:flex;height:100%;padding:.1em .8em 0;align-items:center}.slide-panel{width:calc(100% - 1em);max-width:475px;transition:transform .35s ease}.slide-panel[panel-open]{transform:translateX(0)}.notice{margin:1em 0;padding:.5em .9em .55em .65em;border-left:.5em solid}.notice p{margin:.4em 0 0}.note{background:#e9fbe9;border-color:#52e052}.note .notice-link{display:block;color:#178217}.issue{background:#e9f0fb;border-color:#527fe0}.issue .notice-link:before{display:block;color:#1e4cae}.warning{background:#fbe9e9;border-color:#e05252}.warning .notice-link{display:block;color:#ae1e1e}.example{color:#cebe00;background:#1a1e23;border-left:.5em solid}.example .notice-link{display:block;color:inherit;font-size:1.1em;font-family:Heebo,san-serif}.example pre[class*=language-]{padding:0;border-radius:0}.todo{background:#fbe4ff;border-color:#9700e2}.todo .notice-link{display:block;color:#6d00a2}.mermaid{display:flex;align-items:center;justify-content:center;margin:1.5em 0 1.75em}.reference-list{margin:0;padding:0;list-style:none}.reference-list dd a,.reference-status{font-style:italic}.reference-status{color:var(--green-status)}.tippy-box .reference-status{color:var(--light-green-status)}code[class*=language-],pre,pre[class*=language-]{font-size:.9em;margin:1em 0 1.5em;border-radius:3px}.example code[class*=language-],.example pre,.example pre[class*=language-]{margin:0}#svg{display:none}#header{position:sticky;position:-webkit-sticky;padding:0;top:0;margin:-.5em -2em 0 -2em;background:rgba(255,255,255,.9);border-bottom:1px solid rgba(0,0,0,.175);box-shadow:0 1px 3px 1px rgba(0,0,0,.1);z-index:2}#logo{box-sizing:border-box;display:flex;align-items:center;height:100%;padding:.5em}#logo img{height:100%}#logo+span{margin-left:auto}#header #toc_toggle{display:none;padding:0 1em;border-right:1px solid rgba(0,0,0,.15)}#content{max-width:800px}#content h1:first-of-type{margin:1em 0 .5em}#content h1:first-of-type .markdownIt-Anchor{display:none}#repo_issues{width:calc(100% - 1.5em);max-width:450px;border-left:1px solid rgba(0,0,0,.15)}#repo_issues>header{background:#eee;border-bottom:1px solid #ddd}#repo_issues>header span:first-of-type{font-weight:700;padding-top:.1em}#repo_issues>header .repo-issue-toggle{margin-left:auto;color:inherit;font-weight:700;text-decoration:none}#repo_issue_list{list-style:none;margin:0;padding:0 1.25em 1.25em;font-size:.85em;overflow:auto;-ms-overflow-style:none;scrollbar-width:none}#repo_issue_list::-webkit-scrollbar{display:none}#repo_issue_list:empty:before{content:"No issues found";display:block;text-align:center;font-size:1.1em;color:#aaa;margin:1em 0 0}.repo-issue detail-box{display:flex;flex-direction:column;padding:1em 0;border-bottom:1px solid #ddd}.repo-issue detail-box>section{order:1}.repo-issue detail-box>section:empty+.repo-issue-title [detail-box-toggle]{display:none}.repo-issue-title{display:flex;align-items:center}.repo-issue-link{flex:1;margin:0 0 0 .5em}.repo-issue-number{height:1em;margin:0 .4em 0 0;padding:.3em .25em 0;border-radius:3px;font-weight:700;background:#eee;border:1px solid #ddd;text-align:center;line-height:1em}.repo-issue-number:before{content:"#";font-weight:400;margin:0 .1em 0 0}.repo-issue [detail-box-toggle]{margin:0 0 0 1em;opacity:.35;transition:opacity .4s}.repo-issue [detail-box-toggle]:hover,.repo-issue detail-box[open] [detail-box-toggle]{opacity:1}#toc{display:flex;flex-direction:column;width:25%;max-width:325px;min-width:275px;background:#eceff1}#toc header{color:var(--themed-element-text);background:var(--themed-element-bk);box-shadow:0 1px 3px 0 rgba(0,0,0,.3);border:var(--themed-element-border);border-top:none;border-left:none}#toc header [panel-toggle]{display:none;height:var(--header-height);line-height:var(--header-height);margin-left:auto;padding:0 1em;color:inherit;font-weight:700;text-decoration:none}#toc_list{flex:1;padding:1em .8em;overflow:auto}.toc{padding:0 0 1.75em;font-size:.85em}.toc,.toc ul{margin:0;list-style:none}.toc ul{padding:0 0 0 1em}.toc a{display:block;padding:.4em .3em .225em;text-decoration:none;border-radius:3px;color:#333}.toc a:before{color:#000;font-weight:700}.toc a:hover{text-shadow:0 1px 1px #fff;background:rgba(0,0,0,.1)}.toc>li a:before{counter-increment:toc1;content:counter(toc1) ".";padding:0 .4em 0 .2em}.toc>li>ul{counter-reset:toc2}.toc>li>ul>li a:before{counter-increment:toc2;content:counter(toc1) "." counter(toc2);padding:0 .45em 0 .2em}.toc>li>ul ul{counter-reset:toc3}.toc>li>ul ul li a:before{counter-increment:toc3;content:counter(toc1) "." counter(toc2) "." counter(toc3);padding:0 .5em 0 .2em}@media (min-width:900px){slide-panel{z-index:2}#slidepanels[open=sidebar]:before{opacity:0;transition:none;pointer-events:none}#slidepanels:before{z-index:1}#toc{transition:none;transform:translate3d(0,0,0);box-shadow:0 0 5px 1px rgba(0,0,0,.15) inset;z-index:0}}@media (max-width:900px){main{width:100%;min-width:auto;max-width:none;padding:.5em 1.25em 1.5em 1.25em}#header{margin:-.5em -1.25em 0 -1.25em}#toc header [panel-toggle]{display:block}#header #toc_toggle{display:flex}}@media (max-width:550px){td{font-size:.8em}}@keyframes display-show{0%{display:none;opacity:0}1%{display:block}100%{opacity:1}}@keyframes highlight{50%{background-color:#ff0}}
-
+
-
+
@@ -38,8 +38,8 @@
-
-
+
+
@@ -47,611 +47,230 @@
-
Let’s face it, other tools and generators for writing technical specifications aimed at standards bodies or industry groups are cumbersome, underwhelming, and lack the features you might want in a technical specification document. Spec-Up’s goal is to deliver you a better spec-writing experience with far less effort and tedium than other tools in the ecosystem. Spec-Up is a simple tool that auto-generates great specs from markdown. The version of markdown Spec-up uses contains all the same features you might expect from common implementations, like GitHub, but adds much more, including notice blocks, complex tables, charts, advanced syntax highlighting, UML diagrams, etc.
This document introduces a standardized <did>/whois DID URL path that provides a decentralized mechanism to retrieve a verifiable presentation published by the DID Controller, containing verifiable credentials about the DID and the entity controlling the DID.
The <did>/whois path introduces a convention for all DID Methods to enable a
+resolver to learn more about the public identity of a DID Controller through the
+discovery of Verifiable Credentials about the DID. Inspired by the WHOIS [RFC3912]
+protocol from the early ARPANET days, this feature allows resolving
+<did>/whois to retrieve a Verifiable Presentation (VP) containing Verifiable
+Credentials containing public information about the DID Controller. This capability provides:
+
+
A decentralized mechanism for querying verifiable information about DIDs.
+
A trust model based on cryptographic verification of attestations from
+(possibly domain specific) authorities rather than centralized registries.
+
+
When <did>/whois is resolved using a DID service compliant with the [LINKED-VP], the response is a Verifiable Presentation (VP)
+signed by the DID. The VP may contain:
+
+
Information about the DID and the legal entity of the DID Controller that the
+DID Controller wants to be made public.
+
Verifiable Credentials (VCs) with the DID as the credentialSubject that may
+bind other identifiers (legal name, legal entity registration identifiers,
+etc.) to the DID.
+
VCs with other identifiers bound (via other VCs in the VP) to the DID as the
+credentialSubject.
+
+
For example, a VC in the VP may use the DID as the credentialSubject,
+published by an authority, indicating the DID is associated with a legal entity
+with a set of identifiers—such as the legal name of the entity and a
+registration identifier (e.g., an LEI as published by GLEIF). A second VC in
+the VP might use the entity identifier from that first VC as the
+credentialSubject to include attestations such as ISO certifications. The
+resolver decides whether to trust the issuers of the VCs, potentially using
+/whois with those DIDs to gather information about their identity.
Consider the DID Controller of a mining company exporting a “product”
+– a shipment of the material produced by their mine. The company publishes a
+“Digital Product Passport” (DPP) in the form of a Verifiable Credential about
+the shipment. An importer resolves the product identifier and retrieves and
+verifies the DPP. It wants to know who it was that issued the (self-attested)
+DPP verifiable credential. It finds in the DPP the DID of the issuer and then
+resolves <did>/whois. The mining company has published a VP about its DID,
+putting the following verifiable credentials containing public information into
+the VP and signing it with its DID:
-
npm install spec-up
+
A Verifiable Credential attesting to the Legal Entity’s Registration:
+
+
Details such as the company’s legal name, registration date, and contact information might be included.
+
The credentialSubject of the VC is the same DID that signed the DPP, and the /whois VP.
+
This enables the importer to identify and verify the legitimacy of the company.
+
If necessary, the importer can resolve the <did>/whois of the issuer of the VC to learn more about them.
+
-
Create a specs.json file in the root folder of your repository to specify configuration values used in the generation of your spec documents. The values in your specs.json file include things like where your spec’s markdown files are located, where to output the generated spec document, and various metadata values used in rendering, such as the title, logo, and repo links for each of your specs. The following are the required/optional fields supported in the specs.json config file:
+
A Verifiable Credential for a Mining Permit:
-
spec_directory(STRING, required) - You must specify the repo-root-relative location of your spec’s markdown file directory. You MUST name your spec’s markdown file spec.md and locate it in your spec_directory for the tool to automatically find and use it for rendering. If you want to use a different name for the markdown file, or you have multiple markdown files you would like the tool to assemble into one document, you must specify them using the optionalmarkdown_paths field described below. See the “multi-file” example in the spec-up repo.
-
title(STRING, required) - You must add a title for your spec, which will be rendered in the generated document’s H1 text and page title.
-
markdown_paths(ARRAY, optional) - If you want to name your spec’s markdown file something other than spec.md, or you have multiple files you would like assembled into a single output document, you must specify their paths as array entries in the order you would like them assembled. The paths in this array are assumed to be based on the spec_directory you specified, so DO NOT repeat the full root relative path.
-
katex(BOOLEAN, optional) - To enable TeX support via KaTeX, set this property to true. After rendering, be sure to copy the fonts/ subdirectory, containing the necessary web fonts.
-
output_path(STRING, optional) - If you want the generated spec document to be output to a different location than the spec_directory you specified (e.g. the project root for GitHub Pages publishing) you can specify another root relative path (use ./ for root), and the tool will write the document file there instead.
+
Issued by the mining authority (likely a government) in the company’s jurisdiction.
+
This second VC might use the company’s legal name as the
+credentialSubject rather than the entity’s DID. The data in the first VC
+provides the binding from the legal name to the DID.
+
Allows further resolution of the mining permit VC’s DID and its /whois
+path for additional validation.
-
In your main node.js file, drop in this bad boy: require('spec-up')()
+
A Verifiable Credential for Auditing Practices:
+
+
Details about the company’s compliance with standards audited by a trusted entity.
+
Further resolution of the auditor’s DID /whois path may verify its accreditation.
+
-
Boom! That’s it. Spec-Up will auto-detect modifications to files in your spec_directory and auto-generate your spec’s updated HTML document every time you save a change.
-
Usage
-
If your spec.json and package.json and package-lock.json files are in working order and in the root folder of the repo from which it will be deployed, Spec-up can be called by command line (from the root of your repo) in three different modes:
-
-
-
-
command
-
behavior
-
-
-
-
-
npm run edit
-
after rendering, this will stay running and the gulp library will watch the source files in your spec directory/ies for changes and re-render any time you save a file. Opening these rendered files in a browser and refreshing them will keep you up to date.
-
-
-
npm run render
-
this renders the site once and does not keep a gulpy watch on the underlying files.
<-- You see that beautiful TOC over there to your left? (tap the header link to slide it out on mobile) Yeah, you don’t need to do a damn thing, that just magically appears based on your use of h2, h3, and h4 headings.
Many specs may want to include a section for terminology references, and Definition Lists are a great way to do that. Here’s how to leverage Spec-Up’s automatic term reference features via Definition List markup:
-
-[[def: Term 1, Term One]]:
-~ This is the first term we will define.
-
-[[def: Term 2, Term Two]]:
-~ This is the second term, but not the last.
-
-[[def: Term 3, Term Three]]:
-~ This is the last term, because you know what they say: third term's the charm!
-
-
-
Term 1:
-
This is the first term we will define.
-
Term 2:
-
This is the second term, but not the last.
-
Term 3:
-
This is the last term, because you know what they say: third term’s the charm!
-
-
Now let’s refer to some of the terms defined above to show how the auto-linking of terms works: Term 1, Term Two, Term 3. Additionally, as long as you define your terms using Definition Lists (as seen in the markdown above), you will be able to hover any reference to a term to see a tooltip with its definition.
You can also reference table-oriented terms and definitions which are decomposed into heading-titled attributes in distinct cells:
-
-Variable | Default Value | Max Value
-------------------- | -------------- | ---------
-[[def: Variable 1]] | 123 | 9999
-
-
-
-
-
Variable
-
Default Value
-
Max Value
-
-
-
-
-
Variable 1
-
123
-
9999
-
-
-
-
Anytime you add a definition of a term in the first column of a table, like Variable 1, it will link to the cell and display a tooltip with the entire set of row values when you hover the term.
It is possible to include references to terms from external spec-up generated specifications. To include a source you would like to pull references from include an external_specs array in your spec config. The value should be a key/value object where the key is used in the external reference below and the value is the URL of the external spec.
To include an external term reference within your spec use the following format [[xref: {title}, {term}]] where {title} is the title given to the spec in the config and {term} is the term being used. For example using the PE spec given in the example above Holder
To be, or not to be, that is the question:
-Whether 'tis nobler in the mind to suffer
-The slings and arrows of outrageous fortune,
-Or to take arms against a sea of troubles
-And by opposing end them. To die—to sleep,
-No more;
// Some comment in JSON
-{
- "foo":"bar",
- "baz":2
-}
+
The mining company determines what VCs it wants to publish in its /whois VP,
+and the importer resolving the DPP can resolve “up the hierarchy” of the various
+VCs to find the authorities issuing the collection of VCs. In the end, the
+importer software may recognize and trust the authorities issuing the VCs and
+make a trust decision on the mining company. If not, the software can take the
+collected information (VCs and issuers) and pass that along to a person to make
+the trust decision.
Use the following format to pull in content from other files in your project:
-
-This text has been inserted here from another file: [[insert: ./single-file-test/assets/test.text]]
-
-
This text has been inserted here from another file: Beam me in, Scotty!
-
You can even insert content within more complex blocks, like the JSON object below which is being pulled in and rendered in a syntax-highlighted example block:
-
-::: example Code Example
-```json
-[[insert: ./single-file-test/assets/test.json]]
-```
-:::
-
Resolve the DID and retrieve and verify the DIDDoc.
+
Locate the <did>#whois service in the resolved DID Document. This service MUST be of type LinkedVerifiablePresentation.
+
+
A DID Method MAY define an implicit #whois service that useful for that DID Method. For example, the [DIDWEBVH] DID Method has a DID-to-HTTPS-URL transformation used when resolving the DIDDoc, and implicitly defines a #$whois service that uses the same DID-to-HTTPS transformation to define the location of the whois.vp resource. A DID ControllerMAY explicitly include a #whois service in their DID Document, overriding the implicit #whois service.
+
+
+
Resolve the serviceEndpoint to obtain the Verifiable Presentation.
+
Verify the VP and the VCs in the VP.
+
Parse the VP to extract Verifiable Credentials and associated metadata.
+
Optionally resolve the /whois path of issuers of the VCs for further trust validation as needed and available.
-```mermaid
-sequenceDiagram
- Alice ->> Bob: Hello Bob, how are you?
- Bob-->>John: How about you John?
- Bob--x Alice: I am good thanks!
- Bob-x John: I am good thanks!
- Note right of John: Bob thinks a long long time, so long that the text does not fit on a row.
-
- Bob-->Alice: Checking with John...
- Alice->John: Yes... John, how are you?
-```
-
-
-sequenceDiagram
- Alice ->> Bob: Hello Bob, how are you?
- Bob-->>John: How about you John?
- Bob--x Alice: I am good thanks!
- Bob-x John: I am good thanks!
- Note right of John: Bob thinks a long long time, so long that the text does not fit on a row.
-
- Bob-->Alice: Checking with John...
- Alice->John: Yes... John, how are you?
-
When the katex option is enabled, the KaTeX math engine is used for TeX rendering. You can find a list of supported features and examples here: https://katex.org/docs/supported.html.
Spec-Up automatically upgrades the links of certain sites, like GitHub. GitHub is the only supported site with Fancy Links right now, but we’ll be adding more as we go.
Such a VC MAY attest to the binding of other identifiers to the DID. For example, the VC may be from an authority that attests to the legal name and registration identifier of the entity controlling the DID.
-
Pull Requests
+
The credentialSubject of other VCs may be identifiers cryptographically bound in other VCs within the VP to the DID being resolved.
For example, the legal name or legal entity registration identifier could be the credentialSubject if another VC in the VP binds that identifier to the DID.
-
Releases
+
The DID Controller determines which Verifiable Credentials to include based on their usefulness for establishing the identity and trustworthiness of the entity controlling the DID.
+
The resolver determines which Verifiable Credentials are useful in its determination of the identity and trustworthiness of the entity controlling the DID.
+
+
What Verifiable Credentials and who should issue those credentials are outside
+of the scope of this specification. A future version of the specification may
+define at least a credential that binds the DID to the other identifiers used
+by/assigned to the legal entity controlling the DID. For example, the
+United Nations Transparency Protocol’s Digital Identity Anchor might be a good
+candidate for a standard VC to bind the DID to the legal entity of the
+controller.
You can reference external specifications from IETF, W3C, and WHATWG as follows:
-
-
Anywhere in your document you want to referece an external specification, use the spec-prefixed custom token format: [[spec:RFC4122]]
-
Wherever in your document you want to print out all your external specification references, use the spec custom token format without any spec name: [[spec]]
-
+
+
Access Control:
-
If you want to split up your references into groups (e.g. normative vs informative), just make sure to use dash-delimited unique reference grouping string in your custom tokens: [[spec-norm:RFC4122]], [[spec-inform:RFC4122]], [[spec-foo:RFC4122]], etc.
-
To print out a custom group’s references, just include the grouping string for a given set of references in a custom token without any spec name: [[spec-norm]], [[spec-inform]], [[spec-foo]].
+
There is not an intention to limit access to the /whois service endpoint. It is the responsibility of the DID Controller to ensure that only Verifiable Presentations containing public information are published at the service endpoint.
+
Personally identifiable information (PII) MUST NOT be published to the <did>/whois service endpoint.
-
Here are a set of example references that are distributed among the reference groups spec, spec-norm, spec-inform:
The /whois path standardizes a decentralized mechanism for retrieving verifiable information about DIDs. It empowers trust decisions through cryptographic verification and promotes interoperability across decentralized systems.
The DID Controller is the entity that has the authority to update its DID. In
+the context of this specification, the DID Controller is the entity
+represented by the DID. The <did>/whois capability will most often be used
+by legal entities that want to establish a Verifiable Credential-backed
+linkage between their DID and their legal entity, attested to be a suitable
+authority.
+
W3C Verifiable Presentation
+
A Verifiable Presentation as defined in the W3C [[spec:vcdm]].
- DID Specification Registries.
- Orie Steele; Manu Sporny; 2023-09-11. Status: NOTE.
+ did:webvh DID Method.
+ Stephen Curran; John Jordan; Brian Richter; Andrew Whitehead; Michel Sahli; Martina Kolpondinos; Dmitri Zagdulin; 2024-12-20. Status: Draft.
Features enable Verifiers to express, and Holders to support,
-extended functionality (relative to the base objects) by defining one or more
-properties on one or more objects.
Feature
Features enable Verifiers to express, and Holders to support,
-extended functionality (relative to the base objects) by defining one or more
-properties on one or more objects.
Some examples refer to an unfamiliar query protocol, dwn://, as a way of
-storing and querying schemata and other resources. While orthogonal to this
-specification and not yet on a standards track, the concept of “decentralized web nodes”
-proposes an architecture that may be of interest or utility to implementers of
-this specification. For more information, see the draft specification
-hosted at the decentralized identity foundation
-here
Decentralized Web Node
Some examples refer to an unfamiliar query protocol, dwn://, as a way of
-storing and querying schemata and other resources. While orthogonal to this
-specification and not yet on a standards track, the concept of “decentralized web nodes”
-proposes an architecture that may be of interest or utility to implementers of
-this specification. For more information, see the draft specification
-hosted at the decentralized identity foundation
-here
Input Descriptor
Input Descriptors are used by a Verifier to describe the information required
-of a Holder before an interaction can proceed. See
-Input Descriptor.
Input Descriptor
Input Descriptors are used by a Verifier to describe the information required
-of a Holder before an interaction can proceed. See
-Input Descriptor.
Input Descriptor Object
Input Descriptors Objects are populated with properties describing what type
-of input data/Claim, or sub-fields thereof, are required for submission
-to the Verifier. See
-Input Descriptor Object.
Input Descriptor Object
Input Descriptors Objects are populated with properties describing what type
-of input data/Claim, or sub-fields thereof, are required for submission
-to the Verifier. See
-Input Descriptor Object.
Link Secrets
Link Secrets are values held by the Holder but hidden from other
-parties. They are typically incorporated into cryptographic signatures used in
-claims to demonstrate correlation while preventing replay attacks. An Issuer
-may ascertain that a Holder possesses a link secret without its disclosure.
-See Link Secrets.
Presentation Definition
Presentation Definitions are objects that articulate what proofs a Verifier
-requires. These help the Verifier to decide how or whether to interact with a
-Holder. Presentation Definitions are composed of inputs, which describe
-the forms and details of the proofs they require, and optional sets of
-selection rules, to allow Holders flexibility in cases where many different
-types of proofs may satisfy an input requirement. See
-Presentation Definition.
Presentation Request
Presentation Requests are transport mechanisms for Presentation. Presentation Requests can take multiple shapes, using a variety
-of protocols and signature schemes not refined in this specification. They are
-sent by a Verifier to a Holder. Defining Presentation Requests
-is outside the scope of this specification. See
-Presentation Request.
Presentation Submission
Presentation Submissions are objects embedded within target claim negotiation
-formats that unify the presentation of proofs to a Verifier in
-accordance with the requirements a Verifier specified in a
-Presentation Definition. See
-Presentation Submission.
Subject
Subjects are the entities about which Claims are made. The Subject may
-not be the same entity as the Holder
Subject
Subjects are the entities about which Claims are made. The Subject may
-not be the same entity as the Holder
Submission Requirement
Submission Requirements are objects that define what combinations of inputs
-must be submitted to comply with the requirements a Verifier has for
-proceeding in a flow (e.g. credential issuance, allowing entry, accepting an
-application). See Submission Requirements.
Submission Requirement
Submission Requirements are objects that define what combinations of inputs
-must be submitted to comply with the requirements a Verifier has for
-proceeding in a flow (e.g. credential issuance, allowing entry, accepting an
-application). See Submission Requirements.