Fedify 2.1.0: Unverified activity hooks, RFC 9421 negotiation, MySQL support, and Astro integration #642
dahlia
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Fedify is a TypeScript framework for building ActivityPub servers that participate in the fediverse. It handles the heavy lifting of federation—HTTP Signatures, JSON-LD processing, WebFinger, and more—so you can focus on building your application instead.
We are pleased to announce Fedify 2.1.0. This release is largely focused on real-world federation reliability: giving applications more control over activities that fail signature verification, completing RFC 9421
Accept-Signaturenegotiation on both sides of the wire, and improving interoperability with GoToSocial. On top of that, two new packages expand Fedify's ecosystem—@fedify/mysqland@fedify/astro—and thefedify lookupCLI tool gains some useful new powers.Handling unverified activities
Anyone who has run a Fedify application in the wild has seen the same kind of log noise: a
Deleteactivity arrives from a remote server, but the actor's signing key now returns404 Not Foundor410 Gone. Fedify can't verify the signature, so it returns401 Unauthorized—and the remote server dutifully keeps retrying. The result is a steady stream of unresolvable errors and pointless traffic, with no good place to intercept them.Fedify 2.1.0 addresses this with
InboxListenerSetters.onUnverifiedActivity(). The hook receives theRequestContext, the parsed activity, and a reason object whosetypeis one of"noSignature","invalidSignature", or"keyFetchError". If the callback returns aResponse, Fedify uses it; if it returns nothing, Fedify falls back to the default401. This keeps unverified activities out of your normal inbox listeners while still letting you act on them deliberately.A common pattern is stopping the redelivery loop for
Deleteactivities from permanently gone actors:Alongside this, the new
verifyRequestDetailed()function gives lower-level code fine-grained access to signature failure reasons, and OpenTelemetry spans now include HTTP signature failure reasons and key-fetch failure details for inbound activities. TheFetchErrortype also gains an optionalresponseproperty so callers can inspect the original HTTP error response.This work was tracked in #472 and implemented in #611.
RFC 9421
Accept-SignaturenegotiationFedify has supported signing with RFC 9421 (HTTP Message Signatures) for some time, but it did not yet implement the negotiation layer described in RFC 9421 §5. Some servers respond to incoming requests with an
Accept-Signatureheader specifying exactly which covered components or metadata parameters they require—and until now, Fedify couldn't adapt to those requirements.Fedify 2.1.0 fills this gap on both sides:
On the outbound side,
doubleKnock()now parsesAccept-Signaturechallenges from401responses and retries with a compatible RFC 9421 signature before falling back to the legacy spec-swap behavior. Existing fallback behavior is preserved when no usable challenge exists.On the inbound side, a new
InboxChallengePolicyoption inFederationOptionslets your server emitAccept-Signatureheaders on inbox401responses, with optional one-time nonce support for replay protection.This was contributed by @2chanhaeng in #626, addressing #583 and #584.
GoToSocial interoperability improvements
Two changes in this release are specifically motivated by GoToSocial compatibility.
First,
RequestContext.getSignedKeyOwner()previously threw an unhandled error when a remote server with authorized fetch enabled returned401 Unauthorizedduring a key owner lookup. This caused Fedify to respond with500 Internal Server Errorwhen federating with GoToSocial instances. It now correctly returnsnullinstead (#473, #589).Second, the preloaded
https://gotosocial.org/nsJSON-LD context has been updated to match the GoToSocial v0.21+ namespace. New terms includeLikeRequest,LikeAuthorization,automaticApproval,manualApproval,interactingObject, and several others, while deprecated terms are retained for backward compatibility (#453, #622).GoToSocial interaction controls vocabulary
Building on the context update above,
@fedify/vocabnow includes the GoToSocial interaction controls vocabulary. This adds vocabulary types for expressing who is allowed to like, reply to, or announce a post, and for granting or revoking those approvals.New additions include:
InteractionPolicyandInteractionRulevalue classesLikeRequest,ReplyRequest, andAnnounceRequestactivity types for requesting interaction approvalLikeAuthorization,ReplyAuthorization, andAnnounceAuthorizationtypes for proving approved interactionsObject.interactionPolicy,Object.approvedBy, and corresponding authorization properties/accessorsThis vocabulary lays the groundwork for applications implementing quote posts and interaction approval flows with GoToSocial-compatible servers (#453, #622).
@fedify/mysql: MySQL and MariaDB backendsThe new
@fedify/mysqlpackage provides bothKvStoreandMessageQueueimplementations backed by MySQL or MariaDB (MySQL 8.0+ or MariaDB 10.6+), using themysql2driver.MysqlKvStorestores key–value pairs in a MySQL table with TTL, prefix listing, and compare-and-swap support.MysqlMessageQueueusesSELECT … FOR UPDATE SKIP LOCKEDfor polling, MySQL advisory locks (GET_LOCK/RELEASE_LOCK) for ordering-key serialization, and supports delayed delivery,enqueueMany(), and concurrent workers.This rounds out the major relational databases alongside the existing
@fedify/postgresand@fedify/sqlitepackages (#585, #586, #597, #599).@fedify/astro: Astro integrationThe new
@fedify/astropackage integrates Fedify with Astro. It providesfedifyIntegration()for Vite SSR configuration andfedifyMiddleware()for request handling, with runtime-specific templates for Deno, Bun, and Node.js. Thefedify initcommand now offers Astro as a web framework option.This was contributed by @2chanhaeng in #50.
fedify lookupimprovementsThe
fedify lookupcommand has gained several new capabilities.--recurse/--recurse-depthfollows object relationship chains—reply chains viainReplyTo/replyTarget, quote chains viaquoteUrl, and similar relationships. It's mutually exclusive with--traverse, and--suppress-errorsapplies in recurse mode as best-effort lookup.--reversereverses the presentation order of emitted results across all output modes.By default,
fedify lookupnow disallows private and localhost addresses to prevent accidental exposure during normal use. The-p/--allow-private-addressflag re-enables private address access for local development workflows (#606, #607, #608, #609).xsd:decimalsupport@fedify/vocab-runtimenow includesDecimal, a branded string type for exactxsd:decimalvalues, along withisDecimal(),canParseDecimal(), andparseDecimal()for checking and validating XML Schema decimal lexical forms without introducing a decimal arithmetic dependency. The vocabulary code generator in@fedify/vocab-toolshas been updated to generateDecimalproperties forxsd:decimalranges. This lays the groundwork for precision-safe marketplace and measurement values as needed by FEP-0837 (#617, #640).Bug fixes
Endpoints.toJsonLd()emitting invalid"type": "as:Endpoints"in JSON-LD output. Theas:Endpointstype doesn't exist in the ActivityStreams vocabulary and caused validation failures on implementations like browser.pub.Source.toJsonLd()had the same issue with"type": "as:Source". (Endpoints object serializes with invalid "type": "as:Endpoints" in actor JSON #576)fedify initno longer adds"temporal"todeno.json's"unstable"field when the installed Deno version is 2.7.0 or later, and omits the"unstable"field entirely when no unstable feature is required.Acknowledgments
Thanks to the contributors who made this release possible:
Accept-Signaturenegotiation,@fedify/astro,fedify initimprovementsFor the complete list of changes, please refer to the CHANGES.md file in the repository.
Beta Was this translation helpful? Give feedback.
All reactions