SoarPolicyAccessManager
This Access Manager adheres to SoarAm::AmApi. It is initialized with a soar_sr service registy client (https://rubygems.org/gems/soar_sr)
This access manager denies access for unauthenticated requests, that is, request that do not have request.session['user'] set. If set, this access manager then queries the service registry for meta regarding the service identifier in question.
If the service meta indicates no policy, the request is allowed. It the service meta indicates a policy, the policy service is asked, given the authenticated subject identifier, service identifier, resource identifier and request parameters, whether the request should be allowed. This access manager then allows / denies accordingly.
In the case of the service not found in the service registry, or a failure of any kind, the request is denied. In the interest of security, exceptions while authorizing will be swallowed by this access manager. Only the last exception message will be reported to STDERR.
Quickstart
When using soar_sc the soar_authorization gem automagically passes values set in your router as post parameters in authorization requests to policies.
SoarSc Routing params | SoarAuthorization params | AccessManager Params | Policy Params |
---|---|---|---|
service_name | service_identifier | requestor_identifier | |
path | resource_identifier | resource_identifier | |
authentication.identifier | authentication_identifier | subject_identifier |
Stub provider
Use this provider during tests and development when you don't want any http policy authorization requests.
Create meta variable mapping services to policy identifiers (names)
> meta = {
'service_identifier1' => {
'policy' => 'policy1'
}
}
Create policies variable mapping policy identifiers to resources. Access to a resource is allowed if your authentication identifier (uuid) is present in the array.
> policies = {
'policy1' => {
'/resource_identifier1' => ['authentication_identifier1'],
'/resource_identifier2' => []
}
}
Instantiate the stub provider and pass it to the access manager model.
> provider = Soar::Policy::AccessManager::ModelProvider::Stub.new(meta: meta, policies: policies})
> policy_am = Soar::Policy::AccessManager::Model.new(provider)
> puts policy_am.authorized?({
service_identifier: 'service_identifier1',
resource_identifier: '/resource_identifier1',
request: {
params: {},
authentication_identifier: 'authentication_identifier1'
}
})
Policy provider
Use this provider during tests and development to send authorization requests directly to a policy.
Create meta variable mapping services to policy identifiers (names)
> meta = {
'service_identifier1' => 'policy1',
'service_identifier2' => 'policy2'
}
Create policies variable mapping policy identifiers to policy endpoints.
> policies = {
'policy1' => 'http://localhost:8080/allow',
'policy2' => 'http://localhost:8080/deny'
}
Instantiate the stub provider and pass it to the access manager model.
> provider = Soar::Policy::AccessManager::ModelProvider::Policy.new(meta: meta, policies: policies})
> policy_am = Soar::Policy::AccessManager::Model.new(provider)
> puts policy_am.authorized?({
service_identifier: 'service_identifier1',
resource_identifier: '',
request: {
params: {},
authentication_identifier: ''
}
})
Service registry provider
Use this provider during production. It reaches out to the service registry and policies. It's used by soar sc.
> service_registry = SoarSc::service_registry
> provider = Soar::Policy::AccessManager::ModelProvider::ServiceRegistry.new(service_registry)
> policy_am = Soar::Policy::AccessManager::Model.new(provider)
> puts policy_am.authorized?({
service_identifier: 'service_identifier1',
resource_identifier: '/path',
request: {
params: request.params,
authentication_identifier: SoarAuthentication::Authentication.new(request).identifier
}
})
This access manager can be used with the SoarAuthorization::Authorize middleware:
> SoarAuthorization::Authorize::register_access_manager('/path', 'path-service', policy_am)
> use SoarAuthorization::Authorize
Tests
Local
Unit Tests
$ bundle exec rspec
Provider Integration Tests
Stub provider
$ TEST_ORCHESTRATION_PROVIDER=Stub bundle exec cucumber
Service Registry provider
Serve two policies, allow all and deny all, locally via file config.ru using Rack webserver.
$ docker-compose up
Test providers for the stub and service registry via the model api interface
$ TEST_ORCHESTRATION_PROVIDER=ServiceRegistry bundle exec cucumber
Policy provider
Serve two policies, allow all and deny all, locally via file config.ru using Rack webserver.
$ docker-compose up
Test providers for the stub and service registry via the model api interface
$ TEST_ORCHESTRATION_PROVIDER=Policy bundle exec cucumber
CI
$ USER_NAME=$USER USER_ID=$(id -u) POLICY_HOST=policy:8080 TEST_ORCHESTRATION_PROVIDER=ServiceRegistry docker-compose --file docker-compose.test.yml up --abort-on-container-exit --remove-orphans
EXIT_CODE=$(docker ps -a -f "name=soar-policy-access_manager-tests" -q | xargs docker inspect -f "{{ .State.ExitCode }}")
exit $EXIT_CODE
Enviroment Variables explained
Sets USER_NAME and USER_ID to your currently logged in user. This is important when you're mounting volumes into a container. Root in the container = root on your local.
USER_NAME=$USER
USER_ID=$(id -u)
Select whether you're testing the ServiceRegistry , Policy or Stub provider. Defaults to Stub
TEST_ORCHESTRATION_PROVIDER=Stub
Contributing
Please send feedback and comments to the author at:
Ernst van Graan [email protected]
This gem is sponsored by Hetzner (Pty) Ltd - http://hetzner.co.za
License
The gem is available as open source under the terms of the MIT License.