Auth0 FGA blocked resource on organization type - authorization

I have 4 types, the business subscribes to the plan and gets the plan's features, the feature provides access to resources. I want to add a blocked relation to the Resources type. I don't want the user to access the can_access relationship if they have a relationship with blocked.
type user
type plan
relations
define subscriber as self
define subscriber_member as member from subscriber
type business
relations
define member as self and user_in_context
define user_in_context as self
type feature
relations
define associated_plan as self
define feature_member as subscriber_member from associated_plan
type resource
relations
define associated_feature as self
define can_access as feature_member from associated_feature but not blocked
define blocked as self
If I define the following tuple to the user, it prevents access to this resource from all business memberships.
user: user:test
relation: blocked
object: resource:get_list
When this tuple is defined, the user is blocked from all businesses to the get_list resource. I want to prevent the user from accessing the resource in the business context, how can I do it?

Related

How to express pagination in attribute based access control?

Based on my coarse reading, ABAC, i.e. attribute based access control, boils down to attach attributes to subjects, resources and other related entities (such as actions to be performed on the resources), and then evaluate a set of boolean valued functions to grant or deny the access.
To be concrete, let's consider XACML.
This is fine when the resource to be accessed is known before it hits the decision engine (PDP, in the case of XACML), e.g. view the mobile number of some account, in which case the attributes of the resource to be accessed probability can be easily retrieved with a single select SQL.
However consider the function of listing one's bank account transaction history, 10 entries per page, let's assume that only the account owner can view this history, and the transaction is stored in the database in a table transaction like:
transaction_id, from_account_id, to_account_id, amount, time_of_transaction
This function, without access control, is usually written with a SQL like this:
select to_account_id, amount, time_of_transaction
from transaction
where from_account_id = $current_user_account_id
The question: How can one express this in XACML? Obviously, the following approach is not practical (due to performance reasons):
Attach each transaction in the transaction table with the from_account_id attribute
Attach the request (of listing transaction history) with the account_id attribute
The decision rule, R, is if from_account_id == account_id then grant else deny
The decision engine fetch loops the transaction table, evaluate each row according to R, if granted, then emit the row, util 10 rows are emitted.
I assume that there will be some preprocess step to fetch the transactions first, (without consulting the decision engine), and then consult the decision engine with the fetched transaction, to see if it has access?
What you are referring to is known as 'open-ended' or data-centric authorization i.e.access control on an unknown number (or a large number) of items such as a bank account's transaction history. Typically ABAC (and XACML or alfa) have a decision model that is transactional (i.e. Can Alice view record #123?)
It's worth noting the policy in XACML/ALFA doesn't change in either scenario. You'd still write something along the lines of:
A user can view a transaction history item if the owner is XXX and the date is less than YYY...
What you need to consider is how to ask the question (that goes from the PEP to the PDP). There are 2 ways to do this:
Use the Multiple Decision Profile to bundle your request e.g. Can Alice view items #1, #2, #3...
Use an open-ended request. This is known as partial evaluation or reverse querying. Axiomatics has a product (ARQ) that addresses this use case.
I actually wrote about a similar use case in this SO post.
HTH,
David

Limit user in Fauna DB to read only his own data

We are using FaunaDB for storing users and users movie collection. For accessing data in Fauna Functions we use secret key which is binded to Roles.
Users document looks like this:
{
username:"John Doe",
email: "john#doe.com",
userID: "124"
}
Movie Collection document looks like this:
{
userID: "124",
movies:['Titanic','Forrest Gump']
}
To query user movie collection we call fauna function with role user and specific secret key generated for that role
Call(Function("Get_users_moive"), '124')
I would like to know is to possible to limit user, to query only his own data? In the function above if I give another userID it will retrun another user collection.
Thanks
You can certainly do this in Fauna. You can create "identity" documents in a Fauna database, and give those documents credentials that can be used to authenticate the user. Once a user authenticates, the secret for a token is created. From that point, the user can directly query Fauna using that secret, if you choose to allow them to do so.
In addition, Fauna has attributed-based access controls (ABAC). You define a role, which has two primary features: a privileges definition that lets you control which collections, indexes, documents, etc. that a user with the role has, and a membership definition which lets you specify which identities belong to the role.
A role's privileges and membership definitions can use predicates: functions that can make a dynamic determination of whether a privilege, or the membership should apply to the current query.
You can find out more in the documentation:
Tokens
ABAC
To ensure that a user can only access movie records that they created, you'll need to store a reference to the identity document within each movie document.
When a user uses the secret for the token that they acquired via the Login function, a role predicate can use the CurrentIdentity function to retrieve a reference to the associated identity document, and then compare that to the reference stored in the movie document. If those match, you grant read access, otherwise you don't.
For details, see:
Login
CurrentIdentity

