owned this note
owned this note
Published
Linked with GitHub
---
title: UCAN demo slides
tags: Slides, UCAN
description: View the slide with "Slide Mode".
slideOptions:
theme: white
---
### UCAN: Authorizing Users Without a Back End
<!-- Put the link to this slide here so people can follow -->
slide: https://hackmd.io/@gozala/ucan-demo
---
### Decentralized Identifier (did:key)
- Just a public key (e.g EdDSA, RSA)
- Self sertifying
---
#### User Controlled Authorization Networks (UCAN)
- Object Capability Model (OCAP)
- JSON Web Tokens (JWTs)
- Controlled ahead of time (e.g. time limits)
- Support delegation
---

---

---

---

---

---
### Capabilities
- **Operation** - Action that can be performed
- **ID** - Resource action can be perfromed to
- **Type** - Identifier to indicating the type of the thing
---
## Fission defines it as
```json
{
$TYPE: $IDENTIFIER,
"cap": $CAPABILITY
}
```
---
### They type it as
```ts
type Capability = {
[rsc: string]: string
cap: string
}
```
---
### In practice it's
```ts
interface Capability<OP extends string> = {
cap: OP
[constraint: string]: unknown
}
```
---
### Capabilities
- 💚 Open ended just requires `cap` discriminant.
- 💔 Too loose, can't catch escalation
---
### My definition
```ts
export interface Capability<
OP extends Uppercase<string>,
ID extends string
> extends Constraints {
cap: OP
id?: ID
}
export interface Constraints {
[key: string]: number | string | undefined
}
```
---
### Capabilities (simplified)
- **Operation** - Action that can be performed
- **ID** - Resource action can be perfromed to
- ~~**Type** - Identifier to indicating the type of the thing~~ (ID contains the type)
---
### Capabilities 💭 HTTP API
```md
PUT /uploads/did:key:foo/
```
```json
{
"cap":"PUT"
"id": "/uploads/did:key:gozala/"
}
```
---
### Capabilities 💪
```ts
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
}
]
```
---
### 🤖 Authorizing 👨🏽💻
```ts
const root = UCAN.build({
issuer: service.keypair, // 🤖 who grants access
audience: user, // 👨🏽💻 who is granted access
lifetimeInSeconds: 24 * 60 * 60, // ⏱ how long
capabilities // 💪
})
```
---
### 👨🏽💻 Constrainting Capabilities 💪🧤
```js
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`, // 👨🏽💻💪🧤👨👩👧👦
}
]
```
---

---
### 👨🏽💻 Delegation 👨🎨
```ts
const delegate = UCAN.build({
issuer: user.keypair, // 🔐👨🏽💻 granted access
audience: comrade, // 🆔👨🎨 grantee
lifetimeInSeconds: 24 * 60 * 60, // ⏱ a day
capabilities: constrainedCapabilities
})
```
---
### 👨🎨 Requesting 🤖
```ts
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`
}]
})
```
---
## Authorization flow
1. Client generates keypair 🔐
---
## Authorization flow
1. Client generates keypair 🔐
2. Client derives [did:key] from public key 🆔
[did:key]:https://w3c-ccg.github.io/did-method-key/
---
## Authorization flow
1. Client generates keypair 🔐
2. Client derives [did:key][] from public key 🆔
3. Client requests a UCAN for the [did:key] 🛂
[did:key]:https://w3c-ccg.github.io/did-method-key/
---
## Authorization flow
1. Client generates keypair 🔐
2. Client derives [did:key][] from public key 🆔
3. Client requests a UCAN for the [did:key] 🛂
4. Service sends back signed UCAN token 🎟
[did:key]:https://w3c-ccg.github.io/did-method-key/
---
## Did you noitce ?
- Private key has never left a user device
- Service can verify user identity retroactively (e.g. send email & activate capability on confirmation)
---
## Exercise capabilities
1. 👨🏽💻 derives UCAN 🎟 addressed to a service 🤖
1. 👨🏽💻 attaches derived UCAN 🎟 token to request
2. 🤖 Checks UCAN is addressed to it.
2. 🤖 Checks request has adequate capabilities
3. 🤖 Checks that root capability is signed by 🤖 private key.
4. 🤖 Fulfill / deny request accordingly.
---
### Delegation
1. 👨🏽💻 Issues a new UCAN to 👨🎨🔐🆔
1. 👨🏽💻 Attaches own UCAN 🎟 as proof.
1. 👨🏽💻 Signs token with a private key ✍️.
1. 👨🎨 Derives UCAN 🎫 for the service 🤖
1. 👨🎨 Attaches derived UCAN 🎫 to a request.
1. 🤖 Checks 🎫 is addressed to it.
1. 🤖 Checks 🎫 has subset of 🎟 capabilities.
1. 🤖 Checks signature chain.
1. 🤖 Checks root token is issued by 🤖
---
### Delegation
1. 👨🎨 Issues a new UCAN 🧾 for 👩🏻🔬
2. ....
---
### Cascading Revocation
---
## Iconography
- 🤖 - Service
- 👨🏽💻 - Client
- 👨🎨 - User
---
### Thank you!