Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define service DID document and add did:web endpoint #53

Closed
letmaik opened this issue Dec 20, 2022 · 2 comments · Fixed by #85
Closed

Define service DID document and add did:web endpoint #53

letmaik opened this issue Dec 20, 2022 · 2 comments · Fixed by #85
Assignees
Labels
enhancement New feature or request

Comments

@letmaik
Copy link
Member

letmaik commented Dec 20, 2022

The goal is to experiment with representing the service's receipt trust anchors across disaster recoveries through a stable DID.

#25 was a first step towards that goal which allows setting the service DID and including it in receipts. The next step is to define what the corresponding DID document would look like when using did:web and exposing it under GET <domain>/.well-known/did.json.

There are some challenges that need to be solved:

Usage of JWK

Verification material in DID documents is expressed using one or more JWKs (JSON Web Key), where each JWK represents a public key. The expectation is that the public key verifies the signature of what was signed.

In CCF, there is a hierarchy of service key and node key, both wrapped in certificates. The node key differs per node and is the one that signs the tree root and hence is used to verify receipt signatures. The service key only changes when a disaster recovery event occurs.

There are two options:

Option A: Node public keys could be exposed in the DID document which would make most sense from a DID point of view but is not economical as the list will grow too large very quickly.

Option B: Service public keys could be exposed in the DID document which makes more sense from a trust anchor and efficiency point of view but doesn't seem to be immediately compatible with existing DID practices.

To make Option B work, the details of CCF including the indirection through the node certificate could be hidden behind the receipt/tree algorithm, whose interface would receive the service key and internally uses the node key and node certificate for verification after checking that the node certificate was signed by the service key.

Validation using historic keys

Receipts shall always be verifiable, even if they are old and the current signing keys of a service are not the ones used in the old receipts.

From the point of CCF, old service keys can be considered as valid only for the range of transactions for which they were in use. The current service key has no upper bound, until a disaster recovery happens.

In DID, the only standard way to restrict the use of a key to validate new signatures is by either including or not including it in the DID document. If a DID method supports retrieving old versions of DID documents via versionId or versionTime and a signature includes that metadata and there is a reliable way to establish the point in time at which the signature was made, then resolving an old DID document state would allow to retrieve the correct key and verify the signature. did:web does not support this.

Option A: Include all historic keys and add non-standard metadata to each key which restricts its use. This could be a transaction sequence range, though currently the sequence numbers are not exposed in receipts. It could also be a time range, though CCF does not record time in general.

Option B: ?

@letmaik letmaik added the enhancement New feature or request label Dec 20, 2022
@plietar plietar self-assigned this Jan 6, 2023
@plietar
Copy link
Contributor

plietar commented Jan 9, 2023

I had a stab at this, and unfortunately it seems CCF does not currently allow us to use the /.well-known path.

Their ACME subsystem needs to host files under /.well-known/acme-challenge, and because of this it registers a frontend on the whole /.well-known prefix, which intercepts all requests to that prefix (even when ACME is not enabled).

Ideally, the ACME subsystem would only look at that sub-directory, rather than the entire well-known path, but at a glance it seems CCF "actors" always bind an entire top-level name.

cc @achamayou

plietar added a commit that referenced this issue Jan 19, 2023
A DID document is hosted at /scitt/did.json, allowing the service
identifier to be resolved through did:web.

For now, the document only includes the current service certificate, but
in the future this will be included to include past certificates too,
allowing historical receipts to be verified.

Related to #53
plietar added a commit that referenced this issue Jan 25, 2023
This replaces the direct KV lookup with an indexing strategy that
collects and keeps in memory all past identities. This allows the
endpoint to return a full DID document with all these identities,
without the need for historical queries and retries.

This PR adds support for disaster recovery to our test infrastructure,
by restarting the cchost process. Because cchost port numbers are
randomly assigned by the operating system, there would not be a stable
address on which to contact the service. This is problematic both
because we'd have to update `Client` instances to point to the new
service, and because the service's address is used as its did:web long
term identifier. To circumvent both problems, a Python TCP proxy is
used, listening on a unique port for the entire duration of a test, and
dynamically switching the destination of connections as the cchost
process is restarted.

Fixes #53
@letmaik
Copy link
Member Author

letmaik commented Jan 25, 2023

To summarize #68 and #85, what we have now is a did:web endpoint that exposes the current and all historic service public keys and certificates in the DID document. This is option B of "Usage of JWK" and partly option A of "Validation using historic keys".

What's missing is to ideally get rid of certificates and also include usage metadata for historic keys to restrict them to specified transaction ranges. A minor issue that requires a CCF fix is that the endpoint isn't exposed at .well-known but rather under a scitt subfolder, just because CCF's built-in endpoints already reserve the whole .well-known/ prefix.

I will open new issues to track the remaining points.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants