Loading docs/.vitepress/config.mts +7 −3 Original line number Diff line number Diff line Loading @@ -56,12 +56,15 @@ export default defineConfig({ { text: "Tutorial", link: "/tutorial.md" }, { text: "Manual", link: "/manual.md", activeMatch: "/manual" }, { text: "API reference", link: "https://jsr.io/@fedify/fedify" }, ...extraNav ...extraNav, ], sidebar: [ { text: "What is Fedify?", link: "/intro.md" }, { text: "Quick demo", link: "https://dash.deno.com/playground/fedify-demo" }, { text: "Quick demo", link: "https://dash.deno.com/playground/fedify-demo", }, { text: "Installation", link: "/install.md" }, { text: "Tutorial", link: "/tutorial.md" }, { Loading @@ -75,6 +78,7 @@ export default defineConfig({ { text: "Inbox listeners", link: "/manual/inbox.md" }, { text: "Sending activities", link: "/manual/send.md" }, { text: "Collections", link: "/manual/collections.md" }, { text: "Access control", link: "/manual/access-control.md" }, { text: "NodeInfo", link: "/manual/nodeinfo.md" }, { text: "Pragmatics", link: "/manual/pragmatics.md" }, { text: "Integration", link: "/manual/integration.md" }, Loading Loading @@ -124,7 +128,7 @@ export default defineConfig({ href: "/favicon-32x32.png", }, ], ...plausibleScript ...plausibleScript, ], cleanUrls: true, Loading docs/manual.md +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ framework. - [Inbox listeners](./manual/inbox.md) - [Send activities](./manual/send.md) - [Collections](./manual/collections.md) - [Access control](./manual/access-control.md) - [NodeInfo](./manual/nodeinfo.md) - [Pragmatics](./manual/pragmatics.md) - [Integration](./manual/integration.md) Loading docs/manual/access-control.md 0 → 100644 +99 −0 Original line number Diff line number Diff line --- description: >- Fedify provides a flexible access control system that allows you to control who can access your resources. This section explains how to use the access control system. prev: text: Collections link: ./collections.md next: text: NodeInfo link: ./nodeinfo.md --- Access control ============== *This API is available since Fedify 0.7.0.* Fedify provides a flexible access control system that allows you to control who can access your resources through the method named [authorized fetch], which is popularized by Mastodon. The method requires HTTP Signatures to be attached to even `GET` requests, and Fedify automatically verifies the signatures and derives the actor from the signature. > [!NOTE] > Although the method is popularized by Mastodon, it is not a part of the > ActivityPub specification, and clients are not required to use the method. > Turning this feature on may limit the compatibility with some clients. [authorized fetch]: https://swicg.github.io/activitypub-http-signature/#authorized-fetch Enabling authorized fetch ------------------------- To enable authorized fetch, you need to register an `AuthorizePredicate` callback with `ActorCallbackSetters.authorize()` or `CollectionCallbackSetters.authorize()`. The below example shows how to enable authorized fetch for the actor dispatcher: ~~~~ typescript{8-10} import { federation } from "./your-federation.ts"; import { isBlocked } from "./your-blocklist.ts"; federation .setActorDispatcher("/users/{handle}", async (ctx, handle, key) => { // Omitted for brevity; see the related section for details. }) .authorize(async (ctx, handle, signedKey, signedKeyOwner) => { return !isBlocked(handle, signedKeyOwner); }); ~~~~ The equivalet method is available for collections as well: ~~~~ typescript{8-10} import { federation } from "./your-federation.ts"; import { isBlocked } from "./your-blocklist.ts"; federation .setOutboxDispatcher("/users/{handle}/outbox", async (ctx, handle) => { // Omitted for brevity; see the related section for details. }) .authorize(async (ctx, handle, signedKey, signedKeyOwner) => { return !isBlocked(handle, signedKeyOwner); }); ~~~~ If the predicate returns `false`, the request is rejected with a `401 Unauthorized` response. Fine-grained access control --------------------------- You may not want to block everything from an unauthroized user, but only filter some resources. For example, you may want to show some private posts to a specific group of users. In such cases, you can use the `RequestContext.getSignedKeyOwner()` method to get the actor who signed the request and make a decision based on the actor. The method returns the `Actor` object who signed the request (more precisely, the owner of the key that signed the request, if the key is associated with an actor). The below pseudo code shows how to filter out private posts: ~~~~ typescript{7,9} import { federation } from "./your-federation.ts"; import { getPosts, toCreate } from "./your-model.ts"; federation .setOutboxDispatcher("/users/{handle}/outbox", async (ctx, handle) => { const posts = await getPosts(handle); // Get posts from the database const keyOwner = await ctx.getSignedKeyOwner(); // Get the actor who signed the request const items = posts .filter(post => post.isVisibleTo(keyOwner)) .map(toCreate); // Convert model objects to ActivityStreams objects return { items }; }); ~~~~ docs/manual/collections.md +2 −2 Original line number Diff line number Diff line Loading @@ -6,8 +6,8 @@ prev: text: Sending activities link: ./send.md next: text: NodeInfo link: ./nodeinfo.md text: Access control link: ./access-control.md --- Collections Loading docs/manual/nodeinfo.md +2 −2 Original line number Diff line number Diff line Loading @@ -5,8 +5,8 @@ description: >- distributed social networks. This section explains how to expose a NodeInfo endpoint and the key properties of a NodeInfo object. prev: text: Collections link: ./collections.md text: Access control link: ./access-control.md next: text: Pragmatics link: ./pragmatics.md Loading Loading
docs/.vitepress/config.mts +7 −3 Original line number Diff line number Diff line Loading @@ -56,12 +56,15 @@ export default defineConfig({ { text: "Tutorial", link: "/tutorial.md" }, { text: "Manual", link: "/manual.md", activeMatch: "/manual" }, { text: "API reference", link: "https://jsr.io/@fedify/fedify" }, ...extraNav ...extraNav, ], sidebar: [ { text: "What is Fedify?", link: "/intro.md" }, { text: "Quick demo", link: "https://dash.deno.com/playground/fedify-demo" }, { text: "Quick demo", link: "https://dash.deno.com/playground/fedify-demo", }, { text: "Installation", link: "/install.md" }, { text: "Tutorial", link: "/tutorial.md" }, { Loading @@ -75,6 +78,7 @@ export default defineConfig({ { text: "Inbox listeners", link: "/manual/inbox.md" }, { text: "Sending activities", link: "/manual/send.md" }, { text: "Collections", link: "/manual/collections.md" }, { text: "Access control", link: "/manual/access-control.md" }, { text: "NodeInfo", link: "/manual/nodeinfo.md" }, { text: "Pragmatics", link: "/manual/pragmatics.md" }, { text: "Integration", link: "/manual/integration.md" }, Loading Loading @@ -124,7 +128,7 @@ export default defineConfig({ href: "/favicon-32x32.png", }, ], ...plausibleScript ...plausibleScript, ], cleanUrls: true, Loading
docs/manual.md +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ framework. - [Inbox listeners](./manual/inbox.md) - [Send activities](./manual/send.md) - [Collections](./manual/collections.md) - [Access control](./manual/access-control.md) - [NodeInfo](./manual/nodeinfo.md) - [Pragmatics](./manual/pragmatics.md) - [Integration](./manual/integration.md) Loading
docs/manual/access-control.md 0 → 100644 +99 −0 Original line number Diff line number Diff line --- description: >- Fedify provides a flexible access control system that allows you to control who can access your resources. This section explains how to use the access control system. prev: text: Collections link: ./collections.md next: text: NodeInfo link: ./nodeinfo.md --- Access control ============== *This API is available since Fedify 0.7.0.* Fedify provides a flexible access control system that allows you to control who can access your resources through the method named [authorized fetch], which is popularized by Mastodon. The method requires HTTP Signatures to be attached to even `GET` requests, and Fedify automatically verifies the signatures and derives the actor from the signature. > [!NOTE] > Although the method is popularized by Mastodon, it is not a part of the > ActivityPub specification, and clients are not required to use the method. > Turning this feature on may limit the compatibility with some clients. [authorized fetch]: https://swicg.github.io/activitypub-http-signature/#authorized-fetch Enabling authorized fetch ------------------------- To enable authorized fetch, you need to register an `AuthorizePredicate` callback with `ActorCallbackSetters.authorize()` or `CollectionCallbackSetters.authorize()`. The below example shows how to enable authorized fetch for the actor dispatcher: ~~~~ typescript{8-10} import { federation } from "./your-federation.ts"; import { isBlocked } from "./your-blocklist.ts"; federation .setActorDispatcher("/users/{handle}", async (ctx, handle, key) => { // Omitted for brevity; see the related section for details. }) .authorize(async (ctx, handle, signedKey, signedKeyOwner) => { return !isBlocked(handle, signedKeyOwner); }); ~~~~ The equivalet method is available for collections as well: ~~~~ typescript{8-10} import { federation } from "./your-federation.ts"; import { isBlocked } from "./your-blocklist.ts"; federation .setOutboxDispatcher("/users/{handle}/outbox", async (ctx, handle) => { // Omitted for brevity; see the related section for details. }) .authorize(async (ctx, handle, signedKey, signedKeyOwner) => { return !isBlocked(handle, signedKeyOwner); }); ~~~~ If the predicate returns `false`, the request is rejected with a `401 Unauthorized` response. Fine-grained access control --------------------------- You may not want to block everything from an unauthroized user, but only filter some resources. For example, you may want to show some private posts to a specific group of users. In such cases, you can use the `RequestContext.getSignedKeyOwner()` method to get the actor who signed the request and make a decision based on the actor. The method returns the `Actor` object who signed the request (more precisely, the owner of the key that signed the request, if the key is associated with an actor). The below pseudo code shows how to filter out private posts: ~~~~ typescript{7,9} import { federation } from "./your-federation.ts"; import { getPosts, toCreate } from "./your-model.ts"; federation .setOutboxDispatcher("/users/{handle}/outbox", async (ctx, handle) => { const posts = await getPosts(handle); // Get posts from the database const keyOwner = await ctx.getSignedKeyOwner(); // Get the actor who signed the request const items = posts .filter(post => post.isVisibleTo(keyOwner)) .map(toCreate); // Convert model objects to ActivityStreams objects return { items }; }); ~~~~
docs/manual/collections.md +2 −2 Original line number Diff line number Diff line Loading @@ -6,8 +6,8 @@ prev: text: Sending activities link: ./send.md next: text: NodeInfo link: ./nodeinfo.md text: Access control link: ./access-control.md --- Collections Loading
docs/manual/nodeinfo.md +2 −2 Original line number Diff line number Diff line Loading @@ -5,8 +5,8 @@ description: >- distributed social networks. This section explains how to expose a NodeInfo endpoint and the key properties of a NodeInfo object. prev: text: Collections link: ./collections.md text: Access control link: ./access-control.md next: text: Pragmatics link: ./pragmatics.md Loading