@allstar/hemera-acl
v4.1.0
Published
Access control pluging for hemera applications
Downloads
9
Maintainers
Readme
Hemera ACL
Hemera pluging adding Access control via coarse based roles, or granular permissions
Installation
$ npm install @allstar/hemera-acl
Usage
Basic Setup
const Hemera = require('nats-hemera')
const nats = require('nats')
const Acl = require('@allstar/hemera-acl')
const nc = nats.connect({
servers: ['nats://0.0.0.0:4222']
})
const hmera = new Hemera(nc)
hemera.use(acl, {
separator: ':' // default
})
hemera.ready(() => {
// go!
})
Roles
For coarse control, handlers can define a roles
array (or single string) specifying the roles that are allowed
hemera.add({
topic: 'math'
, cmd: 'add'
, auth$: {
roles: 'admin' // only admin access
}
}, function(req, cb) {
// admin user
console.log(this.user$)
cb(null, true)
})
hemera.add({
topic: 'math'
, cmd: 'subtract'
, auth$: {
roles: ['admin', 'manager'] // admin OR manager access
}
}, function(req, cb) {
// admin user
console.log(this.user$)
cb(null, true)
})
hemera.add({
topic: 'math'
, cmd: 'divide'
, auth$: {
roles: [] // no roles - superuser access only
}
}, function(req, cb) {
// admin user
console.log(this.user$)
cb(null, true)
})
Calling w/ roles
Adding a user
object to the hemera metadata
with the roles
array key populated to pass acl validation.
Request that do not pass authorization will return an error
with the code EAUTH. Users with the special key superuser
set tot true
will always pass authorization
hemera.act({
topic: 'math'
, cmd: 'add'
, meta$: {
user: {
roles: ['salesman', 'admin'] // passes authorization for the add handler
}
}
}, function(err, res) {
console.log(res)
})
hemera.act({
topic: 'math'
, cmd: 'subtract'
, meta$: {
user: {
roles: ['grunt'] // fails validatin for the subtract handler
}
}
}, function(err, res) {
console.log(err.code) // EAUTH
})
hemera.act({
topic: 'math'
, cmd: 'divide'
, meta$: {
user: {
superuser: true // always authorized
}
}
}, function(err, res) {
console.log('success!')
})
Permissions
Permissions allow you to specify an arbitry level of granularity from 1 level to as deep as you wish to go. Giving the user object
a nested permissions
object will dictate what a user has access to. The terminal key in the object tree should be a boolean
value (true or false). The absence of a key is equivelent to false
const user = {
roles: ['grunt']
, permissions: {
auth: {
user: {
create: true
, read: true
, update: true
, delete: false
}
}
, blog: {
post: {
create: true
, update: true
, read: true
, delete: true
}
, tag: {
read: true
}
}
}
}
To mark a handler with the desired permission include a permissions
key to the auth object.
hemera.add({
topic: 'blog'
, cmd: 'post'
, auth$: {
permissions: 'blog:post:create' // need to permission to create blog posts
}
}, function(req, cb) {
console.log(this.user$)
cb(null, true)
})
hemera.add({
topic: 'user'
, cmd: 'delete'
, auth$: {
permissions: 'one:very:very:specific:perm:only:few:people:have' // very granular permission
}
}, function(req, cb) {
console.log(this.user$)
cb(null, true)
})
hemera.add({
topic: 'internal'
, cmd: 'dangerous'
, auth$: {
permissions: ' ' // super user only access (empty string)
}
}, function(req, cb) {
console.log(this.user$)
cb(null, true)
})
Calling with permissions
hemera.act({
topic: 'math'
, cmd: 'add'
, meta$: {
user: {
permissions: {
auth: {
user: {
create: true
}
}
, one: {
very: {
very: {
specific: {
perm: {
only: {
few: {
people: {
have: true
}
}
}
}
}
}
}
}
}
}
}
}, function(err, res) {
console.log(res)
})