Products

Anahita Services

The server, one service at a time. Each does one thing, all are reached through one gateway, and the optional ones can be left out.

Signing in

Signing in and signing up, for Anahita’s own apps and anybody else’s.

OAuth 2.0 and OpenID Connect
A complete provider: discovery, keys, UserInfo, refresh tokens, introspection and revocation; PKCE for apps that hold no secret, client credentials for services.
No tokens in the browser
A backend for frontend (BFF): Anahita Web holds only an HttpOnly, SameSite session cookie, and the tokens stay on the server, traded for the cookie on each request.
Passkeys
WebAuthn, with Face ID, Touch ID, Windows Hello or a security key. A passkey is both factors.
Two-factor
Codes from any authenticator app, their secrets encrypted at rest.
OTP by email
A one-time password by email: signing in without a password.
Signing keys
Rotated every 90 days, and sealed with a key of your own or AWS KMS: reading the database is not enough to make a token.
Who may join
Invitations, applications to join, and the agreements a member accepts.
Guarded
Limits on guessing codes and passwords, and a one-time token on every form.

Profiles and the graph

actor-service

Every kind of profile, in one service.

People
A profile at a username, made when somebody signs up.
Groups
Made by members, with administrators and followers; a group can host events.
Events
A start and an end in their own time zone, how many may go, and where to join online; going or maybe, calling it off, and a calendar file.
Websites
A website’s feed, followed like a profile.
Every kind
An avatar and a cover, followers, invitations, who may see and do what, and the same life from enabled to archived to deleted.

Who follows, blocks and subscribes to whom.

Follow requests
A profile can ask to approve its followers, and shows strangers only its name and picture.
Invitations
Up to 50 followers invited to a group or event at once; unanswered ones lapse after 30 days.
Blocks that hold
A block ends follows both ways, and is sent on to the fediverse.
Each person’s say
Who may mention them, and who may tag them in photos, or approve each first.
Group rules
A group or event with rules is followed only once each rule is agreed to.

identity-image-service

The avatars and covers of profiles and posts.

Safe images
Each upload is judged by its bytes, turned upright and encoded afresh; nothing is kept as it arrived.
Addresses that stay
A public profile’s pictures keep one address, so other servers can link to them for good.

graph-grpc-service

The graph every other service reads: profiles and posts are its nodes, and the ties between them its edges.

One gate
Feeds, search, notifications and recommendations all ask one check of who may see what.
Identifiers for good
Every node has a random UUID that never changes, used in every address other servers are given.
Threads in one go
Up to ten notes written as a thread are saved together, all or none.
Purges that finish
Deleting a profile’s posts goes in batches it can resume, and keeps its handle from being taken.

Posts and media

Notes, articles and topics.

Drafts
Articles and topics can be kept as drafts and published when ready.
Embeds and citations
An address on a line of its own shows the post or a card for the page; citations are counted and listed as “Cited by”.
Quotes by consent
Authors choose who may quote them, and can take their post out of any quote.
Who may reply
Anyone, nobody, followers, people they follow or people mentioned; and replies can be hidden.
Private saves
What somebody saves is seen by them alone: nothing is counted, and the author is never told.

Photo posts.

Up to twenty images
In one post, with one caption and one audience.
Alt text
A description of up to 2,000 characters for each image.
Nothing hidden in the file
Each image is encoded afresh at six sizes, never enlarged, so only the picture is kept.
Downloads by consent
Full size only if the author allows it, and never counted.

Video posts. A worker makes each video ready for every screen.

Straight to storage
The browser sends a video in parts directly to object storage.
Several sizes
MP4 at 1080, 720 and 360 by default, up to 4K, with a poster frame.
Nothing hidden in the file
Every file shown is encoded afresh, and the original is deleted.
GIFs as loops
Animated GIFs become silent looping videos, a fraction of the size.
Checked on every play
Each play checks again that the viewer may see the post.

Hashtags.

