Skip to content

pckrishnadas88/fastify-permissions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fastify-permissions

🔐 Route-level permission middleware for Fastify — supports custom permission checks

npm version

npm downloads

Test

license


✨ Features

  • ✅ Add permissions to routes using config.permissions
  • ✅ Register custom permission checks (e.g. isAdmin, isAuthenticated)
  • ✅ Supports multiple permissions per route
  • ✅ Denies requests with a customizable 403 Forbidden error
  • ✅ Compatible with fastify v5

📦 Setup

npm i fastify-permissions

🚀 Usage


Usage

Register Plugin

import Fastify from 'fastify'
import fastifyPermissions from 'fastify-permissions'

const app = Fastify()

// Add a fake user to the request
app.addHook('onRequest', async (req) => {
  const role = req.headers['x-role'] || 'guest'
  req.user = { id: 1, role }
})

app.register(fastifyPermissions, {
  conditions: {
    isAdmin: async (req) => req.user?.role === 'admin',
    isAuthenticated: async (req) => !!req.user,
    isPublic: async (_) => true,
    isManager: async (req) => req.user?.role === 'manager'
  }
})

app.get('/admin', {
  config: {
    permissions: ['isAdmin']
  },
  handler: async (req, reply) => {
    reply.send({ msg: 'admin ok' })
  }
})

app.get('/user', {
  config: {
    permissions: ['isAuthenticated']
  },
  handler: async (req, reply) => {
    reply.send({ msg: 'user ok' })
  }
})

app.get('/public', {
  config: {
    permissions: ['isPublic']
  },
  handler: async (req, reply) => {
    reply.send({ msg: 'public ok' })
  }
})

app.get('/manager', {
  config: {
    permissions: ['isAdmin', 'isManager']
  },
  handler: async (req, reply) => {
    reply.send({ msg: 'manager ok' })
  }
})

app.listen({ port: 3000 })

Output Examples

✅ Successful Request

// Simulate a request with role = 'admin'
curl -H "x-role: admin" http://localhost:3000/admin
// Response:
// { "msg": "admin ok" }

curl -H "x-role: admin" http://localhost:3000/manager
// Response:
// { "msg": "manager ok" }

curl http://localhost:3000/public
// Response:
// { "msg": "public ok" }

🚫 Forbidden Request

// Simulate forbidden request using same app setup
import Fastify from 'fastify'
import fastifyPermissions from 'fastify-permissions'

const app = Fastify()

app.addHook('onRequest', async (req) => {
  req.user = { id: 1, role: 'guest' } // 👈 Not an admin
})

app.register(fastifyPermissions, {
  conditions: {
    isAdmin: async (req) => req.user?.role === 'admin'
  }
})

app.get('/admin', {
  config: {
    permissions: ['isAdmin']
  },
  handler: async (req, reply) => {
    reply.send({ msg: 'admin ok' })
  }
})

app.inject({
  method: 'GET',
  url: '/admin'
}).then(res => {
  console.log(res.statusCode) // 403
  console.log(res.json())     // { error: 'Forbidden', permission: 'isAdmin' }
})
// Simulate a request with role = 'guest'
curl -H "x-role: guest" http://localhost:3000/admin
// Response:
// {
//   "error": "Forbidden",
//   "permission": "isAdmin"
// }

curl -H "x-role: admin" http://localhost:3000/manager
// Response:
// {
//   "error": "Forbidden",
//   "permission": "isManager"
// }

Example

Run the sample app:

node examples/basic.js

Multiple permissions support as array

permissions: ['isAdmin', 'isAuthenticated']

All conditions must pass (AND logic)

⭐ Star This Project

If you find this plugin useful, give it a ⭐ on GitHub!

https://github.com/pckrishnadas88/fastify-permissions

Run tests

npm test

License

MIT License © 2025 Krishnadas P.C

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published