Edit Page

Default Configuration

RESTHeart

Introduction

This page presents the RESTHeart default configuration splitting it in different sections.

The default configuration applies when RESTHeart is started without specifying a configuration file:

$ java -jar restheart.jar

The default configuration template can be printed out with the following command:

$ java -jar restheart.jar -t
Note
The default configuration is fine most of the times. You just want to change few options and the suggested way is using the default configuration with the needed overrides. See modify the configuration with overrides

Standalone configuration

The default configuration enables several plugins that require MongoDB. If you are using RESTHeart without MongoDB an alternative default configuration can be used with the -s option, where s stands for standalone.

This configuration enables the fileRealmAuthenticator and the fileAclAuthorizer and disables the MongoDB data APIs.

It defines the user admin but the password must be set overriding the configuration. The following command sets the password of the admin user as secret using the RHO environment variable:

$ RHO="/fileRealmAuthenticator/users[userid='admin']/password->'secret'" java -jar core/target/restheart.jar -s

Listeners

# RESTHeart Configuration File.
## See https://restheart.org/docs/setup/#configuration-files

---
# HTTP Listener
# WARNING: Using the http listener is not secure.
http-listener:
  enabled: true
  host: localhost
  port: 8080

# HTTPS Listener
https-listener:
  enabled: false
  host: localhost
  port: 4443
  # The https listener requires setting up a TLS certificate.
  # See https://restheart.org/docs/security/tls/
  keystore-path: null
  keystore-password: null
  certificate-password: null

# AJP Listener
ajp-listener:
  enabled: false
  host: localhost
  port: 8009

Authentication Mechanisms

# Auth Token Authentication
# The verified token is generated by the enabled token manager
# See https://restheart.org/docs/security/authentication/basic#_token_authentication
tokenBasicAuthMechanism:
  enabled: true

# Basic Authentication
# See https://restheart.org/docs/security/authentication/basic#_basic_authentication
basicAuthMechanism:
  enabled: true
  authenticator: mongoRealmAuthenticator

# JWT Configuration Provider
# Provides consistent JWT settings (key, algorithm, issuer, audience) across all JWT components
# See https://restheart.org/docs/security/authentication/jwt#_jwt_authentication
jwtConfigProvider:
  enabled: true
  key: null        # null = auto-generate secure random key (recommended for single-node)
                   # For clustered deployments, set the same key on all nodes
  algorithm: HS256 # Supported: HS256, HS384, HS512
  issuer: restheart.org
  audience: null   # null or array of audience strings

# API Key Authentication
# See https://restheart.org/docs/security/authentication/api-key
apiKeyAuthMechanism:
  enabled: false
  authenticator: mongoApiKeyAuthenticator
  prefix: rhak_

# JSON Web Token Authentication
# See https://restheart.org/docs/security/authentication/jwt#_jwt_authentication
jwtAuthenticationMechanism:
  enabled: true
  base64Encoded: false
  usernameClaim: sub
  rolesClaim: roles
  fixedRoles: []
  #  - jwt-role

# Digest Authentication
# See https://restheart.org/docs/security/authentication/basic#_digest_authentication
digestAuthMechanism:
  # Disabled by default: requires plaintext passwords but mongoRealmAuthenticator uses bcrypt hashing
  enabled: false
  realm: RESTHeart Realm
  domain: localhost
  authenticator: mongoRealmAuthenticator

# For development purposes. Always authenticate the request with the given user
# See https://restheart.org/docs/security/authentication/basic#_identity_authentication
identityAuthMechanism:
  enabled: false
  username: admin
  roles:
    - admin
    - user

Authenticators

# fileRealmAuthenticator defines user credentials and roles inline or in a simple YAML con-file.
# See https://restheart.org/docs/security/authentication/authenticators#_file_realm_authenticator
fileRealmAuthenticator:
  enabled: false
  #conf-file: ./users.yml
  users:
    - userid: admin
      password: null
      roles: [admin]

# mongoApiKeyAuthenticator verifies API keys stored in a MongoDB collection.
# The account it builds carries the roles named on the *key* document, never the user's:
# a key is deny-by-default, so it reaches only what has been granted to it deliberately.
# Keys are hashed with SHA-256 rather than bcrypt — a key is high-entropy, and bcrypt's
# slowness would be paid on every request instead of once per login.
# Expiry wants a TTL index on `expiresAt`; revocation takes effect within cache-ttl.
mongoApiKeyAuthenticator:
  enabled: false
  keys-db: restheart
  keys-collection: apiKeys
  prop-hash: hash
  prop-principal: user
  prop-roles: roles
  prop-expires: expiresAt
  track-last-used: true
  cache-enabled: true
  cache-size: 1000
  cache-ttl: 60000
  cache-expire-policy: AFTER_WRITE

# mongoRealmAuthenticator authenticates users defined in a MongoDB collection.
# See https://restheart.org/docs/security/authentication/authenticators#_mongo_realm_authenticator
mongoRealmAuthenticator:
  enabled: true
  users-db: restheart
  users-collection: users
  prop-id: _id
  prop-password: password
  json-path-roles: $.roles
  bcrypt-hashed-password: true
  bcrypt-complexity: 12
  # When true, API requests to create or update accounts will return HTTP 400
  # (Bad Request) if the provided password fails strength validation
  enforce-minimum-password-strength: false
  # Password strength levels: 0=Weak, 1=Fair, 2=Good, 3=Strong, 4=Very Strong
  minimum-password-strength: 3
  # When enabled, creates a default admin user at RestHeart startup if no admin user exists
  create-user: true
  # Defines the user document structure for the default admin user created at startup.
  # Password must be bcrypt-hashed when bcrypt-hashed-password=true
  # Default password is 'secret' (hashed below)
  # See https://bcrypt-generator.com for generating bcrypt hashes
  create-user-document: '{"_id": "admin", "password": "$2a$12$lZiMMNJ6pkyg4uq/I1cF5uxzUbU25aXHtg7W7sD2ED7DG1wzUoo6u", "roles": ["admin"]}'
  cache-enabled: false
  cache-size: 1_000
  cache-ttl: 60_000 # in milliseconds
  cache-expire-policy: AFTER_WRITE
  # List of request parameter names to copy into account properties after successful authentication.
  # Useful for copying metadata attached by interceptors (e.g., tenantId, organizationId).
  # When omitted or empty, no parameters are copied (default behavior).
  # attached-props:
  #   - tenantId
  #   - organizationId

