diff --git a/README.md b/README.md index 3f44bd3..935d144 100644 --- a/README.md +++ b/README.md @@ -118,36 +118,58 @@ private keys). #### action, allowed action +A list of operations that the holder of the zcap is allowed to perform on the +[target](#target-invocation-target), provided they can provide an invocation +signature. + #### agent Any entity, usually an app (mobile, desktop or web app), an AI agent, or cloud microservice, capable of generating or storing cryptographic material (at least a public/private [keypair](#key-cryptographic-key)) so that it can prove cryptographic control over its identifier. -#### allowed actions - #### attenuation #### Authorization header +An HTTP header typically used to carry request authorizations. +See [Constructing the Authorization Header](#constructing-the-authorization-header). -#### capability chain +#### capability chain, proof chain #### caveat See [attenuation](#attenuation). #### controller +The [DID](#did-decentralized-identifier) of the [agent](#agent) authorized to +invoke a capability. #### data integrity proof +A way to cryptographically sign a structured document (like a JSON object), used +for chained delegation proofs. +See the [Verifiable Credential Data Integrity 1.0](https://www.w3.org/TR/vc-data-integrity/) +specification for more details. #### delegation #### Digest header +An HTTP header containing a digest hash of the request body. +See [Constructing the Digest Header](#constructing-the-digest-header). #### DID, Decentralized Identifier +See [Decentralized Identifier 1.1](https://www.w3.org/TR/did-1.1/) spec #### expiration +An optional zcap property with a timestamp determining when a zcap expires. +The timestamp is a string, in [XML-Schema dateTimeStamp](https://www.w3.org/TR/xmlschema11-2/#dateTimeStamp) +format (web developers may be familiar with this format from the Javascript +[`toISOString()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +function). #### HTTP Signatures +Refers to [RFC9421: HTTP Message Signatures](https://www.rfc-editor.org/rfc/rfc9421.html), +a specification that details how to sign HTTP requests (headers and body). +However, see the [Current vs Future Deployments](#current-vs-future-deployments) +section for more discussion. #### invocation, capability invocation The _act_ of invoking a capability at the intended destination ([resource @@ -160,16 +182,34 @@ thus proving possession of the badge, even if not cryptographicaly) would be the equivalent of invoking a capability. #### key, cryptographic key - -#### proof chain +Used to sign capability invocations, HTTP headers, and to generate delegation +proofs. For zCaps specifically, this is likely to be an asymmetric key pair, +using an appropriate elliptic curve such as `ed25519`. #### resource server, RS +A server hosting a resource that's protected by an authorization capability. +For API use cases, it's the API server itself, for storage use cases, it's +the actual file or database server hosting the individual objects specified in +`invocationTarget`. +Note: The RS is ultimately responsible for verifying and enforcing zCaps. #### revocation +A way to revoke (make invalid) a given zcap, after it was issued. #### root zcap +Using zCaps to make authorization-carrying HTTP requests is done in one of two +modes: either using a [root capability](#root-zcap), or using a delegated +capability. + +Root zcaps are used in cases where full "admin" access is appropriate. +All other zcaps are delegated by the agent holding a root zcap. Delegation +is expressed in the [proof chain](#capability-chain-proof-chain) section of a +zcap. + +See [Creating a Root zCap](#creating-a-root-zcap) #### signer +See [Creating a did:key Signer Instance](https://github.com/digitalcredentials/wallet-attached-storage#creating-a-didkey-signer-instance) #### target, invocation target @@ -242,9 +282,8 @@ Example root zcap: #### Delegating a zCap ```js -import { ZcapClient } from '@digitalbazaar/ezcap'; -import { Ed25519Signature2020 } from '@digitalbazaar/ed25519-signature-2020'; -import { ZcapClient } from '@digitalbazaar/ezcap'; +import { Ed25519Signature2020 } from '@digitalcredentials/ed25519-signature-2020'; +import { ZcapClient } from '@digitalcredentials/ezcap'; const zcapClient = new ZcapClient({ delegationSigner: capabilityDelegationKey.signer(), @@ -341,6 +380,67 @@ Example zCap request: ## Using zCaps with HTTP Requests +### Code Examples + +Although this guide goes into the details (below) of how to construct an HTTP +request using zCaps for authorization, developers are likely to interact with +zCaps using some sort of REST client with a wrapper that constructs the +necessary headers. + +Javascript example, using a [root capability](#root-zcap) to make requests. +Note that to use a root zcap, the client needs to know just two things: + +1. Which cryptographic key type to use (that's the `Ed25519Signature2020` suite) +2. A [signer](#signer), which is an abstract handle to a signature function. + Signers are either provisioned at config time (with a private key loaded from + an environment secret), or, preferably, used via an HSM (Hardware Security + Module). + +```js +import { Ed25519Signature2020 } from '@digitalcredentials/ed25519-signature-2020' +import { ZcapClient } from '@digitalcredentials/ezcap' + +const rootSigner = await loadOrConstructRootSigner() + +// Construct a client, pass it the ability to sign requests (via invocationSigner) +const zcapClient = new ZcapClient({ + SuiteClass: Ed25519Signature2020, invocationSigner: rootSigner +}) + +// You can now perform authorization-carrying requests +const url = 'https://example.com/api/protected-endpoint' + +const response = await zcapClient.request({ + url, method: 'GET', action: 'GET' +}) +console.log(response) +``` + +When using a [delegated](#delegating-a-zcap) zcap, you will need to also include +it in each request. Example: + +```js +const capability = await loadDelegatedCapabilityFromConfig() +const invocationSigner = await loadSignerFromConfig() +const zcapClient = new ZcapClient({ + SuiteClass: Ed25519Signature2020, invocationSigner +}) + +// You can also include additional custom headers +const response = await zcapClient.request({ + url, capability, headers, + method: 'POST', action: 'POST', json: { hello: "world" } +}) +console.log(response) +``` + +### Constructing an HTTP Request Algorithm Overview + +Note: This section is mostly for the benefit of zCap library implementers. +Developers wishing to use zCaps to make requests are encouraged to use existing +libraries whenever possible, such as the `@digitalcredentials/ezcap` Javascript +library. + To create an authorized HTTP request by [invoking](#invocation-capability-invocation) a given zcap, follow this general algorithm: