# This schema always follows the latest dev version of Versia Server, which may not be what you want # Change the URL to the commit/tag you are using #:schema https://raw.githubusercontent.com/versia-pub/server/main/config/config.schema.json [database] # Main PostgreSQL database connection host = "localhost" port = 5432 username = "versia" password = "mycoolpassword" database = "versia" # Add any eventual read-only database replicas here # [[database.replicas]] # host = "other-host" # port = 5432 # username = "versia" # password = "mycoolpassword2" # database = "replica1" [redis.queue] # Redis instance for storing the federation queue # Required for federation host = "localhost" port = 6379 password = "" database = 0 enabled = true [redis.cache] # Redis instance to be used as a timeline cache # Optional, can be the same as the queue instance host = "localhost" port = 6380 password = "" database = 1 enabled = false [sonic] # If Sonic is not configured, search will not be enabled host = "localhost" port = 7700 password = "" enabled = true [signups] # Whether to enable registrations or not registration = true rules = [ "Do not harass others", "Be nice to people", "Don't spam", "Don't post illegal content", ] [oidc] # Run Versia Server with this value missing to generate a new key # [oidc.keys] # public = "XXXX" # private = "XXXX" # If enabled, Versia Server will require users to log in with an OAuth provider forced = false # Allow registration with OAuth providers # Overriden by the signups.registration setting allow_registration = true # The provider MUST support OpenID Connect with .well-known discovery # Most notably, GitHub does not support this # Redirect URLs in your OAuth provider can be set to this: # /oauth/sso//callback* # The asterisk is important, as it allows for any query parameters to be passed # Authentik for example uses regex so it can be set to (regex): # /oauth/sso//callback.* # [[oidc.providers]] # name = "CPlusPatch ID" # id = "cpluspatch-id" # This MUST match the provider's issuer URI, including the trailing slash (or lack thereof) # url = "https://id.cpluspatch.com/application/o/versia-testing/" # client_id = "XXXX" # client_secret = "XXXXX" # icon = "https://cpluspatch.com/images/icons/logo.svg" [http] # The full URL Versia Server will be reachable by (paths are not supported) base_url = "https://versia.localhost:9900" # Address to bind to (0.0.0.0 is suggested for proxies) bind = "versia.localhost" bind_port = 9900 # Bans IPv4 or IPv6 IPs (wildcards, networks and ranges are supported) banned_ips = [] # Banned user agents, regex format banned_user_agents = [ # "curl\/7.68.0", # "wget\/1.20.3", ] [http.proxy] # For HTTP proxies (e.g. Tor proxies) # Will be used for all outgoing requests enabled = false address = "http://localhost:8118" [http.tls] # If these values are set, Versia Server will use these files for TLS enabled = false key = "" cert = "" passphrase = "" ca = "" [http.bait] # Enable the bait feature (sends fake data to those who are flagged) enabled = false # Path to file of bait data (if not provided, Versia Server will send the entire Bee Movie script) send_file = "" # IPs to send bait data to (wildcards, networks and ranges are supported) bait_ips = ["127.0.0.1", "::1"] # User agents to send bait data to (regex format) bait_user_agents = ["curl", "wget"] [frontend] # Enable custom frontends (warning: not enabling this will make Versia Server only accessible via the Mastodon API) # Frontends also control the OAuth flow, so if you disable this, you will need to use the Mastodon frontend enabled = true # The URL to reach the frontend at (should be on a local network) url = "http://localhost:3000" [frontend.routes] # Special routes for your frontend, below are the defaults for Versia-FE # Can be set to a route already used by Versia Server, as long as it is on a different HTTP method # e.g. /oauth/authorize is a POST-only route, so you can serve a GET route at /oauth/authorize # home = "/" # login = "/oauth/authorize" # consent = "/oauth/consent" # register = "/register" # password_reset = "/oauth/reset" [frontend.settings] # Arbitrary key/value pairs to be passed to the frontend # This can be used to set up custom themes, etc on supported frontends. # theme = "dark" [smtp] # SMTP server to use for sending emails server = "smtp.example.com" port = 465 username = "test@example.com" password = "password123" tls = true # Disable all email functions (this will allow people to sign up without verifying # their email) enabled = false [media] # Can be "s3" or "local", where "local" uploads the file to the local filesystem # If you need to change this value after setting up your instance, you must move all the files # from one backend to the other manually (the CLI will have an option to do this later) # TODO: Add CLI command to move files backend = "s3" # Whether to check the hash of media when uploading to avoid duplication deduplicate_media = true # If media backend is "local", this is the folder where the files will be stored # Can be any path local_uploads_folder = "uploads" [media.conversion] # Whether to automatically convert images to another format on upload convert_images = true # Can be: "image/jxl", "image/webp", "image/avif", "image/png", "image/jpeg", "image/heif", "image/gif" # JXL support will likely not work convert_to = "image/webp" # Also convert SVG images? convert_vector = false # [s3] # Can be left blank if you don't use the S3 media backend # endpoint = "" # access_key = "XXXXX" # secret_access_key = "XXX" # region = "" # bucket_name = "versia" # public_url = "https://cdn.example.com" [validation] # Checks user data # Does not retroactively apply to previously entered data max_displayname_size = 50 # Character length max_bio_size = 5000 max_note_size = 5000 max_avatar_size = 5_000_000 # Bytes max_header_size = 5_000_000 max_media_size = 40_000_000 max_media_attachments = 10 max_media_description_size = 1000 max_poll_options = 20 max_poll_option_size = 500 min_poll_duration = 60 # Seconds max_poll_duration = 1893456000 max_username_size = 30 max_field_count = 10 max_field_name_size = 1000 max_field_value_size = 1000 # Forbidden usernames, defaults are from Akkoma username_blacklist = [ "well-known", "about", "activities", "api", "auth", "dev", "inbox", "internal", "main", "media", "nodeinfo", "notice", "oauth", "objects", "proxy", "push", "registration", "relay", "settings", "status", "tag", "users", "web", "search", "mfa", ] # Whether to blacklist known temporary email providers blacklist_tempmail = false # Additional email providers to blacklist (list of domains) email_blacklist = [] # Valid URL schemes, otherwise the URL is parsed as text url_scheme_whitelist = [ "http", "https", "ftp", "dat", "dweb", "gopher", "hyper", "ipfs", "ipns", "irc", "xmpp", "ircs", "magnet", "mailto", "mumble", "ssb", "gemini", ] # Only allow those MIME types of data to be uploaded # This can easily be spoofed, but if it is spoofed it will appear broken # to normal clients until despoofed enforce_mime_types = false # Defaults to all valid MIME types # allowed_mime_types = [] [validation.challenges] # "Challenges" (aka captchas) are a way to verify that a user is human # Versia Server's challenges use no external services, and are Proof of Work based # This means that they do not require any user interaction, instead # they require the user's computer to do a small amount of work enabled = false # The difficulty of the challenge, higher is will take more time to solve difficulty = 50000 # Challenge expiration time in seconds expiration = 300 # 5 minutes # Leave this empty to generate a new key key = "" [defaults] # Default visibility for new notes # Can be public, unlisted, private or direct # Private only sends to followers, unlisted doesn't show up in timelines visibility = "public" # Default language for new notes (ISO code) language = "en" # Default avatar, must be a valid URL or left out for a placeholder avatar # avatar = "" # Default header, must be a valid URL or left out for none # header = "" # A style name from https://www.dicebear.com/styles placeholder_style = "thumbs" [federation] # This is a list of domain names, such as "mastodon.social" or "pleroma.site" # These changes will not retroactively apply to existing data before they were changed # For that, please use the CLI (in a later release) # These instances will not be federated with blocked = [] # These instances' data will only be shown to followers, not in public timelines followers_only = [] [federation.discard] # These objects will be discarded when received from these instances reports = [] deletes = [] updates = [] media = [] follows = [] # If instance reactions are blocked, likes will also be discarded likes = [] reactions = [] banners = [] avatars = [] # For bridge software, such as versia-pub/activitypub # Bridges must be hosted separately from the main Versia Server process [federation.bridge] enabled = false # Only versia-ap exists for now software = "versia-ap" # If this is empty, any bridge with the correct token # will be able to send data to your instance allowed_ips = ["192.168.1.0/24"] # Token for the bridge software # Bridge must have the same token! token = "mycooltoken" url = "https://ap.versia.social" [instance] name = "Versia" description = "A Versia Server instance" # Path to a file containing a longer description of your instance # This will be parsed as Markdown # extended_description_path = "config/extended_description.md" # Path to a file containing the terms of service of your instance # This will be parsed as Markdown # tos_path = "config/tos.md" # Path to a file containing the privacy policy of your instance # This will be parsed as Markdown # privacy_policy_path = "config/privacy_policy.md" # URL to your instance logo # logo = "" # URL to your instance banner # banner = "" # Used for federation. If left empty or missing, the server will generate one for you. [instance.keys] public = "" private = "" [permissions] # Control default permissions for users # Note that an anonymous user having a permission will not allow them # to do things that require authentication (e.g. 'owner:notes' -> posting a note will need # auth, but viewing a note will not) # See docs/api/roles.md in source code for a list of all permissions # Defaults to being able to login and manage their own content # anonymous = [] # Defaults to identical to anonymous # default = [] # Defaults to being able to manage all instance data, content, and users # admin = [] [filters] # Regex filters for federated and local data # Drops data matching the filters # Does not apply retroactively to existing data # Note contents note_content = [ # "(https?://)?(www\\.)?youtube\\.com/watch\\?v=[a-zA-Z0-9_-]+", # "(https?://)?(www\\.)?youtu\\.be/[a-zA-Z0-9_-]+", ] emoji = [] # These will drop users matching the filters username = [] displayname = [] bio = [] [logging] # Log all requests (warning: this is a lot of data) log_requests = false # Log request and their contents (warning: this is a lot of data) log_requests_verbose = false # Available levels: debug, info, warning, error, fatal log_level = "debug" # For GDPR compliance, you can disable logging of IPs log_ip = false # Log all filtered objects log_filters = true [logging.sentry] # Whether to enable https://sentry.io error logging enabled = false # Sentry DSN for error logging dsn = "" debug = false sample_rate = 1.0 traces_sample_rate = 1.0 # Can also be regex trace_propagation_targets = [] max_breadcrumbs = 100 # environment = "production" [logging.storage] # Path to logfile for requests requests = "logs/requests.log" [ratelimits] # These settings apply to every route at once # Amount to multiply every route's duration by duration_coeff = 1.0 # Amount to multiply every route's max requests per [duration] by max_coeff = 1.0 [ratelimits.custom] # Add in any API route in this style here # Applies before the global ratelimit changes # "/api/v1/accounts/:id/block" = { duration = 30, max = 60 } # "/api/v1/timelines/public" = { duration = 60, max = 200 }