Clients for the distributed authorization service Permit. This project support both the creation and enforcment of policy in a distributed system.
The mechanism is the set of software components that know how to enforce policy in the system. Here, the mechanism is rerpresented by Permit::Mechanism
which is a HTTP client to the server-side component PermitServer.
In the context of access control, a system is modeled by three sets: subjects (S), actions (A) and resources (R). Resources (or objects) are the assets in the system that need to be protected. Subjects are the active entities in the system that perform actions on the resources.
permit = Permit::Mechanism.new(:subject_id => "core:users_1", :service_name => "wally")
permit.able_to?(:read, "core:space_1")
# => true or false
The method able_to?
asks if the subject core:users_1
has the read
rights to the core:space_1
resource.
The service_name
argument may be omited when using the service_name
global config.
There are a few convetions here: subject_id
is a unique ID across all services. Anything that matched (\w+)\:([a-zA-Z]\w*)_(\d)
is permited as subject_id
. There is a convetion for it's name as follows:
ID = service-name ":" entity-plural-form "_" entity-id
The service-name
should be unique between all the services. The entity-plural-form
should be unique within the service (for example, a DB table name). The entity-id
should be unique between all entity-plural-form
(for example, a table id).
Each service is able to enforce policy is also enabled to create policies. The policy is the set of rules that determine what is allowed in the system. In a cleaner language, a Policy is a set of rules that concern one resource.
policy = Permit::Policy.new(:resource_id => "wally:wall_1231")
policy.rules.add(:subject_id => "core:user_4", :action => :read)
policy.rules.add(:subject_id => "core:user_6", :action => :manage)
policy.commit
The rules are persisted on the server-side Permit component. The policy.commit
publishes the rules through an message queue. Although commit
implements delivery guarantee it will not stop the execution of the program.
You can also revoge rules:
policy.rules.remove(:subject_id => "core:user_4")
policy.commit
This will remove all rules that concerns the resource wally:wall_1231
and the subject core:user_4
.
As a shorthand method you can call add and remove passing a block, this will auto-commit the rules after the block is executed. For example, you could add rules with the same effect as follows:
policy = Permit::Policy.new(:resource_id => "wally:wall_1231")
policy.add do |rules|
rules.add(:subject_id => "core:user_4", :action => :read)
rules.add(:subject_id => "core:user_6", :action => :manage)
end
You can also define Policy in background. For now we support DelayedJob as queue system. You should create the job as follows:
opts = { :resource_id => "core:course_1", :service_name => "core" }
job = Permit::PolicyJob.new(opts) do |policy|
policy.add(:subject_id => "core:user_1", :action => :read)
end
The job will be scheduled for delivery as soon as possible when you call Delayed::Job.enqueue(job)
.
There are few configuration options. Here are the options available:
Permit.configure do |config|
config.logger = Logger.new(STDOUT)
config.deliver_messages = true # Silent mode when falsy
config.mechanism_host = "http://server-side-component-of-permit.com"
config.service_name = "wally"
end
The default values are the ones defined above. The deliver_messages
is useful when used on test environment where no messages should be delivered. The service_name
is used by Permit::Mechanism
and Permit::Policy
when creating and enforcing policy.
The policy is the set of rules that determine what is allowed in the system. The mechanism is the set of software and/or hardware components that know how to enforce the policy in the system [1].
The principle states that mechanism should be strictly separated and independent from the policy they enforce. This provides flexibility because:
- it makes the mechanisms reusable for diferent kinds of policies
- it allows policies to be reused for multiple systems
- it supports the evolution and analysis of policies over time.
- Don't double commit rules (if calling Policy#commit multiple times)
- Client-side caching
- Documenting pattern for sevices policies.
This project intend to run on Ruby 1.8.7 (MRI).
This project is maintained and funded by Redu Educational Techologies.
Copyright (c) 2012 Redu Educational Technologies
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.