Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 108 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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:

Expand Down