mailnix / Authentication

    Getting started

    Authentication

    Every MCP and REST request uses an OAuth 2.1 bearer JWT, audience-bound to the surface it targets.

    Discovery

    Spec-compliant clients discover the Authorization Server (AS) via RFC 9728 + RFC 8414 metadata. Hit the protected-resource endpoint for the surface you want to call:

    # MCP surface
    GET https://mcp.mailnix.ch/.well-known/oauth-protected-resource
    
    # REST surface
    GET https://api.mailnix.ch/.well-known/oauth-protected-resource

    Follow authorization_servers to the AS metadata document at https://app.mailnix.ch/.well-known/oauth-authorization-server: that document carries the issuer, JWKS, token endpoint, and supported grants.

    Grant types

    The AS supports three paths to a bearer:

    • Anonymous bootstrap (client_credentials): the seeded mailnix-anonymous-bootstrap client. One HTTP call, sandbox-only, no user identity required. This replaces the old dev_key handshake.
    • Authorization Code + PKCE S256: the standard interactive login. Pass resource=https://mcp.mailnix.ch/mcp or resource=https://api.mailnix.ch/v1 to bind the issued token to the right audience. Limerion IDP handles the user-facing login.
    • Dashboard API keys: Settings → API keys lets you mint, rotate, and revoke keys in the web UI. The plaintext token is shown once on issuance.

    Scopes & audience

    Tokens are scoped and audience-bound per surface:

    SurfaceAudienceScopes
    MCPhttps://mcp.mailnix.ch/mcpmcp:read / mcp:send-sandbox / mcp:send / mcp:admin
    RESThttps://api.mailnix.ch/v1api:read / api:send / api:admin

    A token minted for the REST audience cannot drive the MCP server (and vice versa). The browser-safe mnxpub_ publishable keys are pinned to /v1 only.

    Refresh tokens

    Refresh tokens rotate on every /oauth/token call. Presenting a rotated-out refresh token revokes the entire chain; that's the theft-detection signal. Store the most recent refresh token securely and discard older copies.

    Auth errors

    • invalid_token: missing, expired, or wrong-audience bearer. The response carries WWW-Authenticate: Bearer realm="mailnix" with resource_metadata=....
    • insufficient_scope: token is authentic but missing the required scope tier (e.g. api:read presented on POST /v1/messages).
    • forbidden: paused or banned project, or banned user.