# Cookie Authentication
# see: https://restheart.org/docs/security/authentication/cookie#_cookie_authentication

# Sets auth cookie on POST /token/cookie (or legacy: when '?set-auth-cookie' is present)
# Compatible with both rndTokenManager and jwtTokenManager
authCookieSetter:
  enabled: true # Enabled by default for /token/cookie endpoint
  name: rh_auth # The name of the cookie to be set
  domain: localhost # The domain within which the cookie is valid.
  path: / # The cookie path, applicable to the entire domain.
  http-only: true # If true enhances security by making the cookie inaccessible to JavaScript.
  same-site: true # Restricts the cookie to first-party contexts, preventing CSRF attacks.
  same-site-mode: strict # Strictly prevents the cookie from being sent along with cross-site requests.
  ttl: 15 # Cookie expiration time in minutes (matches jwtTokenManager/ttl)
  allow-legacy: false # If true, allows legacy ?set-auth-cookie query parameter on any endpoint (not recommended)

# Creates Authorization header from auth cookie. Compatible with Basic and JWT auth.
authCookieHandler:
  enabled: true # Enabled by default for cookie-based authentication

# Clears auth cookie on POST /logout, logging out the user
authCookieRemover:
  enabled: true # Enabled by default
  secure: false # If request to clean the cookie should be authenticated
  defaultUri: /logout # The endpoint that triggers this service.

Authorizers

# fileAclAuthorizer authorizes requests according to the Access Control List defined inline or in a YAML file.
# See https://restheart.org/docs/security/authorization#file-acl-authorizer
fileAclAuthorizer:
  enabled: false
  #conf-file: ./acl.yml
  permissions:
    - role: admin
      predicate: path-prefix('/')
      priority: 0

# mongoAclAuthorizer authorizes requests according to the Access Control List defined in a MongoDB collection.
# See https://restheart.org/docs/security/authorization#mongo-acl-authorizer
mongoAclAuthorizer:
  enabled: true
  acl-db: restheart
  acl-collection: acl
  # Clients with root-role can execute any request
  root-role: admin
  cache-enabled: true
  cache-size: 1_000
  cache-ttl: 5_000 # in milliseconds
  cache-expire-policy: AFTER_WRITE

# originVetoer protects from CSRF attacks by forbidding requests whose Origin header is not whitelisted
# See https://restheart.org/docs/security/authorization#originvetoer
originVetoer:
  enabled: false
  whitelist:
    - https://restheart.org
    - http://localhost
  # when true, requests with no Origin header (non-browser clients) are allowed;
  # browser requests are still validated against the whitelist.
  # Since 9.6 the default changed to true; set to false to restore pre-9.6 behavior.
  allow-missing-origin: true
  # Optional paths to skip Origin header checks. Supports patterns like /{var}/path/*
  # ignore-paths:
  #   - /{tenant}/bucket.files/{id}/binary
  #   - /coll/docid

# fullAuthorizer authorizes all requests
fullAuthorizer:
  enabled: false
  authentication-required: true

Token Managers

# Token Manager
# See https://restheart.org/docs/security/authentication/authenticators#_token_managers

# Generates and verifies auth tokens. First configured manager is used.
# Token returned via auth-token header on successful authentication.

# rndTokenManager generates auth tokens using a random number generator.
rndTokenManager:
  enabled: false
  ttl: 15 # in minutes
  srv-uri: /tokens

# jwtTokenManager generates JWT auth tokens.
# Use this in clustered deployments, since all nodes sharing the key
# can verify the token independently
jwtTokenManager:
  enabled: true
  ttl: 15 # in minutes
  srv-uri: /token
  # Note: key, algorithm, issuer, audience configured via jwtConfigProvider
  # additional JWT claims from accounts properties
  account-properties-claims:
  # - foo # property name
  # - /nested/property # xpath expr for nested properties

restheart-accounts

Application-level account management (registration, email verification, invitations, password reset, OAuth social login). All plugins are disabled by default and require MongoDB — they are not available in standalone mode. See restheart-accounts overview and configuration reference.

Note
JWT key and issuer are not configured here — they are sourced automatically from jwtConfigProvider.

Enable the whole plugin by setting accountsConfig.enabled: true and configuring the required fields. All other services cascade-enable automatically once accountsConfig is active.

