Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/michael-tiger-2010/dragonjson/llms.txt

Use this file to discover all available pages before exploring further.

dragonJSON forwards authentication headers on every request — both GET reads and POST mutations. Credentials are set once at client initialization and applied automatically for the lifetime of that client instance. On the server side, the Node.js reference implementation uses a tree-shaped authConfig object that maps path prefixes to $auth functions, with the deepest match in the tree taking precedence.

Client-side: Bearer token

Pass a Bearer token via the auth option. dragonJSON adds it as an Authorization header on every request:
const [server] = dragonJSON("https://api.example.com/data", {
  auth: "Bearer my-token",
});
// Adds: Authorization: Bearer my-token
// on every GET and POST request
This is the standard pattern for JWT or API token auth. The string is forwarded verbatim, so you can use any scheme your server expects — just include the full header value.

Client-side: custom headers

For API keys, tenant identifiers, or any other custom header, use the headers option:
const [server] = dragonJSON("https://api.example.com/data", {
  headers: {
    "X-Api-Key": "my-key",
    "X-Tenant-Id": "acme",
  },
});
auth and headers can be combined. When both are present, Authorization is merged into the headers object alongside any custom entries.

Server-side auth config (Node.js)

The Node.js reference server reads auth rules from a top-level authConfig object defined in server.js. Each key in the object is a path segment name (not a dot-separated string — the keys form a tree). Each node in the tree may contain a $auth function and any number of named child nodes. $auth function signature
$auth(token, accessArray, operation)
token
string
The Bearer token extracted from the Authorization header. Empty string ("") if no Authorization header was sent.
accessArray
string[]
Path segments after the matched node. For example, if $auth is defined on users and the requested path is users.user1.name, then accessArray is ["user1", "name"].
operation
string
What the client is trying to do. One of:
  • "get" — single-path read (GET ?path=)
  • "get:batch" — path appeared in a batched read (GET ?paths=)
  • "get:command" — freeform $get with a command parameter
  • "set"$set mutation (plain POST, no __op)
  • "add"$add mutation (__op: "add")
  • "remove"$remove mutation (__op: "remove")
Return true to allow the request, false to deny it. The server responds with HTTP 403 on denial. Example authConfig This is the full authConfig from the Node.js server:
const authConfig = {
  users: {
    $auth(token, accessArray, operation) {
      if (operation === "get" || operation === "get:batch") {
        return ["admin-secret", "readonly-token"].includes(token);
      }
      return token === "admin-secret"; // mutations require admin
    },
    user1: {
      $auth(token, accessArray, operation) {
        return token === "admin-secret";
      },
    },
  },
  meta: {
    $auth(token, accessArray, operation) {
      if (operation.startsWith("get")) return true; // reads open
      return token === "admin-secret";
    },
  },
  posts: {
    $auth(token, accessArray, operation) {
      return true; // fully public
    },
  },
};

Resolution rule

The server resolves the correct $auth function using a deepest-match-wins strategy. For a requested path such as users.user1.name:
1

Check the deepest matching node

Look up authConfig.users.user1.$auth. It exists, so call it with accessArray = ["name"]. If it returns true, the request proceeds.
2

Fall back one level

If no $auth was found at users.user1, fall back to authConfig.users.$auth and call it with accessArray = ["user1", "name"].
3

Fall back to root

If that also has no match, check for a root-level authConfig.$auth and call it with the full segment array.
4

No match — path is open

If no $auth is found at any level, the path has no restriction and the request is allowed.
Paths not matched by any authConfig entry are open by default. Add a root-level $auth to lock down the entire tree:
const authConfig = {
  $auth(token, accessArray, operation) {
    return token === "my-global-secret";
  },
  // per-path overrides still work below this
};

Build docs developers (and LLMs) love