{
$TYPE: $IDENTIFIER,
"cap": $CAPABILITY
}
type Capability = {
[rsc: string]: string
cap: string
}
interface Capability<OP extends string> = {
cap: OP
[constraint: string]: unknown
}
cap
discriminant.
export interface Capability<
OP extends Uppercase<string>,
ID extends string
> extends Constraints {
cap: OP
id?: ID
}
export interface Constraints {
[key: string]: number | string | undefined
}
PUT /uploads/did:key:foo/
{
"cap":"PUT"
"id": "/uploads/did:key:gozala/"
}
const capabilities = [
{ // Capability to add stuff to namespace
cap: "POST", // Action
id: `/uploads/${user}/`, // Resource
// Constraints for this capability
storageLimit: 32 * 1.1e12, // 1TiB,
},
{ // Capability to list stuff in user namespace
cap: "LIST", // Action
id: `/uploads/${user}/`, // Resource
}
]
const root = UCAN.build({
issuer: service.keypair, // ๐ค who grants access
audience: user, // ๐จ๐ฝโ๐ป who is granted access
lifetimeInSeconds: 24 * 60 * 60, // โฑ how long
capabilities // ๐ช
})
const constrainedCapabilities = [
{ // Add stuff to user subspace
cap: "POST", // Action
id: `/uploads/${user}/${scope}/`, // ๐จ๐ฝโ๐ป๐ช๐งค๐จโ๐จ
storageLimit: 1.074e9, // 1GiB,
},
{ // List stuff in user subspace
cap: "LIST",
id: `/uploads/${user}/${scope}`, // ๐จ๐ฝโ๐ป๐ช๐งค๐จโ๐จ
},
{
// List stuff in public subspace
cap: "LIST",
id: `/uploads/${user}/public`, // ๐จ๐ฝโ๐ป๐ช๐งค๐จโ๐ฉโ๐งโ๐ฆ
}
]
const delegate = UCAN.build({
issuer: user.keypair, // ๐๐จ๐ฝโ๐ป granted access
audience: comrade, // ๐๐จโ๐จ grantee
lifetimeInSeconds: 24 * 60 * 60, // โฑ a day
capabilities: constrainedCapabilities
})
const requestToken = UCAN.build({
issuer: user.keypair, // ๐๐จโ๐จ granted access
audience: comrade, // ๐๐ค grantee
lifetimeInSeconds: 24 * 60 * 60, // โฑ a day
proof: delegate,
capabilities: [{
cap: "LIST",
id: `/uploads/${user}/public`
}]
})