diff --git a/app/changelog/page.mdx b/app/changelog/page.mdx
index f904380..969fba6 100644
--- a/app/changelog/page.mdx
+++ b/app/changelog/page.mdx
@@ -12,6 +12,7 @@ This page lists changes since Working Draft 3. {{ className: 'lead' }}
- Added a new `content-type` for Versia entities: `application/vnd.versia+json`.
- Removed per-User keypairs: now, only the instance keypair is used for signing.
+- Moved [Delegation](/extensions/delegation) to an extension
- Modified how URIs and references to other entities are handled:
- The `uri` field has been removed from all entities.
- Every field that used to be a URI now uses that entity's `id` field.
diff --git a/app/extensions/delegation/page.mdx b/app/extensions/delegation/page.mdx
new file mode 100644
index 0000000..3e9a17a
--- /dev/null
+++ b/app/extensions/delegation/page.mdx
@@ -0,0 +1,78 @@
+export const metadata = {
+ title: 'Delegation Extension',
+ description: 'Lets users perform actions on other accounts\' behalf.'
+}
+
+# Delegation Extension
+
+Delegation is used to authorize actions on behalf of another user. {{ className: 'lead '}}
+
+## Vocabulary
+
+- **Delegator**: The user that is delegating actions to another user. (The user that owns the key)
+- **Delegate**: The user that is being delegated actions. (The user that the key is pointing to)
+
+## Implementation Details
+
+Any actions or entities created by the **delegate** should be attributed to the **delegator** user in clients transparently to end-users (e.g. showing the **delegator** user's name and avatar). This allows for a form of "consensual impersonation" that is authorized by the **delegators** and **delegates**.
+
+This is useful as a way to centralize all of a user's many "alt accounts" into a single, unified feed.
+
+
+ If an instance encounters an action from a User that has a Delegator listed, but that Delegator does not allow the User to perform actions on their behalf, the actions **MUST** be shown as the User's own.
+
+ Also, if a User has a Delegator listed, but that Delegator does not allow the User to perform actions on their behalf, instances **SHOULD** mark the User with a warning about possible impersonation or fraud.
+
+
+## Extension Definition
+
+
+
+
+ The Delegation extension uses an ID of `pub.versia:delegation`.
+
+ If the extension is present, exactly **one** of the fields **MUST** be specified:
+
+
+ If this user performs actions on behalf on another user, **MUST** have a reference to that user.
+
+
+ If other users perform actions on behalf of this user, **MUST** have a list of references to all such users.
+
+
+
+
+
+
+ ```jsonc {{ title: "Example Delegator" }}
+ {
+ // ...
+ "type": "User",
+ "id": "73cb1728-75d7-4080-8d28-4adf49bb0a0d",
+ // ...
+ "extensions": { // [!code focus:5]
+ "pub.versia:delegation": {
+ "delegator": "versia.example.com:bfb6bb39-bb08-4226-91ac-8adebc3da046"
+ }
+ }
+ }
+ ```
+
+ ```jsonc {{ title: "Example Delegates List" }}
+ {
+ // ...
+ "type": "User",
+ "id": "bfb6bb39-bb08-4226-91ac-8adebc3da046",
+ // ...
+ "extensions": { // [!code focus:7]
+ "pub.versia:delegation": {
+ "allowed_delegates": [
+ "versia.social:73cb1728-75d7-4080-8d28-4adf49bb0a0d"
+ ]
+ }
+ }
+ }
+ ```
+
+
+
diff --git a/app/federation/delegation/page.mdx b/app/federation/delegation/page.mdx
deleted file mode 100644
index 43d4e8c..0000000
--- a/app/federation/delegation/page.mdx
+++ /dev/null
@@ -1,25 +0,0 @@
-export const metadata = {
- title: 'Delegation',
- description: 'Delegation is used to authorize actions on behalf of another user',
-}
-
-# Delegation
-
-Delegation is used to authorize actions on behalf of another user. {{ className: 'lead' }}
-
-## Vocabulary
-
-- **Delegator**: The user that is delegating actions to another user. (The user that owns the key)
-- **Delegate**: The user that is being delegated actions. (The user that the key is pointing to)
-
-## The `actor` Field on Public Keys
-
-[Users](/entities/user)'s `public_key` property contains a field called `actor`. This field contains the URI to the **delegator** user, which is used to authorize actions on behalf of the **delegate** user.
-
-This means that the **delegator** user can sign requests with their private key, and any implementations should consider the **delegate** user as equivalent to the **delegator** user.
-
-## Implementation Details
-
-Any actions or entities created by the **delegate** should be attributed to the **delegator** user in clients transparently to end-users (e.g. showing the **delegator** user's name and avatar). This allows for a form of "consensual impersonation" that is authorized by the **delegators** and **delegates**.
-
-This is useful as a way to centralize all of a user's many "alt accounts" into a single, unified feed.
\ No newline at end of file
diff --git a/components/Navigation.tsx b/components/Navigation.tsx
index a3c4d6d..9a53fe1 100644
--- a/components/Navigation.tsx
+++ b/components/Navigation.tsx
@@ -267,7 +267,6 @@ export const navigation: NavGroup[] = [
{ title: "HTTP", href: "/federation/http" },
{ title: "Validation", href: "/federation/validation" },
{ title: "Discovery", href: "/federation/discovery" },
- { title: "Delegation", href: "/federation/delegation" },
{ title: "Example", href: "/federation/example" },
],
},
@@ -295,6 +294,7 @@ export const navigation: NavGroup[] = [
title: "Extensions",
links: [
{ title: "Custom Emojis", href: "/extensions/custom-emojis" },
+ { title: "Delegation", href: "/extensions/delegation" },
{ title: "Groups", href: "/extensions/groups" },
{
title: "Instance Messaging",
diff --git a/components/mdx.tsx b/components/mdx.tsx
index 09debe9..a71ea0f 100644
--- a/components/mdx.tsx
+++ b/components/mdx.tsx
@@ -44,6 +44,37 @@ function InfoIcon(props: ComponentPropsWithoutRef<"svg">) {
);
}
+function WarningIcon(props: ComponentPropsWithoutRef<"svg">) {
+ return (
+
+ );
+}
+
export function Note({ children }: { children: ReactNode }) {
return (
@@ -55,6 +86,17 @@ export function Note({ children }: { children: ReactNode }) {
);
}
+export function Warning({ children }: { children: ReactNode }) {
+ return (
+
+
+
+ {children}
+
+
+ );
+}
+
export function Row({ children }: { children: ReactNode }) {
return (