Security and networking

How to expose Dinatos safely: reverse proxy and TLS, CORS, API keys, and self-signed certificates.

Network exposure

docker-compose.yml publishes Postgres (5432) and the app (8000) on 127.0.0.1 only. Other machines cannot reach them.

To make Dinatos reachable elsewhere:

  1. Put a reverse proxy (nginx, Caddy, Traefik) in front of port 8000.

  2. Terminate TLS in the proxy. The app has no TLS of its own.

CORS

CORS controls which web origins a browser lets call the API. Set it with DINATOS_CORS_ALLOWED_ORIGINS (see Configuration reference).

  • Default ["*"] allows any origin. This is safe here because login uses a bearer token in a header, not cookies, so there is no ambient session for another site to abuse.

  • The built-in web app is same-origin and never needs CORS. Native apps do not use it either.

  • It matters only for a web build on another origin (see Clients). Restrict it to that origin:

    DINATOS_CORS_ALLOWED_ORIGINS: '["https://app.example.com"]'
    
  • To lock it down fully when you use only the built-in app, set [].

API keys and the MCP endpoint

/mcp serves the MCP server. It accepts only API keys (Authorization: Bearer dnk_...) that users create under Settings -> API keys. A key is shown once and stored only as a hash. Anyone holding it can act as its owner, except for managing keys and administering the server.

Proxy requirements:

  • Serve it over HTTPS. Over HTTP the key travels in the clear.

  • Pass the Authorization header through.

  • Do not buffer or cache /mcp responses. No sticky sessions are needed.

To keep MCP internal, block /mcp at the proxy. Nothing else depends on it.

Self-signed certificates

Clients cannot verify a self-signed certificate and refuse to connect. On Android and Linux apps, users can turn on Allow self-signed certificates next to the Server URL. It is off by default and skips certificate checks for that server. Browsers have no such option. A CA-issued certificate, such as Let’s Encrypt, avoids the problem.

Accounts and sessions

  • Passwords are hashed with Argon2.

  • Logins last DINATOS_SESSION_TTL_DAYS (default 30) and can be ended individually by logging out.

  • Anyone can register unless you set DINATOS_ALLOW_REGISTRATION=false. The first account is the administrator.

Report vulnerabilities as described in the security policy.