Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Media storage

Media is optional. When enabled, Signal !saw commands can attach images and audio to observations. Events contain signed content references; the media bytes remain in S3-compatible object storage and never pass through relays.

Configuration

birdd currently supports S3 and S3-compatible storage:

[media]
enabled = true
endpoint = "http://127.0.0.1:3900"
public_endpoint = "https://birds.example.org/_birdd/media"
region = "garage"
bucket = "birdd-media"
access_key = "..."
secret_key = "..."

endpoint is the private S3 API used by birdd. Plain HTTP is accepted only for a loopback endpoint. Leave it unset to use the normal regional AWS endpoint.

public_endpoint is the HTTPS birdd media route other flocks use; it is not the S3 endpoint. It must end in /_birdd/media. Run the adapter server behind that route:

birdd --config birdd.toml serve --listen 127.0.0.1:8787

For production, keep credentials out of generated configuration. The NixOS module accepts mediaAccessKeyFile and mediaSecretKeyFile; standalone processes can use BIRDD_MEDIA_ACCESS_KEY_FILE and BIRDD_MEDIA_SECRET_KEY_FILE.

The NixOS full-node role enables the reference Garage object store, generates its application credentials, and configures the endpoint, region, bucket, and public media URL automatically. Set services.birddGarage.capacity to size its single-node storage allocation. Use a standalone birdd-garage module when adding the same managed storage to a custom role, or configure the media fields and credentials directly to use another S3-compatible service.

Limits

The defaults allow:

  • max_attachments = 4 attachments per observation
  • max_attachment_bytes = 15728640 bytes per attachment
  • max_total_bytes = 31457280 bytes for the complete attachment set
  • max_image_dimension = 4096 pixels per dimension after processing
  • processing_timeout_seconds = 30 seconds for each media processor

Sanitization

Accepted images are JPEG, PNG, WebP, HEIC, and HEIF. They are decoded, auto-oriented, resized when needed, stripped of metadata, and stored as JPEG.

Accepted audio includes AAC, MP4 audio, MP3, Ogg, Opus, WAV, and M4A. It is decoded, stripped of metadata and video, and stored as Opus in an Ogg container.

Non-NixOS installations must provide vipsthumbnail and ffmpeg on the path of the Signal adapter. Unsupported formats, view-once messages, expiring messages, and attachment sets over the configured limits are rejected.

Federation

Media references use a SHA-256 digest. Remote requests are authorized with a short-lived NIP-98 event signed by the requesting flock. The origin serves only media referenced by a live local observation and disclosed to that requester. The receiver verifies the MIME type, byte length, and digest before caching it.

Only directly trusted flocks may fetch media. Restricted-audience recipients must also have a published event that disclosed that media reference. Set projection.media = false to remove media references from an audience.

Without public_endpoint, local media still works, but remote flocks cannot fetch it.

Note

The object store has no built-in garbage collection. Correcting or deleting an observation does not delete its old objects. Include object storage in your backup and retention plan.