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 Permission will have effect
    • Table - where the the Permission applies
    • Action - what can the Actor do with this permission
    • Scope - when does the Permission apply

Each permission consists of:

  • An Actor (one of Enterprise, Firm, User, Group) to whom the permission is granted;
  • A combination of a Table, Action, Scope level, and (optionally) Instance of 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

FieldDescriptionValid Values
IdSystem assigned primary key.Integer > 0
Enterprise*The Actor to whom the permission is grantedEnterprise.Id or 0
Firm*Firm.Id or 0
User*User.Id or 0
Group*Group.Id or 0
TableThe table against which the permission is appliedA valid table number or 0. 0 means that this permission grant applies to all tables.
ActionThe action that the Actor can performOne of the values of the PermissionAction type.
ScopeThe scope level of the permission being grantedOne of the values of the PermissionScope type:
- Instance
- User
- Firm
- Enterprise
- Venue
- All
InstanceIf 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.
StatusUsed to activate or deactivate (suspend) and delete the Permission record.STATUS_ACTIVE or zero.

Table - Permission Table

*At most one of; Enterprise, Firm, User, Group may 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:

  • Enterprise
  • Firm
  • Group; or
  • User and a Permission record must be defined as having either;
  • no values for any of the Actor columns. That is, a global permission that applies to every User in 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.

FieldDescription
OwnerUserIs 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.
OwnerFirmIs 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, OwnerFirm and OwnerGroup all set to NULL (not set) is considered a public record to which any User may 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

ActionDescription
ViewThe 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.
ViewLevel2View level 2 (OrderBook) data for an InstrumentMarket.
ViewLevel3View level 3 (information on individual orders) data for an InstrumentMarket.
CreateCreate a new record in the given table.
DeleteDelete a record from the given table.
CancelCancel an Order, Trade or a HoldingTransaction.
EnterEnter orders (required on Account, User and InstrumentMarket for the applicable record in each).
EnterOnBehalfOfEnter orders on behalf of other users.
AmendModify a record in the given table.
HoldHold an order.
SuspendSuspend records in the given table.
RfqEnter an RFQ for an InstrumentMarket.
ReportTradeEnter a reported (off-market) Trade for an InstrumentMarket.
TransitionTransition a Trade through settlement states.
AmendSettleStatusAmend the settlement status of a Trade.
DepositDeposit securities into a Holding balance via a HoldingTransaction.
WithdrawWithdraw securities from a Holding balance via a HoldingTransaction.
SetBalanceSet the balance of a Holding via a HoldingTransaction.
AdministerView 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.

ScopeApplies to records where
InstanceUser has Instance access to the particular Record identified by the Permission.Table and Permission.Instance values
UserAny of the following true:
- Record.OwnerUser == Record.OwnerGroup == Record.OwnerFirm == NULL
- UserId == Record.OwnerUser
- User is a member of Group Record.OwnerGroup
FirmAny 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
EnterpriseAny 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)
VenueAny 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)
AllAlways

Table – Permission Scopes

The Tables for which the full the full range of Scope values are applicable are those defined within

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 Table defined in the Permission record

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:

  • Industry
  • Sector
  • Venue
  • InstrumentGroup
  • Enterprise
  • Firm
  • Market
  • Group
  • Blotter
  • InstrumentMarket
  • BlobObject

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 User and 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.

  1. First, the User is assigned permission Action View with Scope level Firm on the Account table.
    1. The User will be able to view all Accounts where:
      1. The OwnerUser of the Account is the User
      2. The OwnerGroup of the Account is one of the Groups to which the User belongs
      3. The OwnerFirm of the Account is the User's Firm
      4. None of OwnerUser, OwnerGroup or OwnerFirm is set (public record)
    2. The User will not be able to perform any other Actions on the Accounts, including amending, deleting or entering orders for any of the Accounts.
  2. Next, the User is assigned permission Actions Amend and Delete with Scope level User on the Account table.
    1. The User will be able to amend or delete any Account for which:
    2. The OwnerUser of the Account is the User
    3. The OwnerGroup of the Account is one of the groups to which the User belongs
    4. None of OwnerUser, OwnerGroup or OwnerFirm is set (public record)
    5. The User will not be able to perform any other Actions on the Accounts, including entering orders.
  3. Next, the User is assigned permission Action Enter with Scope level Firm on the Account table.
    1. The User will be able to enter orders for any Account for which:
      1. The OwnerUser of the Account is the User
      2. The OwnerGroup of the Account is one of the groups to which the User belongs
      3. The OwnerFirm of the Account is the ``User's Firm`
      4. None of OwnerUser, OwnerGroup or OwnerFirm is set (public record)

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.

AccountOwnerUserOwnerFirm
Account1UserAFirmX
Account2UserAFirmX
Account3UserBFirmX
Account4UserBFirmX
Account5FirmX

Table – Permission Example (a)

Suppose we had Permission records as follows.

IdEnterpriseFirmUserGroupTableScopeInstanceAction
1UserAAccountUserView
2UserBAccountUserView

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).

IdEnterpriseFirmUserGroupTableScopeInstanceAction
1UserAAccountUserView
2UserBAccountUserView
3EnterpriseXAccountUserView
4FirmXAccountUserView

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.

IdEnterpriseFirmUserGroupTableScopeInstanceAction
1UserAAccountFirmView
2UserBAccountUserView
3EnterpriseXAccountUserView
4FirmXAccountUserView

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.

IdEnterpriseFirmUserGroupTableScopeInstanceAction
1UserAAccountFirmView
2UserBAccountUserView
3EnterpriseXAccountFirmView
4FirmXAccountFirmView

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.

IdEnterpriseFirmUserGroupTableScopeInstanceAction
1UserAAccountFirmView
2UserBAccountUserView
3EnterpriseXAccountFirmView
4FirmXAccountFirmView
5UserAAccountUserEnter
6UserBAccountUserEnter
7EnterpriseXAccountFirmEnter
8FirmXAccountFirmEnter

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 AccountsAccount1 and Account2.

Finally, we could modify the Permission records to allow UserA to enter Orders for any Account in the Firm.

IdEnterpriseFirmUserGroupTableScopeInstanceAction
1UserAAccountFirmView
2UserBAccountUserView
3EnterpriseXAccountFirmView
4FirmXAccountFirmView
5UserAAccountFirmEnter
6UserBAccountUserEnter
7EnterpriseXAccountFirmEnter
8FirmXAccountFirmEnter

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.

AccountOwnerUserOwnerFirmOwnerGroup
Account1UserAFirmXGroupJ
Account2UserAFirmXGroupJ
Account3UserBFirmX
Account4UserBFirmXGroupJ
Account5FirmX

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.

IdEnterpriseFirmUserGroupTableScopeInstanceAction
1UserAAccountFirmView
2UserBAccountUserView
3EnterpriseXAccountFirmView
4FirmXAccountFirmView
5UserAAccountUserEnter
6UserBAccountUserEnter
7EnterpriseXAccountFirmEnter
8FirmXAccountFirmEnter

Table – Extension of Permissions with Groups (a)

We now add records for GroupJ as follows.

IdEnterpriseFirmUserGroupTableScopeInstanceAction
1UserAAccountFirmView
2UserBAccountUserView
3EnterpriseXAccountFirmView
4FirmXAccountFirmView
5UserAAccountUserEnter
6UserBAccountUserEnter
7EnterpriseXAccountFirmEnter
8FirmXAccountFirmEnter
9GroupJAccountFirmView
10GroupJAccountFirmEnter

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 nq functionality
  • 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.