Permissions and Access Control
MarketGrid incorporates a comprehensive and powerful permission model that allows for fine control over what functionality and data a (User) may access.
The permission model requires that a User be granted specific access in order to have visibility of data and to be able to perform functions on that data. Further, the model requires that the Firm and Enterprise of a given User must have at least equivalent, if not greater, permission that that granted to the User in order for the permission for that User to be effective.
Overview
At the centre of the MarketGrid permission model are several concepts:
- Permission - the representation of a permission within the system
- Actor - who is being granted this
Permission - Permission Target - The domain over which the
Permissionwill have effect
Each permission consists of:
- An Actor (one of
Enterprise,Firm,User,Group) to whom the permission is granted; - A combination of a
Table,Action,Scopelevel, and (optionally)Instanceof a record which describe the permission that is being granted.
graph TD
subgraph Permission Model
Actor --> E[Enterprise]
Actor --> F[Firm]
Actor --> G[Group]
Actor --> H[User]
Table --> User
Table --> Firm
Table --> TO[...]
Table --> Instrument
Action --> View
Action --> Create
Action --> Amend
Action --> AO[...]
Scope --> Instance
Scope --> I[User]
Scope --> J[Firm]
Scope --> Enterprise
Scope --> Venue
Scope --> All
end
Figure - Permission Model Components
These components interact as shown in the following diagram. Whilst the diagram is in the form of an Entity-Relationship digram it is more a conceptual representation rather than a formal ER diagram.
erDiagram
Enterprise {
string ShortName
string Name
}
Firm {
string ShortName
string Name
}
User {
string UserId
string FirstName
string LastName
}
Group {
string Name
}
Enterprise ||--o{ Firm : controls
Firm ||--o{ User : employs
Firm ||--o{ Group : defines
User }o--o{ Group : "belongs to"
Enterprise ||--o{ Actor : "one of"
Firm ||--o{ Actor : "one of"
Group ||--o{ Actor : "one of"
User ||--o{ Actor : "one of"
Table {
enum Order
enum Trade
enum Market
enum Instrument
enum InstrumentMarket
enum more---
enum Firm
enum User
enum more---
enum Account
enum Holding
enum more---
enum All
}
Action {
enum View
enum ViewLevel2
enum ViewLevel3
enum Create
enum Delete
enum Cancel
enum Enter
enum EnterOnBehalfOf
enum Amend
enum SetBalance
enum Administer
enum more---
enum All
}
Scope {
enum Instance
enum User
enum Firm
enum Enterprise
enum All
}
Instance {
Id InstancePrimaryKey
Table TableId
}
Permission {
integer Id
}
Actor ||--o{ Permission : has
Table ||--o{ Permission : "is target of"
Action ||--o{ Permission : "can perform"
Scope ||--o{ Permission : "over"
Instance ||--o{ Permission : "for"
Figure - Permission Model Composition
Permission Records
Permissions are assigned through the Permission table. This table is the record keeping part of the permission model. Each permission granted in the system is stored as a record in this table and when a User performs an action in the system, there is a library of functions to examine the scope of data to which that User has visibility and the kinds of activity that the User may perform.
The complete description of this table is presented in the data model however the following extract shows the essential details with links to the details in this document
| Field | Description | Valid Values |
|---|---|---|
| Id | System assigned primary key. | Integer > 0 |
Enterprise* | The Actor to whom the permission is granted | Enterprise.Id or 0 |
Firm* | Firm.Id or 0 | |
User* | User.Id or 0 | |
Group* | Group.Id or 0 | |
| Table | The table against which the permission is applied | A valid table number or 0. 0 means that this permission grant applies to all tables. |
Action | The action that the Actor can perform | One of the values of the PermissionAction type. |
Scope | The scope level of the permission being granted | One of the values of the PermissionScope type:- Instance - User - Firm - Enterprise - Venue - All |
| Instance | If Scope is Instance then this is the specific record in the table to which permission is granted. | The Id of the instance (row) in the table to which permission is being granted if Scope is Instance , otherwise 0. |
| Status | Used to activate or deactivate (suspend) and delete the Permission record. | STATUS_ACTIVE or zero. |
Table - Permission Table
*At most one of;
Enterprise,Firm,User,Groupmay be non-zero.
Permission Actor
In MarketGrid, the concep of an Actor refers to the hierarchy of entities that interact with the system. A Permission is granted to an entity in the Actor hierarchy. In the context of the permission model, this refers to:
EnterpriseFirmGroup; orUserand aPermissionrecord must be defined as having either;- no values for any of the Actor columns. That is, a global permission that applies to every
Userin the system; or - a value in exactly one of the Actor hierarchy columns above.
Record Ownership
For each table in MarketGrid, every record (row) in the table may be owned by a User, a Firm and a Group. Three fields common to every row of every table do this, any combination of which may be set.
| Field | Description |
|---|---|
OwnerUser | Is set to the Id of the particular User that owns the record, or NULL (not set). An example of where a record would have OwnerUser set is the Order table, where an Order is always owned by a particular User (usually the User entering the Order). An example of where a record would not have OwnerUser set is the Calendar table. This is a global table that is visible to all Users. |
OwnerFirm | Is set to the Id of the particular Firm that owns the record, or NULL (not set). An example where a record would have OwnerFirm set is the Account table. Every Account belongs to a Firm |
OwnerGroup* | Is set to the Id of the particular Group that owns the record, or NULL (not set). |
Table – Record Ownership
Public Records
A record that has
OwnerUser,OwnerFirmandOwnerGroupall set to NULL (not set) is considered a public record to which anyUsermay have access.
Groups
MarketGrid supports the concept of a Group which allow collections of permitted functionality and visibility of data to be shared among a number of Users. A Group is simply a collection of Users from the same Firm. A User may belong to any number of Groups (or none), each of which in turn belongs to the User's Firm.
The following diagram illustrates with an example where FirmX has two groups, GroupJ and GroupK and four Users, UserA , UserB , UserC and UserD. Users are allocated to the Groups as shown, with UserC not being a member of any Group.
graph TD
FX[Firm X]:::darkblue --> GJ[Group J]:::blue
FX --> GK[Group K]:::blue
subgraph Group J
GJ --> UA1[User A]:::green
GJ --> UB1[User B]:::green
GJ --> UD1[User D]:::green
end
subgraph Group K
GK --> UA2[User A]:::pink
GK --> UD2[User D]:::pink
end
FX --> UA[User A]:::darkgreen
FX --> UB[User B]:::darkgreen
FX --> UC[User C]:::darkgreen
FX --> UD[User D]:::darkgreen
classDef green fill:#dfd
classDef darkgreen fill:#bdb
classDef blue fill:#ddf
classDef darkblue fill:#bbd
classDef pink fill:#fdf
classDef darkpink fill:#dbd
Figure - Group Example
Permission Target
The target of a Permission is the combination of Table, Action and Scope over which the Permission is defined.
Permission Table
Within MarketGrid data is stored in Tables. These are the objects that are defined in the datamodel and they are the basis for the way that MarketGrid describes the markets defined in the platform and they represent the artefacts (such as Orders and Trades) that are produced as a result of trading activity. As a result of being part of the data model, there is a Table enumeration in the system that is used to refer to a table from within the system itself.
In the Permission model each record must refer to the Table to which the Permission relates and this reference is an instance of the Table enumeration.
In addition to applying to a generic Table it is possible to grant permissions to specific instances of a given Table, for example just the specific MAIN Market. This feature is covered in the [Permission Scope][instance-scope] section in this document.
Permission Action
A Permission describes a particular Action that a User can perform on objects in the system.
Valid Actions are instances of the PermissionAction enumeration as defined in the data model
| Action | Description |
|---|---|
| View | The basic Action that a User must have in order to view any records in a given table. In order to do any other Action on a table record, the User must also have at least the View Action granted on the same record. |
| ViewLevel2 | View level 2 (OrderBook) data for an InstrumentMarket. |
| ViewLevel3 | View level 3 (information on individual orders) data for an InstrumentMarket. |
| Create | Create a new record in the given table. |
| Delete | Delete a record from the given table. |
| Cancel | Cancel an Order, Trade or a HoldingTransaction. |
| Enter | Enter orders (required on Account, User and InstrumentMarket for the applicable record in each). |
| EnterOnBehalfOf | Enter orders on behalf of other users. |
| Amend | Modify a record in the given table. |
| Hold | Hold an order. |
| Suspend | Suspend records in the given table. |
| Rfq | Enter an RFQ for an InstrumentMarket. |
| ReportTrade | Enter a reported (off-market) Trade for an InstrumentMarket. |
| Transition | Transition a Trade through settlement states. |
| AmendSettleStatus | Amend the settlement status of a Trade. |
| Deposit | Deposit securities into a Holding balance via a HoldingTransaction. |
| Withdraw | Withdraw securities from a Holding balance via a HoldingTransaction. |
| SetBalance | Set the balance of a Holding via a HoldingTransaction. |
| Administer | View the given table in an administrative context within the MarketGrid UI. |
Table – Permission Actions
Not every Action makes sense for every table. For example, the EnterOnBehalfOf Action relates specifically to entering Orders on behalf of another User and is only applicable to the User table.
Permission Scope
The Scope of a permission describes the level at which a Permission is applied. Scope is applied in two different ways, depending on the category of object to which the Permission applies.
When the target of the Permission is part of, or connected to, the Actor hierarchy then the full range of Scope values as described in the following table are applicable.
| Scope | Applies to records where |
|---|---|
| Instance | User has Instance access to the particular Record identified by the Permission.Table and Permission.Instance values |
| User | Any of the following true: - Record.OwnerUser == Record.OwnerGroup == Record.OwnerFirm == NULL- UserId == Record.OwnerUser- User is a member of Group Record.OwnerGroup |
| Firm | Any of the following true: - Record.OwnerUser == Record.OwnerGroup == Record.OwnerFirm == NULL- FIRM_OF(User) == FIRM_OF(Record.OwnerUser)- FIRM_OF(User) == FIRM_OF(Record.OwnerGroup)- FIRM_OF(User) == Record.OwnerFirm |
| Enterprise | Any of the following true: - Record.OwnerUser == Record.OwnerGroup == Record.OwnerFirm == NULL- ENTERPRISE_OF(User) == ENTERPRISE_OF(Record.OwnerUser)- ENTERPRISE_OF(User) == ENTERPRISE_OF(Record.OwnerGroup)- ENTERPRISE_OF(User) == ENTERPRISE_OF(Record.OwnerFirm) |
| Venue | Any of the following true: - Record.OwnerUser == Record.OwnerGroup == Record.OwnerFirm == NULL- VENUE_OF(User) == VENUE_OF(Record.OwnerUser)- VENUE_OF(User) == VENUE_OF(Record.OwnerGroup)- VENUE_OF(User) == VENUE_OF(Record.OwnerFirm) |
| All | Always |
Table – Permission Scopes
The Tables for which the full the full range of Scope values are applicable are those defined within
- Actor hierarchy - eg.
User,Group,Firm,Enterprise - Position Keeping section - eg.
Holding,Position,Account - Trading section - eg.
OrderandTrade - Messaging section
By contrast, the Tables in
- Product hierarchy - eg.
Market,Instrument,InstrumentMarket
can only be associated with either the:
- the All scope - applicable universally to all records in the given
Table - the Instance scope - applicable to a single instance of the
Tabledefined in thePermissionrecord
Instance Scope
To enable the Instance Scope, MarketGrid uses a record-level caching mechanism to allow very fast-lookup for permissions. Not all Tables are cached at the record level. Instance Scope may only be used on such cached Tables. Currently, these are:
IndustrySectorVenueInstrumentGroupEnterpriseFirmMarketGroupBlotterInstrumentMarketBlobObject
The caching of these tables is defined in the data model, but can also be overridden at runtime using the cache_permissions engine option. For example:
mg start scenario_name --matching_engine.cache_permissions BlobObject=false
Note:
Caching requires a significant amount of memory since it "explodes" into a matrix with a cell for every
Userand record in the cached table.
Examples
Permission Example for the Account Table
Consider a worked example for granting permissions to a User to the Account table.
- First, the
Useris assigned permissionActionView withScopelevel Firm on the Account table.- The
Userwill be able to view allAccountswhere:- The
OwnerUserof theAccountis theUser - The
OwnerGroupof theAccountis one of theGroupsto which theUserbelongs - The
OwnerFirmof theAccountis theUser'sFirm - None of
OwnerUser,OwnerGrouporOwnerFirmis set (public record)
- The
- The
Userwill not be able to perform any otherActionson theAccounts, including amending, deleting or entering orders for any of theAccounts.
- The
- Next, the
Useris assigned permissionActionsAmend and Delete withScopelevel User on theAccounttable.- The
Userwill be able to amend or delete anyAccountfor which: - The
OwnerUserof theAccountis theUser - The
OwnerGroupof theAccountis one of the groups to which theUserbelongs - None of
OwnerUser,OwnerGrouporOwnerFirmis set (public record) - The
Userwill not be able to perform any otherActionson theAccounts, including entering orders.
- The
- Next, the
Useris assigned permissionActionEnter withScopelevel Firm on theAccounttable.- The
Userwill be able to enter orders for anyAccountfor which:- The
OwnerUserof theAccountis theUser - The
OwnerGroupof theAccountis one of the groups to which theUserbelongs - The
OwnerFirmof theAccountis the ``User'sFirm` - None of
OwnerUser,OwnerGrouporOwnerFirmis set (public record)
- The
- The
Constraints by Actor Hierarchy
A User's permissions are constrained by those of its Firm and Enterprise. In order to have a particular permission, the Firm AND the Enterprise of the User must have that permission, granted at the necessary Scope for the same Action and over an equivalend range (Table and optionally Instance)
For example, suppose we have a Firm, FirmX (that belongs to Enterprise EnterpriseX ) with two Users, UserA and UserB. We also have Accounts in the Firm as follows.
| Account | OwnerUser | OwnerFirm |
|---|---|---|
| Account1 | UserA | FirmX |
| Account2 | UserA | FirmX |
| Account3 | UserB | FirmX |
| Account4 | UserB | FirmX |
| Account5 | FirmX |
Table – Permission Example (a)
Suppose we had Permission records as follows.
| Id | Enterprise | Firm | User | Group | Table | Scope | Instance | Action |
|---|---|---|---|---|---|---|---|---|
| 1 | UserA | Account | User | View | ||||
| 2 | UserB | Account | User | View |
Table - Permission Example (b)
With the records above, while permission has been granted to each of UserA and UserB to see their own Accounts, they would actually not be able to see any Accounts as no permission has been granted to their Firm nor their Enterprise to view Account.
Now, suppose we have Permission records as follows (bold cells are new or changed).
| Id | Enterprise | Firm | User | Group | Table | Scope | Instance | Action |
|---|---|---|---|---|---|---|---|---|
| 1 | UserA | Account | User | View | ||||
| 2 | UserB | Account | User | View | ||||
| 3 | EnterpriseX | Account | User | View | ||||
| 4 | FirmX | Account | User | View |
Table – Permission Example (c)
* The order of the Permission records is not important.
The above set of Permission records would let UserA see Account1 and Account2 and UserB see Account3 and Account4 , as each has User Scope permission on the Account table for the View Action.
If we wanted to allow UserA to be able to see all Accounts in the Firm, suppose we modified the Permission records as follows.
| Id | Enterprise | Firm | User | Group | Table | Scope | Instance | Action |
|---|---|---|---|---|---|---|---|---|
| 1 | UserA | Account | Firm | View | ||||
| 2 | UserB | Account | User | View | ||||
| 3 | EnterpriseX | Account | User | View | ||||
| 4 | FirmX | Account | User | View |
Table – Permission Example (d)
Although UserA now has the View Action with Firm Scope, they would still only be limited to seeing Accounts with User Scope as their Firm and Enterprise are limited to User Scope. In order to allow UserA to have Firm Scope, we would need the following.
| Id | Enterprise | Firm | User | Group | Table | Scope | Instance | Action |
|---|---|---|---|---|---|---|---|---|
| 1 | UserA | Account | Firm | View | ||||
| 2 | UserB | Account | User | View | ||||
| 3 | EnterpriseX | Account | Firm | View | ||||
| 4 | FirmX | Account | Firm | View |
Table – Permission Example (e)
With these changes, UserA would be able to see all five Accounts for the Firm, including Account5 which is not assigned to any particular User.
Continuing the example above, while UserA and UserB can each see the Accounts for which they have been granted permission, they could not, for example, enter Orders for those Accounts. To enter Orders for an Account, a User needs to have permission with the Enter Action for that Account.
Suppose we now have the following Permission records.
| Id | Enterprise | Firm | User | Group | Table | Scope | Instance | Action |
|---|---|---|---|---|---|---|---|---|
| 1 | UserA | Account | Firm | View | ||||
| 2 | UserB | Account | User | View | ||||
| 3 | EnterpriseX | Account | Firm | View | ||||
| 4 | FirmX | Account | Firm | View | ||||
| 5 | UserA | Account | User | Enter | ||||
| 6 | UserB | Account | User | Enter | ||||
| 7 | EnterpriseX | Account | Firm | Enter | ||||
| 8 | FirmX | Account | Firm | Enter |
Table – Permission Example (f)
This would allow UserA to see all Accounts for the Firm (for example to view their Holding balances) but would only allow UserA to enter Orders for its own Accounts – Account1 and Account2.
Finally, we could modify the Permission records to allow UserA to enter Orders for any Account in the Firm.
| Id | Enterprise | Firm | User | Group | Table | Scope | Instance | Action |
|---|---|---|---|---|---|---|---|---|
| 1 | UserA | Account | Firm | View | ||||
| 2 | UserB | Account | User | View | ||||
| 3 | EnterpriseX | Account | Firm | View | ||||
| 4 | FirmX | Account | Firm | View | ||||
| 5 | UserA | Account | Firm | Enter | ||||
| 6 | UserB | Account | User | Enter | ||||
| 7 | EnterpriseX | Account | Firm | Enter | ||||
| 8 | FirmX | Account | Firm | Enter |
Table – Permission Example(g)
In order to have permission for any Action, a User must have at least the equivalent View Action permission – i.e., at a minimum, the User must be able to see a record in order to do anything associated with that record. Therefore, for example, if we gave UserB Firm Scope for the Enter Action on the Account table,UserB would still not be able to enter orders for Accounts other than its own (Account3 and Account4) since it only has permission for the View Action with User Scope.
Group Functionality
Extension of Visibility
The records of a given table to which a User has access may be extended by its membership in Groups. For any record of a table that has OwnerGroup set, the record will be visible to any User that is a member of that Group. For determining the visibility of records, any record that is owned by a Group is considered to be owned by all the members of that Group.
If we extend our previous example as follows.
| Account | OwnerUser | OwnerFirm | OwnerGroup |
|---|---|---|---|
| Account1 | UserA | FirmX | GroupJ |
| Account2 | UserA | FirmX | GroupJ |
| Account3 | UserB | FirmX | |
| Account4 | UserB | FirmX | GroupJ |
| Account5 | FirmX |
Table – Extension of Visibility with Groups
With this change, Account1 , Account2 and Account4 are all visible to both UserA and UserB since they are considered to be owned by both Users by virtue of them both being in GroupJ and GroupJ being the OwnerGroup of those Accounts. In fact, those Accounts would also be visible to UserD since that User is also a member of GroupJ.
[NOTE: The above assumes that the User has at least User Scope permission with View Action on the Account table.]
Extension of Permissions
Permission records may be assigned to a Group in the Permission table in the same way that they may be assigned to an Enterprise, Firm or User. A User will automatically inherit all the permissions assigned to any Groups to which it belongs – that is, the Groups' permissions extend the User's permissions.
Suppose that we start with a Permission table from the previous example as follows.
| Id | Enterprise | Firm | User | Group | Table | Scope | Instance | Action |
|---|---|---|---|---|---|---|---|---|
| 1 | UserA | Account | Firm | View | ||||
| 2 | UserB | Account | User | View | ||||
| 3 | EnterpriseX | Account | Firm | View | ||||
| 4 | FirmX | Account | Firm | View | ||||
| 5 | UserA | Account | User | Enter | ||||
| 6 | UserB | Account | User | Enter | ||||
| 7 | EnterpriseX | Account | Firm | Enter | ||||
| 8 | FirmX | Account | Firm | Enter |
Table – Extension of Permissions with Groups (a)
We now add records for GroupJ as follows.
| Id | Enterprise | Firm | User | Group | Table | Scope | Instance | Action |
|---|---|---|---|---|---|---|---|---|
| 1 | UserA | Account | Firm | View | ||||
| 2 | UserB | Account | User | View | ||||
| 3 | EnterpriseX | Account | Firm | View | ||||
| 4 | FirmX | Account | Firm | View | ||||
| 5 | UserA | Account | User | Enter | ||||
| 6 | UserB | Account | User | Enter | ||||
| 7 | EnterpriseX | Account | Firm | Enter | ||||
| 8 | FirmX | Account | Firm | Enter | ||||
| 9 | GroupJ | Account | Firm | View | ||||
| 10 | GroupJ | Account | Firm | Enter |
Table – Extension of Permissions with Groups (b)
With the changes above, UserB may now view all Accounts in the Firm and also enter Orders for all Accounts in the Firm. This is because UserB is a member of GroupJ so inherits GroupJ's permissions that are additive with its own.
Permission Checking
The permission model uses the data described in this document to check access to functionality and visibility of data in real time.
Data Visibility
Data visibility is checked withing the various processes that serve data in MarketGrid using the data in their local copy of the shared memory database using the same functions that the Trading Engine uses to check access. This is to avoid the need for client applications to re-implement the permission checking in their own code space and hence run the risk of getting different permission results depending on the implementation. There are three main processes that fall into this category:
- NServer - the backend process that serves the UI and implements the
nqfunctionality - MDB - the Market Database uses the same permission model to control access to the data it stores.
- NFE FIXServer - for the purposes of sending data (eg "Execution Reports" and "Market Data") the NFE validates the visiblity of data using the same model as described here
The philosophy in this model is that permission checking is done at the data source so that a client connection never receives data for which there is no visibility.
Functional Permission
For checking access to functionality, all permissions are checked at the Trading Engine for each inbound message in-line within the Trading Engine process at the moment of execution. As such there is no opportunity for insertion of transactions between permission checking and execution. Likewise changes to permissions, also executed as a normal transaction, take immediate effect and there is no delay between the granting and revoking of a permission and that change taking effect.
Since permission checking is performed in-line for each inbound message the performance of the permission model is critical to the performance of the platform.