Skip to main content

Rust Libraries

Rust libraries for implementing ActivityPub.

activitypub-federation

Battle-tested library from Lemmy.

PropertyValue
Repositorygithub.com/LemmyNet/activitypub-federation-rust
crates.ioactivitypub-federation
LicenseAGPL-3.0
StatusActive, Production Ready

Features

  • Complete S2S federation
  • HTTP Signatures
  • WebFinger
  • Activity queue
  • Async/await

Example

use activitypub_federation::{
config::FederationConfig,
traits::Actor,
};

#[derive(Clone)]
struct MyActor {
id: Url,
inbox: Url,
public_key: String,
}

impl Actor for MyActor {
fn id(&self) -> Url {
self.id.clone()
}

fn public_key_pem(&self) -> &str {
&self.public_key
}

fn inbox(&self) -> Url {
self.inbox.clone()
}
}

Sending Activities

use activitypub_federation::activity_sending::SendActivityTask;

let activity = Create {
actor: actor.id(),
object: note,
};

SendActivityTask::prepare(&activity, &actor, vec![inbox_url])
.await?
.send(&data)
.await?;

activitystreams

Type-safe ActivityStreams vocabulary.

PropertyValue
Repositorycrates.io/crates/activitystreams
LicenseGPL-3.0
StatusActive

Example

use activitystreams::{
activity::Create,
object::Note,
prelude::*,
};

let note = Note::new()
.set_content("Hello from Rust!")
.set_attributed_to("https://example.com/users/alice".parse()?);

let create = Create::new(
"https://example.com/users/alice".parse()?,
note.into_any_base()?,
);

http-signature-normalization

HTTP Signature handling.

PropertyValue
Repositorycrates.io/crates/http-signature-normalization
LicenseAGPL-3.0
StatusActive

Signing

use http_signature_normalization_actix::prelude::*;

let config = Config::default()
.set_expiration(Duration::seconds(30));

let signed = config
.begin_sign("POST", "/inbox", headers)?
.sign(key_id, |signing_string| {
// Sign with private key
sign_with_rsa(signing_string, private_key)
})?;

Verification

let unverified = config.begin_verify(
request.method(),
request.uri().path_and_query(),
request.headers(),
)?;

let key_id = unverified.key_id();
// Fetch public key
let verified = unverified.verify(|signing_string, signature| {
verify_rsa(signing_string, signature, public_key)
})?;

webfinger

WebFinger client.

PropertyValue
Repositorycrates.io/crates/webfinger
LicenseMIT
StatusStable

Example

use webfinger::WebFinger;

let wf = WebFinger::fetch("alice@example.com").await?;

for link in wf.links {
if link.rel == "self" {
println!("Actor URL: {}", link.href);
}
}

Comparison

LibraryScopeComplexityUse Case
activitypub-federationFull federationHighProduction servers
activitystreamsTypes onlyMediumType safety
http-signature-normalizationSigningLowHTTP Signatures

Production Examples

Lemmy

lemmy/crates/apub/
├── src/
│ ├── activities/ # Activity handlers
│ ├── objects/ # AP objects
│ └── protocol/ # Type definitions

Quick Start

For new projects: Use activitypub-federation.

For custom implementations: Combine activitystreams + http-signature-normalization.

See Also