# Core configuration provider — enabling this activates the whole plugin.
# See https://restheart.org/docs/accounts/configuration
accountsConfig:
  enabled: false
  # The MongoDB database and collection holding users, teams, invitations and
  # oauth_codes are sourced from mongoRealmAuthenticator (users-db and
  # users-collection), so that accounts writes users where the authenticator
  # reads them.
  # If the users collection carries the 'jsonSchema' metadata, the user document
  # is validated against that schema on POST /auth/register.
  app-name: "My App"
  # JWT access token TTL in minutes. Key and issuer are sourced from jwtConfigProvider.
  jwt-ttl: 15
  cookie-domain: localhost
  cookie-name: rh_auth
  frontend-url: http://localhost:4200
  frontend-app-url: http://localhost:4200/app
  terms-version: "1.0"
  privacy-version: "1.0"
  default-locale: en
  # Custom email template paths (null = use built-in templates)
  # templates:
  #   verification:   etc/email-templates/verification.html
  #   password-reset: etc/email-templates/password-reset.html
  #   invite:         etc/email-templates/invite.html

  # ── Membership SPI (9.4.1+) ─────────────────────────────────────────────
  # See https://restheart.org/docs/accounts/membership-providers

  # JWT claim name for the active team identifier.
  # Default: "team".
  team-claim-name: team

  # Role name for regular (non-admin) team members.
  # Default: "member". Set to "user" if existing ACL rules already use that label.
  member-role-name: member

  # System ACL role assigned to users after email verification or OAuth login.
  # Default: "user". Override per-team via override-accounts-default-role.
  default-role: user

  # Team role assigned to the user who creates a new team.
  # Stored in user.teams[].role and team.members[].role.
  # Default: "owner". Override per-team via override-accounts-ownership-role.
  ownership-role: owner

  # Set to false to disable /auth/invite, /auth/resend-invite,
  # /auth/teams and /auth/switch-team.
  # Useful when a custom MembershipProvider exposes its own equivalent endpoints.
  membership-endpoints-enabled: true

  # Additional JWT claims propagated from request attached-parameters to tokens
  # issued by accounts endpoints (verify, activate, reset-password, switch-team, OAuth).
  # Mirrors jwtTokenManager.account-properties-claims: use the same list so that
  # all token-issuance paths produce identical JWTs.
  # For multi-team deployments, include the teams claim (e.g. "teams").
  # authDb is always included automatically — never list it here.
  account-properties-claims:
  # - srvNode  # example: attached-param set by SrvNodeEnricher in multi-team deployments

# Dependency-injection service holding the active MembershipProvider.
accountsService:
  enabled: false

# Ensures MongoDB collections and indexes required by restheart-accounts are in place.
accountsInitializer:
  enabled: false

# POST /auth/register — public user signup with email verification
registerService:
  enabled: false

# GET  /auth/verify — email verification via one-time token link
emailVerificationService:
  enabled: false

# POST /auth/forgot-password — sends a password-reset link, or re-sends the
# verification email if the account hasn't completed email verification yet
forgotPasswordService:
  enabled: false

# PATCH /auth/reset-password — applies a reset token and sets a new password
resetPasswordService:
  enabled: false

# PATCH /auth/activate — activates an invited user and sets their password
activateService:
  enabled: false

# POST /auth/invite — invites a user to the caller's team
inviteService:
  enabled: false

# POST /auth/resend-invite — re-sends an expired invitation email
resendInviteService:
  enabled: false

# GET  /auth/teams — lists the authenticated user's team memberships
getTeamsService:
  enabled: false

# POST /auth/switch-team — switches the active team and reissues the JWT cookie
switchTeamService:
  enabled: false

# Interceptor: clears the auth cookie when token authentication fails
tokenFailedAuthInterceptor:
  enabled: false

# OAuth 2.0 social login (Google, GitHub, custom providers)
# See https://restheart.org/docs/accounts/google-oauth
oauthConfig:
  enabled: false
  api-base-url: http://localhost:8080
  frontend-success-url: http://localhost:4200/app
  frontend-error-url: http://localhost:4200/login?error=oauth_error
  providers:
    google:
      enabled: false
      client-id: null
      client-secret: null
      scope: "openid email profile"
    # github:
    #   enabled: false
    #   client-id: null
    #   client-secret: null
    #   scope: "user:email"

# Core OAuth service — manages provider registration and authorization-code exchange.
oauthService:
  enabled: false

# GET  /auth/oauth/authorize/{provider} — starts the OAuth flow
oauthInitiator:
  enabled: false

# GET  /auth/oauth/callback/{provider}  — handles the OAuth callback
oauthCallback:
  enabled: false

# Built-in Google OAuth 2.0 provider
googleOAuthProvider:
  enabled: false

# Built-in GitHub OAuth 2.0 provider
githubOAuthProvider:
  enabled: false

# Emails plugin (SMTP email sender) (required for registration, invitations, password reset)
# See https://restheart.org/docs/accounts/configuration
emails:
  enabled: false
  app-name: "My App"
  sender-email: noreply@example.com
  smtp-hostname: localhost
  smtp-port: 465
  smtp-username: null
  smtp-password: null

OAuth 2.0 / 2.1 Services

All OAuth services are disabled by default and must be explicitly enabled. See OAuth 2.0 / 2.1 for the full documentation.

# OAuth 2.0 token endpoint — password, client_credentials, authorization_code grants
# See https://restheart.org/docs/security/oauth
authTokenService:
  uri: /token
  # Redirect target for GET /token/redirect. null (default) means the endpoint
  # returns 400 unless a per-request override-redirect-url is attached instead.
  redirect-url: null                # e.g. https://app.example.com/callback

# OAuth 2.0 Authorization Server Metadata (RFC 8414)
# Endpoint: GET /.well-known/oauth-authorization-server
# Returns server metadata for automatic client discovery (API gateways, MCP clients, CLI tools).
oauthAuthorizationServerMetadataService:
  enabled: false
  # Optional: override scheme+host for metadata URLs (needed behind a TLS-terminating proxy).
  # Falls back to the request Host header when null.
  base-url: null                    # e.g. https://api.example.com
  # URI of the authorization endpoint — must match oauthAuthorizationService URI.
  authorize-endpoint-uri: /authorize
  # Optional: URI of the dynamic client registration endpoint (RFC 7591). When set,
  # registration_endpoint is included in the AS metadata response. Enable
  # oauthClientRegistrationService to activate the endpoint.
  # registration-endpoint-uri: /register