How to implement design in OOP

I have following structure
One organization can have many environments.
One environment can have many Applications.
One application can have many Policis.
I created class of each entities i.e.
class Organization,
class Environment,
class Application,
class Policy
Now I want to apply policies to Application.
One policy should have one Policy class object. All instances of Policy are different. Every policy have unique name and ID.
Inheritance will not work, Consider following hierarchy -
Organization
Environment(Organization)
API(Environment)
Policy(API)
because every policy, required to procide all details of API, Environment, Organization.
Can we do aggregation here? Need help on this
All instances of Policy are different.
Every policy have unique name and ID
You can indicate that with the constraint :
Policy.allInstances() -> forAll(p1, p2 |
p1 <> p2 implies (p1.name <> p2.name and p1.ID <> p2.ID))
A class diagram from the information you give can be :
I do not use bidirectional relations supposing Policy does not know the associated Application(s) whose does not know associated Environment(s) whose does not know associated Organization(s).
I use multiplicities * equivalent to 0..* because nothing in your question says the minimum multiplicity is 1 each time. I do not indicate the multiplicity in the opposite direction of the relations because your question does not indicate something about them.
Inheritance will not work
A inherits B implies A is a B, among the classes your give none of them satisfy that, so there is no possible inheritance between them.
Can we do aggregation here
may be between Environment and Application because we can say an environment is composed by applications, but else where no.

Can I Read/Write from separate actors with same PersistenceId?

The Petabridge blog's Akka.Persistence intro makes it clear that you can't have multiple actors with the same PersistenceId:
The PersistenceId field is important - it uniquely identifies an entity that is persisting its state using Akka.Persistence, and there should be exactly one persistent actor at any given time for a single PersistenceId.
[...] so imagine if you have two actors with the same PersistenceId but different sequence numbers writing to the same store. It will be chaos and will inevitably error out - so that’s why it’s crucial that every PersistenceId be globally unique within your ActorSystem (at least for all actors writing to that store.)
I can think of a scenario where you would have two separate actors: one that takes care of saving persistence state to database (i.e. calls Persist()), and another one that replays messages from the journal when manually requested to do so (i.e. calls Recover()). The read and write operations would occur from different actors. Only one ever writes, and only one ever reads. However, both need the same PersistenceId.
I believe that in this scenario it should be safe to have two actors using the same PersistenceId. But given the above warnings quoted above, is there any reason why such an approach could be dangerous in practice?
I can think of a scenario where you would have two separate actors:
one that takes care of saving persistence state to database (i.e.
calls Persist()), and another one that replays messages from the
journal when manually requested to do so (i.e. calls Recover()). The
read and write operations would occur from different actors. Only one
ever writes, and only one ever reads. However, both need the same
PersistenceId.
The behaviour you require is already exposed as Persistent Actors and Persistent Views. From the docs:
While a persistent actor may be used to produce and persist events,
views are used only to read internal state based on them. Like the
persistent actor, a view has a PersistenceId to specify a collection
of events to be resent to current view. This value should however be
correlated with the PersistentId of an actor who is the producer of
the events.
Edit: updated to provide more info on how to access events in the Persistent View.
You can load from a journal by overriding the Receive method of a Persistent View. The argument for this method is an object, so you'll need to cast that object to whatever event(s) you have persisted via the Persistent Actor.
The Receive method also handles any other messages you pass to the View - e.g. a read request from the presentation layer. I usually store a list of events internally in the View and return a custom view model from these.
protected override bool Receive(object message)
{
// if the message is a previously persisted event, update our internal list
var e = message as MyEvent;
if (e != null) _events.Add(e);
return true;
// if the message is a request for a view model, read from our list of stored events
var r = message as ReadRequest;
if (r == null) return false;
Sender.Tell(new ViewModel(_events));
return true;
}

