Record Level Ownership Design : Analysis

Overall the design proposed by AZ looks promising and fits well with the ODS / API architecture.  Rather than adding ApiClientId column to all root level aggregate entities, could we consider using the API client's "Namespace Prefix" in a column named "CreatedByNamespace", or similar.  This new column  could be another "boilerplate" column in each aggregate root table alongside the Id, CreateDate, and LastModifiedDate columns so that it is always present and always populated going forward. This will not only facilitate ownership based security, but also be generally useful to be able to know which system was the actual source of the data and a "CreatedBy" column is not uncommon in databases for tracking this sort of information.

 API logic needs to be modified to populate the new CreatedByNamespace property on the aggregate root entity from the API client's key context. This could probably be done in the Create method of the CreateEntity<T> class.

 A new "Ownership Based" authorization strategy could be created  that is almost identical to the current "Namespace Based" authorization strategy which uses the "Namespace" column and a "LIKE" filter. 

ODS / API  authorization layer design can be expanded to support multiple authorization strategies for a  give resource/action combination. This really is an authorization concern and while the flexibility of the general IoC-based architecture would allow the functionality to be configured in as additional C# classes driven by a feature configuration value, the most natural place for it to land is in the authorization code driven by authorization metadata.

In EdFi_Security database schema, The ClaimSetResourceClaims and ResourceClaimAuthorizationMetadatas tables each have a surrogate primary key and no other constraints.

 This means that while we filter these records by Resource/Action when authorizing API requests, there is no enforcement of uniqueness at that level. Therefore, we could add extra records to create an "OwnershipBased" authorization strategy, and add additional entries alongside the "RelationshipsWithEdOrgsAndPeople" strategy assigned to the "relationshipBasedData" resource claim, as shown here:

Hence while these records are filtered by Resource/Action when authorizing API requests, there is no enforcement of uniqueness at that level. Therefore there could be extra records to for an "OwnershipBased" authorization strategy alongside the "RelationshipsWithEdOrgsAndPeople" strategy assigned to the "relationshipBasedData" resource claim, as shown here:

These additional metadata to for extra authorization strategy  could be applied to to the main metadata (applicable by default to all API clients), by adding records to ResourceClaimAuthorizationMetadata table  to include multiple authorization strategies per Resource/Action

or overrides could be defined for a specific claim set by adding records to ClaimSetResourceClaims table  and utilizing AuthorizationStrategyOverride_AuthorizationStrategyId column to include multiple authorization strategies per Resource/Action (One thing to note is that if overrides are defined, overrides should be a wholesale replacement, so if multiple authorization strategies are needed, they should both be defined in the overrides.


Ideally,  security database should be modified to match our intent (move the AuthorizationStrategy / ValidationRuleSetName columns to a child table and put a constraint on Resource/Action on the aforementioned tables), but design could absolutely work without any schema changes. Noting that the schema changes will require changes to Sandbox and On-prem admin Apps and security configuration tools.  The security visualization tool would need to be updated in either case to reflect the presence of multiple authorization strategies on the graph nodes.


Finally, the authorization code would need to be updated to identify multiple matching authorization strategies for a request, and apply multiple sets of filter criteria to the queries.