# OAuth 2.1 Authorization Code + PKCE endpoint (RFC 7636)
# GET /authorize  — redirects to login-url
# POST /authorize — issues authorization code after successful authentication
# Requires: jwtTokenManager enabled, login-url set, allowed-redirect-uris configured.
oauthAuthorizationService:
  enabled: false
  # URL of the frontend login page (required)
  login-url: null                   # e.g. https://myapp.example.com/login
  # Allowed redirect_uri values — supports * wildcard
  allowed-redirect-uris:
    - http://localhost:*

# OAuth 2.0 Protected Resource Metadata (RFC 9728)
# Endpoint: GET /.well-known/oauth-protected-resource[/{resource-path}]
# Used by MCP clients to discover the authorization server before starting the OAuth flow.
oauthProtectedResourceMetadataService:
  enabled: false
  # Optional: same as base-url in oauthAuthorizationServerMetadataService.
  base-url: null                    # e.g. https://api.example.com

# OAuth 2.0 Dynamic Client Registration (RFC 7591)
# Endpoint: POST /register
# Allows OAuth clients (e.g. mcp-inspector, MCP SDKs) to self-register without admin
# intervention. Pair with oauthAuthorizationServerMetadataService's
# registration-endpoint-uri to advertise this endpoint in the AS metadata response.
oauthClientRegistrationService:
  enabled: false

restheart-stripe

Stripe SaaS billing: customer lifecycle, Checkout, Customer Portal, webhook ingestion, plan catalog and seat licensing. All plugins are disabled by default and require MongoDB. See restheart-stripe overview and configuration reference.

Enable the whole plugin by setting stripeConfig.enabled: true and configuring secret-key/webhook-secret. subscriptions and products are independent modes — enable either or both.

# Stripe SaaS billing: Customer lifecycle, Checkout, Customer Portal, webhook
# ingestion, plan catalog and seat licensing.
# See https://restheart.org/docs/stripe
stripeConfig:
  enabled: false
  # sk_test_... in development, sk_live_... in production. Never commit to
  # version control - inject via environment variable substitution.
  secret-key: $(STRIPE_SECRET_KEY)
  # From the Stripe Dashboard -> Developers -> Webhooks -> signing secret.
  webhook-secret: $(STRIPE_WEBHOOK_SECRET)

  # The MongoDB database containing the teams collection is sourced from
  # mongoRealmAuthenticator (users-db), the same way accountsConfig sources
  # it, so this module always reads and writes team documents where
  # restheart-accounts writes them.
  teams-collection: teams

  subscriptions:
    enabled: true
    # Plan id assigned to an entity with no subscription. Must name a key
    # declared under 'plans' below.
    default-plan: free
    # Trial days used when a plan does not declare its own trial-period-days.
    default-trial-period-days: 0

    success-url: "https://app.example.com/billing?success=true"
    cancel-url: "https://app.example.com/billing?canceled=true"
    portal-return-url: "https://app.example.com/billing"

    # The plan catalog. Display data (name, description, price) is not
    # configured here - it is read from the Stripe Product/Price the price
    # ids point at (GET /stripe/plans). Configuration carries only what this
    # module must enforce.
    plans:
      free:
        seats:
          mode: capped
          max: 1
      # gold:
      #   price-id-monthly: price_xxx
      #   price-id-annual:  price_yyy
      #   trial-period-days: 30
      #   seats:
      #     mode: capped   # capped | per-seat | unlimited
      #     max: 10
      #   limits:
      #     max-projects: 50

    # payment-failed and trial-will-end default to disabled: Stripe can send
    # its own equivalent email from the Dashboard ("Subscriptions and
    # emails"), and duplication cannot be detected at runtime. Enabling one
    # here means turning the matching Stripe dashboard email off.
    # notifications:
    #   payment-failed:        { enabled: false }
    #   trial-will-end:        { enabled: false }
    #   subscription-canceled: { enabled: true }
    #   over-limit:            { enabled: true }

    # Custom email template paths (null = use built-in templates)
    # templates:
    #   payment-failed:        etc/email-templates/stripe/payment-failed.html
    #   trial-will-end:        etc/email-templates/stripe/trial-will-end.html
    #   subscription-canceled: etc/email-templates/stripe/subscription-canceled.html
    #   over-limit:            etc/email-templates/stripe/over-limit.html

  products:
    enabled: false
    # Set to false to skip automatic init; use StripeInitService on demand.
    init-enabled: true

    catalog-collection: catalog
    orders-collection: orders
    transactions-collection: transactions

    default-currency: eur
    # User-document field holding the buyer's email; omit if users have none.
    # Guests always supply it in the request body.
    buyer-email-field: _id
    # Stripe-issued invoices for team-paid orders; guests always get a receipt.
    invoice-team-orders: true
    collect-tax-id: true

    success-url: "https://shop.example.com/done?session={CHECKOUT_SESSION_ID}"
    cancel-url: "https://shop.example.com/cart"

    session-expires-minutes: 60
    max-line-items: 50
    max-quantity-per-line: 100

    # Stripe Tax. false => amounts are taken as final and tax is the deployment's problem.
    automatic-tax: true

    # Offered for carts containing a physical product.
    # shipping-options:
    #   - display-name: Standard
    #     amount: 500
    #     delivery-estimate-days: { minimum: 3, maximum: 5 }
    #   - display-name: Express
    #     amount: 1500
    #     delivery-estimate-days: { minimum: 1, maximum: 2 }

    # notifications:
    #   order-confirmed: { enabled: true }
    #   order-refunded:  { enabled: true }

stripeService:
  enabled: false

stripeInitializer:
  enabled: false

stripeCheckoutService:
  enabled: false

stripePortalService:
  enabled: false

stripeSubscriptionService:
  enabled: false

# Verifies the Stripe-Signature header and processes billing events. The only
# public endpoint in the module - security is the signing secret, not authentication.
stripeWebhookService:
  enabled: false