Permissions design pattern that allows date-based access

I am looking at ways to implement an authorization (not authentication) scheme in my app.
There are currently two roles in the system: A and B, but there may be more. User's only have one role.
Basically, the I have it set up now is with two database tables. One is for role-based permissions on a model, and the other is for specific user-based permissions. I am thinking that this way, users can have a set of default permissions based on their role-based permissions, but then they can also have specific permissions granted/revoked.
So for example:
table: user_permissions
columns:
user_id: [int]
action: [string]
allowed: [boolean]
model_id: [int]
model_type: [string]
table: role_permissions
columns:
role: [int]
action: [string]
model_type: [string]
In the user_permissions table, the allowed field specifies whether the action is allowed or not, so that permissions can be revoked if this value is 0.
In another table, I have the definitions for each action:
table: model_actions
columns:
action: [string]
bitvalue: [int]
model_type: [string]
I do this so that when I check permissions on a model, for example ['create', 'delete'], I can use a bitwise and operation to compare the user's permissions to the permissions I am checking. For example, a model X could have the following model_actions:
action: 'create'
bitvalue: 4
model_type: X
action: 'delete'
bitvalue: 2
model_type: X
action: 'view'
bitvalue: 1
model_type: X
If my user/role permissions specify that the create, view, and delete actions for the model X are 1, 0, and 1, respectively, then this is represented as 110 based on the model_actions table. When I check if I can create model X, I use the fact that create is 4 to construct the bitarray 100. If the bitwise AND operation of 110 and 100 is 100, then the permission is valid.
ANYWAY, I think I have a granular permissions design pattern figured out. If not PLEASE feel free to educate me on the subject.
The actual focus of my question concerns the following:
Some of my models have actions that are time-dependent. For example, you can only delete a model Y no more than 24 hours after its created_at date.
What I am thinking is to automatically create a cron job when the model is created that will update the permissions on the date that this occurs. In the case of model Y, I would want to insert a record into the user_permissions that revokes the 'delete' action of this model.
My question is: is this advisable?
Edit
What if I include another row in the SQL tables, that specifies a date for the permission to 'flip' (flipDate)? If a flipDate is defined, and if the current date is after the flip date, the permission is reversed. This seems much easier to manage than a series of cron jobs, especially when models may be updated.
Your models seems fine, but... you are reinventing the wheel a bit and, as you realized yourself, your model is not flexible enough to cater for additional parameters e.g. time.
In the history of authorization, there is a traditional, well-accepted model, called role-based access control (RBAC). That model works extremely well when you have a clearly defined set of roles and a hierarchy between these roles.
However, when the hierarchy isn't as clear or when there are relationships (e.g. a doctor-patient relationship) or when there are dynamic attributes (such as time, location, IP...), RBAC doesn't work well. A new model emerged a few years back called attribute-based access control (ABAC). In a way, it's an evolution or generalization of RBAC. With ABAC, you can define authorization logic in terms of attributes. Attributes are a set of key-value pairs that describe the user, the action, the resource, and the context. With attributes, you can describe any number of authorization situations such as:
a doctor can view a patient's medical record between 9am and 5pm if and only if the patient is assigned to that doctor
a nurse can edit a patient's medical record if and only if the patient belongs to the same clinic as the nurse.
ABAC enables what one could call PBAC or policy-based access control since now the authorization logic moves away from proprietary code and database schemes into a set of centrally managed policies. The de-facto standard for these policies is XACML, the eXtensible Access Control Markup Language.
In a nutshell, XACML lets you do what you are looking for in a technology-neutral way, in a decoupled, externalized way. It means, you get to define authorization once and enforce it everywhere it matters.
I recommend you check out these great resources on the topic:
NIST's website on RBAC (the older model)
NIST's website on ABAC (the model you need)
the OASIS XACML Technical Committee website (the standard that implements ABAC)
Gartner's Externalized Authorization Management
Kuppinger Cole's Dynamic Authorization Management
The ALFA plugin for Eclipse, a tool to write attribute-based policies.