Any language
Letters of any script, digits and emoji, whatever their case.
Fair trending
Each profile counts once, only public posts count, and the window is the operator’s.
Suggestions while writing
Offered as you type, or from the title (“open science” finds #OpenScience).
From elsewhere too
A hashtag in a post from another server leads to this instance’s own page for it.

location-service

The locations posts are tagged with, and finding them on a map.

Open maps
Addresses found with OpenStreetMap’s Photon and Nominatim, which can be run yourself.
The operator decides
Who may add a location: administrators, anyone signed in, or super administrators.
Understood elsewhere
Up to five per post, sent to other servers in the form Pixelfed reads.
Nearby and trending
Locations within a distance of a point, and those used most lately.

like-service

Likes.

With permissions
Each profile chooses who may like what it posts: followers by default.
Lists that respect privacy
Who liked a post shows only the people its reader may see.
Across networks
Likes cross to and from the fediverse and Bluesky.

Feeds, search and notifications

The chronological feed, reposts, and the custom feeds people make.

Chronological first
The first tab is always who you follow, newest first, and it cannot be removed.
Custom feeds
Made from sources, filtered by hashtag, keyword, location, language and kind of post.
Near me
Posts within 1 to 500 km, with the reader’s position never kept.
Never wider
A shared feed shows each reader only what they could already see.
Share, copy, pin
Feeds can be shared, found, copied and kept on the home page.

Search for people, groups, events, posts and shared feeds; the most relevant first, or the newest.

Old and useful
How fast interest fades is the operator’s to set: a year by default, or never.
Each person’s weights
Six signals each person can turn down or up, kept wherever they sign in.
Any script
“Montréal” and “東京” are found as typed.

Recommendations of who to follow.

Reasons, not a model
Worked out from the graph by written rules, and shown with their reasons.
In each person’s hands
Weights for each reason, “Not interested”, and not being suggested at all.
Replaceable
Leave it out, or run another service that answers the same way.

Notifications in the app.

Never emailed
Notifications stay in the app; a test fails if a service starts sending mail.
Gone with their cause
A deleted post or a like taken back takes its notification with it.
Grouped
“Worf and 2 others liked your post”.
Act in place
Accept a follow request, approve a tag or follow back, right from the notification.

The open social web

Makes the instance a server of the fediverse, for the people who choose to be found there.

Both ways
Follows, notes, photos, videos, articles, replies, likes and reposts, with Mastodon, Pixelfed, GoToSocial and others.
Signed and checked
Each person has their own signing keys, kept encrypted; every message in is checked against its sender.
Delivered
Sending is retried for two days, and what goes missing is found and sent again.
Refusing servers
Super administrators can refuse a domain and everything under it.

Bluesky: following profiles there, and posting there for whoever connects their own Bluesky account.

For everyone
Anybody can follow Bluesky profiles from here, without a Bluesky account.
Post as yourself
Connect your Bluesky account to post, reply, like, repost and follow there.
Password never kept
The app password is traded once for a token, which is kept encrypted.
Bring your follows
Follow here the people you already follow on Bluesky.

Follow a website’s feed like a profile. A worker reads every feed and posts what is new.

Any feed
RSS, Atom or JSON Feed, from WordPress, a static site or a podcast; followed here and from the fediverse.
Proven domains
A DNS record or a file on the site, checked again every day.
Polite
Feeds are read every 30 minutes, or at once through WebSub, and less often when they fail.
Replies as the site
Its administrators can answer readers as the website.

The card under a note that links to a page: its title and picture.

Safe fetching
Web addresses only; private and internal addresses are refused, and every redirect is checked again.
Private reading
The picture is served from this instance, so reading a note tells the linked site nothing.
Cards that last
The card is kept with the note, and reads the same if the page changes or goes.

Safety and your data

Reports of people and posts, and the cases administrators decide.

Cases, not piles
Everyone who reports the same thing joins one case.
Your own reasons
The list of reasons can be replaced with your own, in your languages.
Rules
A report can name a site’s, group’s or event’s rule; group administrators see those without the reporters’ names.
Reporters protected
The person reported is never told who reported them.

A copy of your own data, made by a worker and kept for a while to download.

Everything
Every post, private ones too, full-size photos and videos, follows, followers, blocks, likes and saves.
Readable anywhere
A web page in the archive works with no connection and no scripts.
Portable
ActivityStreams files that other fediverse software reads.
Asked for in person
Each copy needs a fresh proof of who you are, and is kept for 7 days.

Upkeep by the clock.

Grace, then gone
A deleted profile is purged when its 30 days of grace are over.
Resumable
A purge that was interrupted carries on where it stopped.
Events
A reminder the day before, and archived 30 days after.
Tidying
Photos uploaded but never posted, and invitations nobody answered, are removed.

Storage, mail and upkeep

Files, on any S3-compatible object storage.

Any store
AWS, Garage or any other S3-compatible store, with a test to check a new one.
Judged by its bytes
What a file says it is counts for nothing: an HTML file named photo.png is refused.
Private by default
The store stays private, and every link to a file is signed and short-lived.

Email, over SMTP.

Any provider
Any SMTP server or relay, with TLS.
Account mail only
Signing in and account messages; nothing else is ever mailed.
Safe while developing
In development, every message goes to the developer instead.
Optional

Serves Anahita Web, with each page’s own title and picture, so a shared link shows as itself.

The same for all
Crawlers and people are sent the same page; nobody is told apart.
Public only
A page is described only if its post and profile are public.
Handles on your domain
The fediverse finds @name@your-domain at the main address.

migration-job

Brings the database up to date at each upgrade.

Three paths
A fresh database, an upgrade in place from the PHP Anahita, or the newest changes.
Proven the same
A test compares a fresh database and an upgraded one, column by column.

Underneath

What the services keep their data in. Each can be run by you, or bought as a managed service.

MySQL

Everything that is kept.

Redis

Sessions.

RabbitMQ

Events between the services.

Object storage

Photos, videos and files, on any S3-compatible store: Garage on your own machine, your own or your cloud’s live.