# Grants, revokes, and lists seat licences.
stripeLicensesService:
  enabled: false

# GET /stripe/plans. Registers no ACL rule of its own - follows the deployment's
# ACL like any other endpoint except stripeWebhookService.
stripePlansService:
  enabled: false

# Shared cache for the plan catalog's Stripe display data (name, description, price),
# invalidated by stripeWebhookService on product.updated / price.updated.
stripeCatalogCache:
  enabled: false

restheart-ai

Note
restheart-ai is available starting from RESTHeart v9.9.

Vector search index management, document chunking for RAG, pluggable embedding/reranking providers, and $vectorScan brute-force search (no mongot or index required). All plugins are disabled by default except the three index-management interceptors, and all require MongoDB. See restheart-ai overview.

# Vector search index CRUD via PUT/GET/DELETE /_indexes/{name} with a
# {"type": "vectorSearch", ...} body. Enabled by default - works out of the box on any
# MongoDB with mongot (Atlas, or Community/Enterprise 8.2+).
vectorSearchIndexCreateInterceptor:
  enabled: true

vectorSearchIndexListInterceptor:
  enabled: true

vectorSearchIndexDeleteInterceptor:
  enabled: true

# Extracts text (Apache Tika) from every file uploaded to any GridFS bucket, splits it
# into overlapping chunks and stores them in target-collection. embedding-provider is
# optional: leave blank to rely on MongoDB's own autoEmbed index type on the chunks
# collection instead of restheart-ai embedding them itself. A filename with a recognized
# source code extension (.java, .py, .go, ...) is chunked at function/class boundaries
# instead, with no overlap between chunks -- see CodeAwareSplitter.
documentChunkingInterceptor:
  enabled: false
  chunk-size: 1000
  chunk-overlap: 200
  target-collection: _chunks
  embedding-provider: ""

# Embeds a text field automatically on write. Also requires the target collection to
# declare { "vectorSearch": { "textField": "...", "embeddingField": "..." } } metadata.
autoEmbeddingInterceptor:
  enabled: false
  embedding-provider: ""

# Registers the $vectorize aggregation operator (embeds text to a vector inline, at
# query time, anywhere in a pipeline).
vectorizeOperator:
  enabled: false
  embedding-provider: ""

# Re-ranks $vectorSearch results when the queried aggregation declares a "rerank"
# attribute. rerank-provider blank (default) calls the Atlas Reranking API directly via
# atlas-api-key; set it to a configured Provider<RerankModel> (voyageRerankProvider,
# cohereRerankProvider) to use that instead.
rerankingInterceptor:
  enabled: false
  # Never commit to version control - inject via environment variable substitution.
  atlas-api-key: $(ATLAS_API_KEY)
  rerank-api-url: https://api.atlas.mongodb.com/api/v1/vectorSearch/rerank
  rerank-provider: ""

# $vectorScan: brute-force vector similarity search requiring no mongot, no Atlas, and
# no vector search index of any kind. See https://github.com/SoftInstigate/restheart/issues/712
vectorScanInterceptor:
  enabled: false
  # Caps how many documents get scored per query, enforced via an injected $limit.
  default-max-candidates: 10000
  default-limit: 10

# Embedding providers (Provider<EmbeddingModel>) - enable the ones you use.
openAIEmbeddingProvider:
  enabled: false
  api-key: $(OPENAI_API_KEY)
  model: text-embedding-3-small
  base-url: https://api.openai.com/v1

voyageEmbeddingProvider:
  enabled: false
  api-key: $(VOYAGE_API_KEY)
  model: voyage-3.5
  base-url: https://api.voyageai.com/v1
  # Optional: "query" or "document" - omitted entirely (not sent as "") when blank.
  # input-type: document

# Voyage's contextualized chunk embeddings (voyage-context-4): when set as
# documentChunkingInterceptor's embedding-provider, all of a file's chunks are embedded
# together so each vector is aware of its neighbors, instead of in isolation.
voyageContextualEmbeddingProvider:
  enabled: false
  api-key: $(VOYAGE_API_KEY)
  model: voyage-context-4
  # input-type: document
  # Optional: 256, 512, 1024 (default) or 2048.
  # output-dimension: 1024

# Local embeddings via Ollama - no API key needed.
ollamaEmbeddingProvider:
  enabled: false
  base-url: http://localhost:11434
  model: nomic-embed-text

# Rerank providers (Provider<RerankModel>) - alternatives to the Atlas Reranking API.
cohereRerankProvider:
  enabled: false
  api-key: $(COHERE_API_KEY)
  model: rerank-v3.5
  base-url: https://api.cohere.com/v2

# Kept distinct from voyageEmbeddingProvider's own api-key: a deployment may use a
# different Voyage key/model for reranking than for embeddings.
voyageRerankProvider:
  enabled: false
  api-key: $(VOYAGE_API_KEY)
  model: rerank-2.5
  base-url: https://api.voyageai.com/v1

Mongo Client Provider

# Provider the MongoClient via @Inject('mclient')
mclient:
  # See https://docs.mongodb.com/manual/reference/connection-string/
  connection-string: mongodb://127.0.0.1

MongoService: MongoDB REST and Websocket API

