Dynamic-Entity-Access-Model
|A Dynamic Entity definition carries six access flags. Together they decide who may create, read, edit and delete rows, and through which route. This page is the reference; the flags are set in the definition JSON next to the entity name (see here).
|
|The five routes on one entity
|
|| Route | Exists when | Who may read | Who may write | Which rows |
||---|---|---|---|---|
|| System: /obp/dynamic-entity/ENTITY or /obp/dynamic-entity/banks/BANK_ID/ENTITY | always | holders of the entity Get role | holders of the Create, Update and Delete roles | the shared pool: rows created here; never personal rows |
|| Personal: /obp/dynamic-entity/my/ENTITY | hasPersonalEntity | any authenticated User; a role only if personalRequiresRole; a consent user in addition only if its Consent lists the entity in my_resources | same rule | the caller's own rows only, keyed by the on-behalf-of user |
|| Community: /obp/dynamic-entity/community/ENTITY | hasCommunityAccess | authenticated holders of the Get role | nobody (read only) | every row, personal rows included |
|| Public: /obp/dynamic-entity/public/ENTITY | hasPublicAccess | anyone, no login | nobody (read only) | the shared pool only |
|| Row level: the System routes with useRowLevelAccess | useRowLevelAccess | per row, whoever the access list marks readable; lists are filtered | per row, access list Update and Delete; the creator is granted read, update, delete and grant on their own row | whatever the access list says |
|
|The entity roles are named after the entity: CanCreateDynamicEntity_SystemENTITY, CanGetDynamicEntity_SystemENTITY, CanUpdateDynamicEntity_SystemENTITY, CanDeleteDynamicEntity_SystemENTITY (without System for bank level entities, held at the bank).
|
|Two settings apply on top of the routes:
|
|* authMode says which credential satisfies the role checks on the System route: UserOnly (Entitlements), ApplicationOnly (Consumer Scopes), UserOrApplication, UserAndApplication. The Personal and Row level routes always need a User; ApplicationOnly is refused on an entity with hasPersonalEntity.
|* Field roles: a field with a read_role is omitted from every response unless the caller holds that role; a field with a write_role is only changed by PATCH from a holder (POST ignores it, PUT preserves its value).
|
|Managing a record's access list (row level)
|
|| Call | Does |
||---|---|
|| GET /obp/dynamic-entity/ENTITY/RECORD_ID/access | lists who may read, update, delete and grant this record, and who granted them |
|| PUT /obp/dynamic-entity/ENTITY/RECORD_ID/access | grants or replaces one entry, or an array of them: user_id is required, can_read, can_update and can_delete default to false, can_grant defaults to true |
|| DELETE /obp/dynamic-entity/ENTITY/RECORD_ID/access/USER_ID | revokes that User, cascading to every grant they passed on |
|
|Bank level entities take the same paths under /banks/BANK_ID/. The caller needs can_grant on the record — the User who created it has it — or CanGrantDynamicEntityRowAccess_SystemENTITY (CanGrantDynamicEntityRowAccess_ENTITY at a bank), which administers any record. The calls return 400 on an entity that is not row level. Creating a record still takes the entity's Create role, and useRowLevelAccess is only supported for locally-backed entities.
|
|Authorship and editing by actor
|
|| Actor | Shared pool | Own rows via my | Other Users' personal rows |
||---|---|---|---|
|| Anonymous | read, if hasPublicAccess | none | none |
|| Authenticated User, no role | none | create, edit, delete (unless personalRequiresRole) | none |
|| Get role holder | read | as above | read them all via community, if hasCommunityAccess |
|| Create, Update, Delete role holders | write | as above | none: personal rows are invisible to the System route |
|| Row access list grantee | per row | as above | per row, if granted |
|| Consent user (a User minted by a Consent) | as the roles its Consent carries | only if the Consent lists the entity in my_resources.personal_dynamic_entities with the needed action (plus the role when personalRequiresRole); rows it writes belong to the User who granted the Consent | none |
|
|Patterns
|
|| Pattern | Flags | Behaviour |
||---|---|---|
|| Curated reference data | personal off, public on | role holders maintain it, everyone reads it |
|| Restricted registry | personal off, public off, community off | role holders only |
|| Team space | personal on, personalRequiresRole on, community on | members write their own rows, the whole team reads everything; the entity roles define the team |
|| User owned records | personal on, personalRequiresRole off, community off, public off | each User has their own rows; an agent reaches them only through a Consent whose my_resources lists the entity |
|| Shared records with per row sharing | useRowLevelAccess on | the creator owns the row and grants others read, update, delete or grant |
|
|One combination deserves care: personal on, personalRequiresRole off, community on. It shows every User's personal rows to any holder of the Get role, which is rarely intended.
|
|personalRequiresRole gates the my route with the entity's own roles, the same roles that open the shared pool. It therefore suits the team space pattern, where the users of my are the role holders anyway. It is not a way to restrict ordinary Users' personal use: giving a User the Get role so they may use my also lets them read the shared pool.
|
|See also here, here and here.
|