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.
EndpointAcls defined the following permissions, one for
each HTTP method:
getpostputpatchdeleteheadoptions
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¶
CollectionAcls are similar to EndpointAcls except that they
define a set of permissions that matches the Collection interface.
CollectionAcls define the following permissions:
insertfindupdateremovesaveObjectfindObjectupdateObjectremovebject
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
Endpointss. 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')
})
}
})
})
|