# MongoDB REST and Websocket API
# See https://restheart.org/docs/tutorial
mongo:
  enabled: true
  uri: /

  # Exposes MongoDB collections/aggregations/streams through the MCP server (see mcpService
  # below), on top of each resource's own opt-in "mcp" metadata block. Set to false to hide
  # every MongoDB resource from MCP regardless of that per-resource metadata.
  # See https://restheart.org/docs/ai/mcp
  mcp: true

  # Expose MongoDB resources at specific URIs.
  # 'what': MongoDB resource (/db[/coll[/docid]]) or '*' for all databases
  # 'where': URI binding (absolute path or template like /{foo}/bar/*)
  # Note: Cannot mix absolute paths and path templates in 'where' URIs
  #
  # Examples:
  # The following exposes all MongoDb resources.
  # In this case the URI of a document is /db/coll/docid
  #
  #   - what: "*"
  #     where: /
  #
  # The following binds the URI /database to the db 'db'
  # In this case the URI of a document is /database/coll/docid
  #
  #   - what: /db
  #     where: /database
  #
  # The following binds the URI /api to the collection 'db.coll'
  # In this case the URI of a document is /api/docid
  #
  #   - what: /db/coll
  #     where: /api
  mongo-mounts:
    - what: /restheart
      where: /

  # Default representation format https://restheart.org/docs/mongodb-rest/representation-format/#other-representation-formats
  default-representation-format: STANDARD

  # Default etag check policy https://restheart.org/docs/mongodb-rest/etag/#etag-policy
  etag-check-policy:
    db: REQUIRED_FOR_DELETE
    coll: REQUIRED_FOR_DELETE
    doc: OPTIONAL

  # get collection cache speedups GET /coll?cache requests
  get-collection-cache-enabled: true
  get-collection-cache-size: 100
  get-collection-cache-ttl: 10_000 # Time To Live, in milliseconds default 10 seconds
  get-collection-cache-docs: 1_000 # number of documents to cache for each request

  # Check if aggregation variables use operators. https://restheart.org/docs/mongodb-rest/aggregations/#security-considerations
  aggregation-check-operators: true

  # default-pagesize is the number of documents returned when the pagesize query
  # parameter is not specified
  # See https://restheart.org/docs/read-docs#paging
  default-pagesize: 100

  # max-pagesize sets the maximum allowed value of the pagesize query parameter
  # Generally, the greater the pagesize, the more json serialization overhead occurs
  # The rule of thumb is not exceeding 1000
  max-pagesize: 1_000

  # Caches db/collection properties for better performance, avoiding 2 extra queries per document GET.
  # In multi-node deployments, property changes may take up to TTL milliseconds to sync across nodes.
  # Database and collection properties typically change only during development.
  local-cache-enabled: true
  # TTL in milliseconds; specify a value < 0 to never expire cached entries
  local-cache-ttl: 60_000 # in milliseconds

  # cache for JSON Schemas
  schema-cache-enabled: true
  # TTL in milliseconds; specify a value < 0 to never expire cached entries
  schema-cache-ttl: 60_000 # in milliseconds

  # The time limit in milliseconds for processing queries. Set to 0 for no time limit.
  query-time-limit: 0 # in milliseconds
  # The time limit in milliseconds for processing aggregations. Set to 0 for no time limit.
  aggregation-time-limit: 0 # in milliseconds

MongoDB Probe Service

Lightweight MongoDB connectivity probe service for readiness checks.

# MongoDB Probe Service
# Endpoint:
# - GET /health/db
# Must respond with HTTP 200 OK if MongoDB is reachable within the configured timeout.
# Purpose:
# Performs a minimal, non-destructive ping against MongoDB (runs `db.runCommand({ ping: 1 })`) to verify connectivity
# and report a small JSON status payload. Intended to be cheap and suitable for health/readiness checks.
# Response example:
# {
#     "db": "admin",
#     "pingMs": 2,
#     "status": "ok"
# }
database-probe:
  enabled: true
  # how long to wait for the ping before timing out (ms)
  timeout-ms: 2000
  # database name to run the ping against
  dbname: admin

MongoDB GraphQL Service

# MongoDB GraphQL API
# See https://restheart.org/docs/mongodb-graphql/
graphql:
  uri: /graphql
  db: restheart
  collection: gql-apps
  # app cache can be disabled if needed, such as during testing or development
  app-cache-enabled: true
  # app cache entries are automatically revalidated every TTR milliseconds
  app-cache-ttr: 60_000 # in milliseconds
  # default-limit is used for queries that don't specify a limit
  default-limit: 100
  # max-limit is the maximum value for a Query limit
  max-limit: 1_000
  # The time limit in milliseconds for processing queries. Set to 0 for no time limit.
  query-time-limit: 0 # in milliseconds
  verbose: false
  # restrict-mapping-db: when enabled, all mappings must use the same db as the GraphQL app definition
  restrict-mapping-db: false
  # Exposes GraphQL apps through the MCP server (see mcpService below), on top of each app's own
  # opt-in "mcp" metadata block. Set to false to hide every GraphQL app from MCP regardless of
  # that per-app metadata. See https://restheart.org/docs/ai/mcp
  mcp: true

# Automatically creates indexes on {"descriptor.uri":1} and {"descriptor.name":1}
# for GraphQL applications to improve query performance when fetching app definitions
# at scale. Enable if you have many GraphQL applications.
createIndexesOnGqlApps:
  enabled: false
Note
app-cache-enabled and app-cache-ttr are available from v8.0.9 and v8.0.11, respectively. Earlier versions use an expiring cache policy with TTL configurable via the now-deprecated graphql/app-def-cache-ttl option. See issue #523.

MCP Server

Note
Available starting from RESTHeart v9.9. See MCP Server and McpAware for the full reference.
# MCP (Model Context Protocol) server — exposes MCP-enabled APIs (MongoDB, GraphQL, and any
# other plugin implementing McpAware) to AI agents.
# See https://restheart.org/docs/ai/mcp and https://restheart.org/docs/framework/mcp-aware
mcpService:
  enabled: true
  uri: /mcp

  # How long list_apis/how_to_call results are cached before refreshing. Trades instant
  # consistency for a bounded staleness window — see the "catalog cache" section of the docs.
  catalog-ttl-seconds: 300

  # Enables the MCP "resources" primitive (resources/list, resources/read,
  # resources/templates/list) in addition to the list_apis/how_to_call tools — the official MCP
  # SDK manages resources as a single server-wide registry, not per-request, so it needs one
  # canonical externally-visible URL rather than whatever a given request's Host header says.
  # Defaults to the standard local setup; override to your real public URL for any other
  # deployment (a reverse proxy, a custom host/port, ...). Comment out to disable the resources
  # primitive entirely (list_apis/how_to_call keep working regardless).
  public-base-url: http://localhost:8080

