Cloudfier is an approach for building business applications, and since role-based access control (RBAC) is such an important thing for any business application, Cloudfier is bound to provide support for modeling what users can do to application objects. Here is our plan.
[There are several proposals by third-parties on how to do security with UML (remember, TextUML is UML), but the OMG itself has not officially adopted any so far. So, since there is no standard and no clear 3rd-party winner, I decided I might as well make up my own approach, tailor-made for the needs of business applications.]
The gist of the idea:
- classes, attributes and operations may declare “access constraints”, which are UML constraints specialized on describing how accessible an element (in practice, classes, attributes and operations);
- those constraints allow specific capabilities (like create and destroy instances of a classes, read and write attribute values or associations links, and call operations);
- access constraints are defined for one or more user roles – one element may have multiple constraints, matching different roles;
- the constraint specification may be an expression that (typically) will take the current logged-in user/actor in account in order to decide access should be allowed.
Profile changes
TextUML models, by default, can count on a UML profile called mdd_extensions. This profile defines several extensions to the base UML standard, for things such as allowing one to mark a class as a test class, elements as debuggable, activities as closures, blocks as initialization blocks, type casts, attribute derivations etc. The mdd_extensions profile was enhanced to support the idea of role classes and access constraints
Role classes
A role class is a class that represents a role an actor can play. Here is the definition of the stereotype:
(* A role class is a class that represents the role for a user. *)
stereotype Role extends UML::Class
end;
Access constraints
Access constraints are constraints with the “Access” stereotype applied to them. The stereotype allows setting:
- the roles affected – user roles that are covered by this constraint;
- the capabilities allowed – what users with one of the roles can do. Values are values of the
AccessCapability
enumeration.
The constraint specification, which is a boolean value specification (could be just a constant, or a complex expression), determines (in addition to the user roles) whether the constraint applies. See the source that defines those extensions:
stereotype Invariant extends UML::Constraint
end;
(* You can declare access constraints on any element. *)
stereotype Access specializes Invariant
property roles : Class[1,*];
property allowed : AccessCapability[*];
end;
enumeration AccessCapability
/* Objects */
Create;
Delete;
/* Attributes/links */
Read;
Update;
/* Operations */
Call;
end;
Notation changes
The notation changes were:
- you can now declare a class as a role class by using the ‘
role
‘ modifier (or you can apply the Role stereotype directly if you prefer); - you can now use the ‘
allow
‘ keyword to declare access constraints on objects, attributes and operations.
Here is an example that should make things clear:
model banking;
role class AccountOwner end;
role class BranchManager end;
role class AccountManager end;
role class SecurityOfficer end;
class Branch
reference manager : BranchManager;
end;
class BankAccount
allow BranchManager, AccountManager create, delete;
reference owner : AccountOwner;
reference branch : Branch;
attribute balance : Double
allow AccountOwner read { System#user() == self.owner }
allow BranchManager read { System#user() == self.branch.manager }
allow SecurityOfficer read;
operation withdraw(amount : Double)
allow AccountOwner { System#user() == self.owner };
operation deposit(amount : Double)
allow AccountOwner { System#user() == self.owner };
end;
end.
For simplicity, I omitted details on the role classes, but they are normal classes otherwise and can have any attributes you may want, may specialize other classes etc.
But the use of the “allow” keyword to declare access constraints should be clear. If it isn’t to you, please provide feedback, here or on the project issue tracker.
Great, when can I use this?
TextUML Toolkit users: you should be able to use this if you update the plug-in in Eclipse now.
Cloudfier users: Cloudfier needs to honor the new access control features when running the model natively, or generating code, and some work is required before that happens, so you will need to wait a little longer to use this feature in your Cloudfier applications.
No matter which tool you use (or even if you don’t use any of them), if you have any opinion on the choices made, your feedback is really quite welcome.