### 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 --- ![](https://i.imgur.com/vraomzN.png) --- ![](https://i.imgur.com/BFmbLiJ.png) --- ![](https://i.imgur.com/dwoDCF7.png) --- ![](https://i.imgur.com/Gr00hLm.png) --- ![](https://i.imgur.com/cvXR55B.png) --- ### 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`, // ๐Ÿ‘จ๐Ÿฝโ€๐Ÿ’ป๐Ÿ’ช๐Ÿงค๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ } ] ``` --- ![](https://i.imgur.com/xmr8pfe.png) --- ### ๐Ÿ‘จ๐Ÿฝโ€๐Ÿ’ป 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!
{"metaMigratedAt":"2023-06-16T14:38:29.668Z","metaMigratedFrom":"YAML","title":"UCAN demo slides","breaks":false,"description":"View the slide with \"Slide Mode\".","slideOptions":"{\"theme\":\"white\"}","contributors":"[{\"id\":\"fff58d5d-df29-4dd3-93ef-42fd0194a26f\",\"add\":7233,\"del\":4054}]"}
    578 views