Proxied resources

# Proxied resources - expose external APIs with RESTHeart acting as a reverse proxy
# See https://restheart.org/docs/proxy
# options:#
#  - location (required) The location URI to bound to the HTTP proxied server.
#  - proxy-pass (required) The URL of the HTTP proxied server. It can be an array of URLs for load balancing.
#  - name (optional) The name of the proxy. It is required to identify 'restheart'.
#  - rewrite-host-header (optional, default true) should the HOST header be rewritten to use the target host of the call.
#  - connections-per-thread (optional, default 10) Controls the number of connections to create per thread.
#  - soft-max-connections-per-thread (optional, default 5) Controls the number of connections to create per thread.
#  - max-queue-size (optional, default 0) Controls the number of connections to create per thread.
#  - connections-ttl (optional, default -1) Connections Time to Live in seconds.
#  - problem-server-retry (optional, default 10) Time in seconds between retries for problem server.
proxies:
#   - location: /anything
#     proxy-pass: https://httpbin.org/anything
#     name: anything

Static Web Resources

# Static Web Resources - serve static files with RESTHeart acting a web server
# See https://restheart.org/docs/static-resources
static-resources:
#  - what: /path/to/resources
#    where: /static
#    welcome-file: index.html
#    embedded: false

Other services

# Simple ping service
# Must respond with HTTP 200 OK
# If enable-extended-response is true, returns the following JSON response
# {
#    "client_ip": "<caller ip>",
#    "host": "<hostname>",
#    "message": "Greetings from RESTHeart!",
#    "version": "<RESTHeart version>"
# }
ping:
  enabled: true
  msg: Greetings from RESTHeart!
  enable-extended-response: true

# Returns the roles of the authenticated user
roles:
  uri: /roles

# A global blacklist for mongodb operators in filter query parameter
filterOperatorsBlacklist:
  blacklist: ["$where"]
  enabled: true

# Aggregation pipeline security settings
aggregationSecurity:
  enabled: true
  # Block dangerous pipeline stages that can access other databases or execute code
  stageBlacklist: ["$out", "$merge", "$lookup", "$graphLookup", "$unionWith"]
  # Block dangerous operators within pipeline stages
  operatorBlacklist: ["$where", "$function", "$accumulator"]
  # Prevent operations that access different databases than the request URI
  allowCrossDatabaseOperations: false
  # Control JavaScript execution in aggregation pipelines
  allowJavaScriptExecution: false

# bruteForceAttackGuard defends from brute force password cracking attacks
# by returning `429 Too Many Requests` when more than
# `max-failed-attempts` requests with wrong credentials
# are received in last 10 seconds from the same ip
bruteForceAttackGuard:
  enabled: false
  # Max number of failed attempts in 10 seconds sliding window
  # before returning 429 Too Many Requests
  max-failed-attempts: 5
  # If true, the source ip is obtained from X-Forwarded-For header
  # this requires that header being set by the proxy, dangerous otherwise
  trust-x-forwarded-for: false
  # When X-Forwarded-For has multiple values,
  # take into account the n-th from last element
  # e.g. with [x.x.x.x, y.y.y.y., z.z.z.z, k.k.k.k]
  # 0 -> k.k.k.k
  # 2 -> y.y.y.y
  x-forwarded-for-value-from-last-element: 0

# Sets the X-Powered-By: restheart.org response header
xPoweredBy:
  enabled: true

# Sets the Date response header
dateHeader:
  enabled: true

Logging

# Logging
# See https://restheart.org/docs/logging
# Options:
# - log-level: to set the log level. Value can be OFF, ERROR, WARN, INFO, DEBUG, TRACE and ALL. (default value is INFO)
# - log-to-console: true => log messages to the console (default value: true)
# - ansi-console: whether console supports native ANSI colors; when false, uses jansi library to enable ANSI color support (primarily for Windows compatibility). Only applies to console logging, not file logging.
# - no-colors: disables all color output in both console and file logging, overriding ansiConsole setting
# - log-to-file: true => log messages to a file (default value: false)
# - log-file-path: to specify the log file path (default value: restheart.log in system temporary directory)
# - packages: only messages form these packages are logged, e.g. [ "org.restheart", "com.restheart", "io.undertow", "org.mongodb" ]
# - full-stacktrace: true to log the full stacktrace of exceptions
# - requests-log-mode: 0 => no log, 1 => light log, 2 => detailed dump (use 2 only for development, it can log credentials)
# - tracing-headers (default, empty = no tracing): add tracing HTTP headers (Use with %X{header-name} in logback.xml); see https://restheart.org/docs/auditing
# - requests-log-exclude-patterns: Request path patterns to exclude from logging
# - requests-log-exclude-interval: Optional: Interval in minutes for logging excluded requests (default: 10)

