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 = 4attachments per observationmax_attachment_bytes = 15728640bytes per attachmentmax_total_bytes = 31457280bytes for the complete attachment setmax_image_dimension = 4096pixels per dimension after processingprocessing_timeout_seconds = 30seconds 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.