Access Control¶
Service
’s accomplish access control by way of ACLs or
Access Control Lists.
ACLs¶
Carbond provides a very generic and extensible ACL framework. In their most
generic form, Acl
objects map Users and Groups
to a set of Permissions which govern access to some entity.
In practice you will use one of the pre-packaged ACL types to gate access to
your Endpoint
’s and their
Operation
’s.
Endpoint ACLs¶
All Endpoint
’s can be configured with an
EndpointAcl
to govern which endpoint
Operation
’s can be accessed by users.
EndpointAcl
s defined the following permissions, one for
each HTTP method:
get
post
put
patch
delete
head
options
All permissions default to false
except the options
permission
which defaults to true
.
Here is an example of a Service
using an
EndpointAcl
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | __(function() {
module.exports = o.main({
_type: carbon.carbond.Service,
port: 8888,
dbUri: 'mongodb://localhost:27017/mydb',
authenticator: o({
_type: carbon.carbond.security.MongoDBApiKeyAuthenticator,
apiKeyParameterName: 'API_KEY',
apiKeyLocation: 'header',
userCollection: 'users',
apiKeyField: 'apiKey'
}),
endpoints: {
hello: o({
_type: carbon.carbond.Endpoint,
acl: o({
_type: carbon.carbond.security.EndpointAcl,
groupDefinitions: { // This ACL defined two groups, 'role' and 'title'.
role: 'role', // We define a group called 'role' based on the user
// property named 'role'.
title: function(user) { return user.title }
},
entries: [
{
user: { role: 'Admin' },
permissions: {
'*': true // '*' grants all permissions
}
},
{
user: { title: 'CFO' },
permissions: { // We could have used '*' here but are being
// explicit.
get: true,
post: true
}
},
{
user: '10002', // User with _id '10002'
permissions: {
get: false,
post: true
}
},
{
user: '*', // All other users
permissions: {
get: true,
post: false
}
}
]
}),
get: function(req) {
return { msg: 'Hello World!' }
},
post: function(req) {
return { msg: 'Hello World! ' + JSON.stringify(req.body) }
}
})
}
})
})
|
Collection ACLs¶
CollectionAcl
s are similar to EndpointAcl
s except that they
define a set of permissions that matches the Collection
interface.
CollectionAcl
s define the following permissions:
insert
find
update
remove
saveObject
findObject
updateObject
removebject
All permissions default to false
.
Here is an example of a Service
using a CollectionAcl
on a MongoDBCollection
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | __(function() {
module.exports = o.main({
_type: carbon.carbond.Service,
port: 8888,
dbUri: 'mongodb://localhost:27017/mydb',
authenticator: o({
_type: carbon.carbond.security.MongoDBApiKeyAuthenticator,
apiKeyParameterName: 'API_KEY',
apiKeyLocation: 'header',
userCollection: 'users',
apiKeyField: 'apiKey'
}),
endpoints: {
hello: o({
_type: carbon.carbond.mongodb.MongoDBCollection,
collectionName: 'hello',
enabled: {'*': true},
acl: o({
_type: carbon.carbond.security.CollectionAcl,
groupDefinitions: { // This ACL defined two groups, 'role' and
// 'title'.
role: 'role', // We define a group called 'role' based on the
// user property named 'role'.
title: function(user) { return user.title }
},
entries: [
{
user: { role: 'Admin' },
permissions: {
'*': true // '*' grants all permissions
}
},
{
user: { title: 'CFO' },
permissions: {
find: true,
findObject: true,
'*': false // This is implied since the default value for
// all permissions is `false`.
}
},
{
user: '10002', // User with _id '10002'
permissions: {
insertObject: true,
findObject: true
}
},
{
user: '*', // All other users
permissions: {
findObject: true
}
}
]
})
})
}
})
})
|
Re-using ACLs across multiple Endpoints¶
In some cases you may wish to re-use the same ACL across many
Endpoints
s. To do this you can simply define your ACL as its own
component and then reference it in your Endpoint
.
Example
MyAcl.js:
1 2 3 4 5 6 7 8 9 | var carbon = require('carbon-io')
var o = carbon.atom.o(module)
module.exports = o({
_type: carbon.carbond.security.CollectionAcl,
/*
* Your ACL definition
*/
})
|
Now you can reference this ACL from any Endpoint
that wished to
use that ACL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | var carbon = require('carbon-io')
var __ = carbon.fibers.__(module)
var _o = carbon.bond._o(module)
var o = carbon.atom.o(module)
__(function() {
module.exports = o.main({
_type: carbon.carbond.Service,
port: 8888,
dbUri: 'mongodb://localhost:27017/mydb',
authenticator: o({
_type: carbon.carbond.security.MongoDBApiKeyAuthenticator,
apiKeyParameterName: 'API_KEY',
apiKeyLocation: 'header',
userCollection: 'users',
apiKeyField: 'apiKey'
}),
endpoints: {
hello: o({
_type: carbon.carbond.mongodb.MongoDBCollection,
collectionName: 'hello',
enabled: {'*': true},
acl: _o('./MyAcl')
})
}
})
})
|