{"schemaVersion":1,"title":"Protect documentation by tier","url":"https://appgram.github.io/docsy/guides/tutorials/lock-mode","markdownUrl":"https://appgram.github.io/docsy/format-md/guides/tutorials/lock-mode","jsonUrl":"https://appgram.github.io/docsy/agent/pages/guides/tutorials/lock-mode.json","version":"current","locale":"en","markdown":"# Protect documentation by tier\n\nConfigure server-side documentation permissions using ordered YAML rules.\n\nWritten by: [nedimf](https://github.com/nedimf), [AppGram](https://appgram.dev)\n\nLock mode protects authored articles, generated API pages, SDK reference pages, Markdown exports, and search results with the same ordered permission rules.\n\nDocsy performs authorization. Your identity provider or application remains responsible for authentication.\n\n## Define tiers and rules\n\nStart with the most specific rule because the first matching rule wins:\n\n```yaml\naccess:\n  mode: locked\n  provider:\n    type: header\n    tierHeader: x-docsy-tiers\n    userHeader: x-docsy-user\n  tiers:\n    developer:\n      label: Developer\n      description: Public integration documentation.\n    enterprise:\n      label: Enterprise\n      description: Restricted administration and security documentation.\n  rules:\n    - pattern: /guides/internal/**\n      tiers: [enterprise]\n    - pattern: /api/license-keys\n      tiers: [enterprise]\n    - pattern: /api/**\n      tiers: [developer, enterprise]\n  gate:\n    title: This documentation is locked.\n    description: Sign in with an account that can access this page.\n    loginUrl: https://app.example.com/login\n    loginLabel: Sign in to continue\n```\n\n`*` matches one path segment. `**` matches any number of segments. A route with no matching rule remains public, even in locked mode.\n\n## Use trusted headers\n\nThe header provider is intended for Cloudflare Access, oauth2-proxy, an ingress gateway, or your own authentication proxy. The proxy must:\n\n1. Remove client-supplied identity headers.\n2. Authenticate the visitor.\n3. Set the trusted tier and optional user headers.\n4. Prevent direct access around the proxy.\n\nTier values can be comma- or space-separated. A trusted request might contain:\n\n```http\nx-docsy-user: user_123\nx-docsy-tiers: developer,enterprise\n```\n\nNever expose a header-provider deployment directly to the internet. Otherwise a visitor could send the trusted headers themselves.\n\n## Ask your application with a webhook\n\nUse a webhook when your application owns the authorization decision:\n\n```yaml\naccess:\n  mode: locked\n  provider:\n    type: webhook\n    endpoint: https://app.example.com/internal/docsy/authorize\n    method: POST\n    forwardHeaders: [cookie, authorization]\n    pathHeader: x-docsy-path\n    timeoutMs: 3000\n```\n\nThe endpoint returns an identity:\n\n```json\n{\n  \"authenticated\": true,\n  \"subject\": \"user_123\",\n  \"tiers\": [\"enterprise\"]\n}\n```\n\nTimeouts, errors, invalid payloads, and non-2xx responses fail closed for protected routes.\n\n## Build and deploy locked mode\n\nLocked mode changes Astro from a static build to a standalone server because authorization runs for every request. It can run on Node or on the tested Bun production runtime:\n\n```bash\nnpm run build\nHOST=0.0.0.0 PORT=8080 npm run preview\n```\n\nTo use Bun after the same Node build, start with `npm run start:bun` instead of `npm run preview`. Bun 1.3.5 or newer is supported as the production runtime; Node remains the build toolchain.\n\nRebuild after changing access mode, rules, article sources, or ingestion configuration. Put the server process behind the trusted proxy or connect it to the webhook provider before exposing it publicly.\n\n","contentLocale":"en","isFallback":false,"authorship":{"authors":[{"name":"nedimf","kind":"human","github":"nedimf","avatar":"/docsy/assets/authors/nedimf.png","role":"AppGram","id":"nedimf","url":"https://github.com/nedimf"},{"name":"AppGram","kind":"organization","github":"AppGram","url":"https://appgram.dev","avatar":"/docsy/assets/ag-logo.svg","id":"appgram"}],"contributors":[],"reviewedBy":[]},"editUrl":"https://github.com/AppGram/docsy/edit/main/content/tutorials/lock-mode.md"}