logging:
  log-level: INFO
  log-to-console: true
  ansi-console: true
  no-colors: false
  log-to-file: false
  log-file-path: restheart.log
  packages: [ "org.restheart", "com.restheart" ]
  full-stacktrace: false
  requests-log-mode: 1
  tracing-headers:
  #  - x-b3-traceid      # vv Zipkin headers, see https://github.com/openzipkin/b3-propagation
  #  - x-b3-spanid
  #  - x-b3-parentspanid
  #  - x-b3-sampled      # ^^
  #  - uber-trace-id     # jaeger header, see https://www.jaegertracing.io/docs/client-libraries/#trace-span-identity
  #  - traceparent       # vv opencensus.io headers, see https://github.com/w3c/distributed-tracing/blob/master/trace_context/HTTP_HEADER_FORMAT.md
  #  - tracestate        # ^^

  requests-log-exclude-patterns:
  #  - "/ping"              # Exact match for load balancer health checks
  #  - "/health"            # Exact match for health endpoint
  #  - "/_ping"             # Exact match for internal ping
  #  - "/monitoring/*"      # Wildcard: excludes all paths starting with /monitoring/
  #  - "/api/*/status"      # Wildcard: excludes /api/v1/status, /api/v2/status, etc.

  requests-log-exclude-interval: 10

Metrics

# Metrics see https://restheart.org/docs/metrics

metrics:
  enabled: true
  uri: /metrics
  missing-registry-status-code: 404 # use 404 or 200

requestsMetricsCollector:
  enabled: false
  include: [ "/*" ]
  exclude: [ "/metrics", "/metrics/*" ]

jvmMetricsCollector:
  enabled: false

Core module configuration

# Base configuration for core module
core:
  # The name of this instance. Displayed in log, also allows to implement instance specific custom code
  name: default

  # The directory containing the plugins jars.
  # The path is either absolute (starts with /) or relative to the restheart.jar file
  # Just add the plugins jar to plugins-directory and they will be automatically
  # added to the classpath and registered.
  plugins-directory: plugins

  # Limit the scanning of classes annotated with @RegisterPlugin
  # to the specified packages. It can speedup the boot time
  # in case of huge plugin jars. It is usually not required.
  # Use an empty array to not limit scanning.
  # Always add the package org.restheart to the list
  plugins-packages: []

  # Set to true for verbose logging of jar scanning for plugins
  plugins-scanning-verbose: false

  # Optionally define the base url of this instance
  # Useful when RESTHeart is mediated by a reverse proxy or an API gateway to determine the instance's correct URL
  base-url: null

  # Number of I/O threads created for non-blocking tasks. Suggested value: core.
  # If <= 0, use the number of cores.
  io-threads: 0

  # Initial number of platform carrier threads for executing worker virtual threads in blocking operations.
  # Suggested value: 1.5*core.
  # If <= 0, use 1.5 times the number of cores.
  workers-scheduler-parallelism: 0

  # Max number of platform carrier threads for executing worker virtual threads in blocking operations.
  workers-scheduler-max-pool-size: 256

  # Set to true to pool buffers for io-threads. buffers pooling is always disabled for virtual worker threads.
  buffers-pooling: true

  # Use 16k buffers for best performance - as in linux 16k is generally the default amount of data that can be sent in a single write() call
  # Setting to 1024 * 16 - 20; the 20 is to allow some space for getProtocol headers, see UNDERTOW-1209
  buffer-size: 16364

  # Specifies whether the buffer pool for I/O threads should use direct buffers.
  # Direct buffers enable the JVM to leverage native I/O operations if supported by the system.
  # Virtual working threads always use heap buffers because they are faster for their operations.
  direct-buffers: true

  # In order to save bandwidth, force requests to support the giz encoding (if not, requests will be rejected)
  force-gzip-encoding: false

  # true to allow unescaped characters in URL
  allow-unescaped-characters-in-url: true

Connection options

# Connection Options
connection-options:
  # Enable HTTP/2 support
  # Note: HTTP2 as implemented by major browsers requires the use of TLS
  # How to enable TLS https://restheart.org/docs/security/tls/
  # How to check HTTP/2 protocol https://stackoverflow.com/a/54164719/4481670
  ENABLE_HTTP2: true

  # The maximum size of a HTTP header block, in bytes.
  # If a client sends more data that this as part of the request header then the connection will be closed.
  # Defaults to 1Mbyte.
  MAX_HEADER_SIZE: 1048576

  # The default maximum size of a request entity.
  # Defaults to unlimited.
  MAX_ENTITY_SIZE: -1

  #The default maximum size of the HTTP entity body when using the mutiltipart parser.
  # Generally this will be larger than MAX_ENTITY_SIZE
  # If this is not specified it will be the same as MAX_ENTITY_SIZE
  MULTIPART_MAX_ENTITY_SIZE: -1

  # The idle timeout in milliseconds after which the channel will be closed.
  # If the underlying channel already has a read or write timeout set
  # The smaller of the two values will be used for read/write timeouts.
  # Defaults to unlimited (-1).
  IDLE_TIMEOUT: -1

  # The maximum allowed time of reading HTTP request in milliseconds.
  # -1 or missing value disables this functionality.
  REQUEST_PARSE_TIMEOUT: -1

  # The amount of time the connection can be idle with no current requests
  # before it is closed;
  # Defaults to unlimited (-1).
  NO_REQUEST_TIMEOUT: -1

  # The maximum number of query parameters that are permitted in a request.
  # If a client sends more than this number the connection will be closed.
  # This limit is necessary to protect against hash based denial of service attacks.
  # Defaults to 1000.
  MAX_PARAMETERS: 1_000

  # The maximum number of headers that are permitted in a request.
  # If a client sends more than this number the connection will be closed.
  # This limit is necessary to protect against hash based denial of service attacks.
  # Defaults to 200.
  MAX_HEADERS: 200

  # The maximum number of cookies that are permitted in a request.
  # If a client sends more than this number the connection will be closed.
  # This limit is necessary to protect against hash based denial of service attacks.
  # Defaults to 200.
  MAX_COOKIES: 200

  # The charset to use to decode the URL and query parameters.
  # Defaults to UTF-8.
  URL_CHARSET: UTF-8

  # If this is true then a Connection: keep-alive header will be added to responses,
  # even when it is not strictly required by the specification.
  # Defaults to true
  ALWAYS_SET_KEEP_ALIVE: true