{"id":13472600,"url":"https://github.com/mercurius-js/auth","last_synced_at":"2025-09-10T04:35:34.424Z","repository":{"id":37955579,"uuid":"355152889","full_name":"mercurius-js/auth","owner":"mercurius-js","description":"Mercurius Auth Plugin","archived":false,"fork":false,"pushed_at":"2024-10-12T09:34:19.000Z","size":259,"stargazers_count":83,"open_issues_count":9,"forks_count":15,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-12T14:58:17.509Z","etag":null,"topics":["fastify","graphql","mercurius","nodejs","plugin"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mercurius-js.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-06T10:47:00.000Z","updated_at":"2024-10-27T10:35:11.000Z","dependencies_parsed_at":"2024-01-16T07:22:25.524Z","dependency_job_id":"d9f8dd85-b13d-493b-937e-68ec3b52958a","html_url":"https://github.com/mercurius-js/auth","commit_stats":{"total_commits":138,"total_committers":14,"mean_commits":9.857142857142858,"dds":0.6159420289855073,"last_synced_commit":"24897284981392fe23c631da310ddf34e4277237"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mercurius-js%2Fauth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mercurius-js%2Fauth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mercurius-js%2Fauth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mercurius-js%2Fauth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mercurius-js","download_url":"https://codeload.github.com/mercurius-js/auth/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248586249,"owners_count":21128997,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fastify","graphql","mercurius","nodejs","plugin"],"created_at":"2024-07-31T16:00:56.138Z","updated_at":"2025-04-12T14:59:00.129Z","avatar_url":"https://github.com/mercurius-js.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# mercurius-auth\n\n![CI workflow](https://github.com/mercurius-js/auth/workflows/CI%20workflow/badge.svg)\n\nMercurius Auth is a plugin for [Mercurius](https://mercurius.dev) that adds configurable Authentication and Authorization support.\n\nFeatures:\n\n- Define auth directives on fields anywhere in your schema and this plugin will apply custom policies against these protected fields when a GraphQL request is made.\n- Works in both normal and gateway mode.\n- In addition to the matching auth directive, auth policies have access to the same GraphQL information that any GraphQL resolver has access to.\n- Build up an auth context to load identities onto the context before policies are applied.\n- Define custom errors.\n- GraphQL spec compliant.\n\n## Docs\n\n- [Install](#install)\n- [Quick Start](#quick-start)\n  - [Directive (default) mode](#directive-default-mode)\n  - [External Policy mode](#external-policy-mode)\n- [Examples](#examples)\n- [Benchmarks](#benchmarks)\n- [API](docs/api/options.md)\n- [Auth Context](docs/auth-context.md)\n- [Apply Policy](docs/apply-policy.md)\n- [Auth Directive](docs/auth-directive.md)\n  - [Schema filtering](docs/schema-filtering.md)\n  - [Schema replacement](docs/schema-replacement.md)\n- [External Policy](docs/external-policy.md)\n- [Errors](docs/errors.md)\n- [Federation](docs/federation.md)\n\n## Install\n\n```bash\nnpm i fastify mercurius mercurius-auth\n```\n\n## Quick Start\n\nWe have two modes of operation for Mercurius Auth:\n\n### Directive (default) mode\n\nSetup in Directive mode as follows (this is the default mode of operation):\n\n```js\n'use strict'\n\nconst Fastify = require('fastify')\nconst mercurius = require('mercurius')\nconst mercuriusAuth = require('mercurius-auth')\n\nconst app = Fastify()\n\nconst schema = `\n  directive @auth(\n    requires: Role = ADMIN,\n  ) on OBJECT | FIELD_DEFINITION\n\n  enum Role {\n    ADMIN\n    REVIEWER\n    USER\n    UNKNOWN\n  }\n\n  type Query {\n    add(x: Int, y: Int): Int @auth(requires: USER)\n  }\n`\n\nconst resolvers = {\n  Query: {\n    add: async (_, { x, y }) =\u003e x + y\n  }\n}\n\napp.register(mercurius, {\n  schema,\n  resolvers\n})\n\napp.register(mercuriusAuth, {\n  authContext (context) {\n    return {\n      identity: context.reply.request.headers['x-user']\n    }\n  },\n  async applyPolicy (authDirectiveAST, parent, args, context, info) {\n    return context.auth.identity === 'admin'\n  },\n  authDirective: 'auth'\n})\n\napp.listen({ port: 3000 })\n```\n\n### External Policy mode\n\nInstead of using GraphQL Directives, you can implement an External Policy at plugin registration to protect GraphQL fields and types. You can find more information about implementing policy systems and how to build external policies for a GraphQL schema in the [External Policy documentation](docs/external-policy.md).\n\n```js\n'use strict'\n\nconst Fastify = require('fastify')\nconst mercurius = require('mercurius')\nconst mercuriusAuth = require('mercurius-auth')\n\nconst app = Fastify()\n\nconst schema = `\n  type Message {\n    title: String\n    message: String\n    adminMessage: String\n  }\n\n  type Query {\n    messages: [Message]\n    message(title: String): Message\n  }\n`\n\nconst messages = [\n  {\n    title: 'one',\n    message: 'one',\n    adminMessage: 'admin message one'\n  },\n  {\n    title: 'two',\n    message: 'two',\n    adminMessage: 'admin message two'\n  }\n]\n\nconst resolvers = {\n  Query: {\n    messages: async (parent, args, context, info) =\u003e {\n      return messages\n    },\n    message: async (parent, args, context, info) =\u003e {\n      return messages.find(message =\u003e message.title === args.title)\n    }\n  }\n}\n\napp.register(mercurius, {\n  schema,\n  resolvers\n})\n\napp.register(mercuriusAuth, {\n  // Load the permissions into the context from the request headers\n  authContext (context) {\n    const permissions = context.reply.request.headers['x-user'] || ''\n    return { permissions }\n  },\n  async applyPolicy (policy, parent, args, context, info) {\n    // When called on field `Message.adminMessage`\n    // policy: { requires: 'admin' }\n    // context.auth.permissions: ['user', 'admin'] - the permissions associated with the user (passed as headers in authContext)\n    return context.auth.permissions.includes(policy.requires)\n  },\n  // Enable External Policy mode\n  mode: 'external',\n  policy: {\n    // Associate policy with the 'Message' Object type\n    Message: {\n      // Define policy for 'Message' Object type\n      __typePolicy: { requires: 'user' },\n      // Define policy for 'adminMessage' field\n      adminMessage: { requires: 'admin' }\n    },\n    // Associate policy with the Query root type\n    Query: {\n      // Define policy for 'message' Query\n      messages: { requires: 'user' }\n    }\n  }\n})\n\napp.listen({ port: 3000 })\n```\n\n## Examples\n\nCheck [GitHub repo](https://github.com/mercurius-js/auth/tree/master/examples) for more examples.\n\n## Benchmarks\n\n### Normal GraphQL Server Mode | Without Auth\n\nLast run: `2021-04-21`\n\n```text\n┌─────────┬──────┬──────┬───────┬───────┬─────────┬─────────┬───────┐\n│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%   │ Avg     │ Stdev   │ Max   │\n├─────────┼──────┼──────┼───────┼───────┼─────────┼─────────┼───────┤\n│ Latency │ 4 ms │ 5 ms │ 9 ms  │ 13 ms │ 5.21 ms │ 2.01 ms │ 57 ms │\n└─────────┴──────┴──────┴───────┴───────┴─────────┴─────────┴───────┘\n┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬─────────┬─────────┐\n│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg      │ Stdev   │ Min     │\n├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤\n│ Req/Sec   │ 11135   │ 11135   │ 18223   │ 18671   │ 17550.19 │ 2049.52 │ 11134   │\n├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤\n│ Bytes/Sec │ 5.86 MB │ 5.86 MB │ 9.58 MB │ 9.82 MB │ 9.23 MB  │ 1.08 MB │ 5.86 MB │\n└───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴─────────┴─────────┘\n\nReq/Bytes counts sampled once per second.\n193k requests in 11.03s, 102 MB read\n```\n\n### Normal GraphQL Server Mode | With Auth\n\nLast run: `2021-04-21`\n\n```text\n┌─────────┬──────┬──────┬───────┬───────┬─────────┬────────┬───────┐\n│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%   │ Avg     │ Stdev  │ Max   │\n├─────────┼──────┼──────┼───────┼───────┼─────────┼────────┼───────┤\n│ Latency │ 5 ms │ 5 ms │ 10 ms │ 14 ms │ 5.59 ms │ 2.1 ms │ 64 ms │\n└─────────┴──────┴──────┴───────┴───────┴─────────┴────────┴───────┘\n┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬─────────┬─────────┐\n│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg      │ Stdev   │ Min     │\n├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤\n│ Req/Sec   │ 9463    │ 9463    │ 17279   │ 17583   │ 16586.55 │ 2260.65 │ 9459    │\n├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤\n│ Bytes/Sec │ 4.98 MB │ 4.98 MB │ 9.08 MB │ 9.25 MB │ 8.72 MB  │ 1.19 MB │ 4.98 MB │\n└───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴─────────┴─────────┘\n\nReq/Bytes counts sampled once per second.\n182k requests in 11.03s, 96 MB read\n```\n\n### Normal GraphQL Server Mode | With Introspection Filters\n\nLast run: `2022-05-24`\n\n```text\n┌─────────┬───────┬───────┬───────┬───────┬──────────┬─────────┬────────┐\n│ Stat    │ 2.5%  │ 50%   │ 97.5% │ 99%   │ Avg      │ Stdev   │ Max    │\n├─────────┼───────┼───────┼───────┼───────┼──────────┼─────────┼────────┤\n│ Latency │ 10 ms │ 12 ms │ 30 ms │ 47 ms │ 13.59 ms │ 6.54 ms │ 155 ms │\n└─────────┴───────┴───────┴───────┴───────┴──────────┴─────────┴────────┘\n┌───────────┬─────────┬─────────┬────────┬─────────┬─────────┬─────────┬─────────┐\n│ Stat      │ 1%      │ 2.5%    │ 50%    │ 97.5%   │ Avg     │ Stdev   │ Min     │\n├───────────┼─────────┼─────────┼────────┼─────────┼─────────┼─────────┼─────────┤\n│ Req/Sec   │ 2559    │ 2559    │ 7607   │ 8335    │ 7101.55 │ 1579.83 │ 2559    │\n├───────────┼─────────┼─────────┼────────┼─────────┼─────────┼─────────┼─────────┤\n│ Bytes/Sec │ 1.04 MB │ 1.04 MB │ 3.1 MB │ 3.39 MB │ 2.89 MB │ 643 kB  │ 1.04 MB │\n└───────────┴─────────┴─────────┴────────┴─────────┴─────────┴─────────┴─────────┘\n\nReq/Bytes counts sampled once per second.\n78k requests in 11.05s, 31.8 MB read\n```\n\n### Gateway GraphQL Server Mode | Without Auth\n\nLast run: `2021-04-21`\n\n```text\n┌─────────┬───────┬───────┬───────┬───────┬──────────┬──────────┬────────┐\n│ Stat    │ 2.5%  │ 50%   │ 97.5% │ 99%   │ Avg      │ Stdev    │ Max    │\n├─────────┼───────┼───────┼───────┼───────┼──────────┼──────────┼────────┤\n│ Latency │ 29 ms │ 32 ms │ 66 ms │ 88 ms │ 34.96 ms │ 11.57 ms │ 195 ms │\n└─────────┴───────┴───────┴───────┴───────┴──────────┴──────────┴────────┘\n┌───────────┬────────┬────────┬─────────┬────────┬────────┬────────┬────────┐\n│ Stat      │ 1%     │ 2.5%   │ 50%     │ 97.5%  │ Avg    │ Stdev  │ Min    │\n├───────────┼────────┼────────┼─────────┼────────┼────────┼────────┼────────┤\n│ Req/Sec   │ 1286   │ 1286   │ 3039    │ 3135   │ 2819.5 │ 543.65 │ 1286   │\n├───────────┼────────┼────────┼─────────┼────────┼────────┼────────┼────────┤\n│ Bytes/Sec │ 450 kB │ 450 kB │ 1.06 MB │ 1.1 MB │ 987 kB │ 190 kB │ 450 kB │\n└───────────┴────────┴────────┴─────────┴────────┴────────┴────────┴────────┘\n\nReq/Bytes counts sampled once per second.\n28k requests in 10.03s, 9.87 MB read\n```\n\n### Gateway GraphQL Server Mode | With Auth\n\nLast run: `2021-04-21`\n\n```text\n┌─────────┬───────┬───────┬───────┬───────┬──────────┬──────────┬────────┐\n│ Stat    │ 2.5%  │ 50%   │ 97.5% │ 99%   │ Avg      │ Stdev    │ Max    │\n├─────────┼───────┼───────┼───────┼───────┼──────────┼──────────┼────────┤\n│ Latency │ 29 ms │ 33 ms │ 69 ms │ 93 ms │ 35.92 ms │ 12.46 ms │ 209 ms │\n└─────────┴───────┴───────┴───────┴───────┴──────────┴──────────┴────────┘\n┌───────────┬────────┬────────┬─────────┬────────┬────────┬────────┬────────┐\n│ Stat      │ 1%     │ 2.5%   │ 50%     │ 97.5%  │ Avg    │ Stdev  │ Min    │\n├───────────┼────────┼────────┼─────────┼────────┼────────┼────────┼────────┤\n│ Req/Sec   │ 1216   │ 1216   │ 2943    │ 3129   │ 2744.7 │ 552.54 │ 1216   │\n├───────────┼────────┼────────┼─────────┼────────┼────────┼────────┼────────┤\n│ Bytes/Sec │ 426 kB │ 426 kB │ 1.03 MB │ 1.1 MB │ 961 kB │ 193 kB │ 426 kB │\n└───────────┴────────┴────────┴─────────┴────────┴────────┴────────┴────────┘\n\nReq/Bytes counts sampled once per second.\n27k requests in 10.03s, 9.61 MB read\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmercurius-js%2Fauth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmercurius-js%2Fauth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmercurius-js%2Fauth/lists"}