Ownership Based Authorization
- Vinaya Mayya
The Ed-Fi ODS / API primarily uses a relationship-based authorization strategy based on education organizations. Ownership based authorization adds an optional additional level of authorization that can be used in scenarios where more granular access controls are needed. Refer to API Claim Sets & Resources for details on various available authorization strategies. This documentation covers the essentials for platform hosts to enable and manage the feature.
Ownership based authorization is an optional feature that is turned off by default - but can be turned on through configuration. When this feature is turned on, each aggregate root entity in the ODS is assigned with an ownership token indicating the access rights to that resource. EdFi_Admin database holds ownership tokens for the API clients. API populates the new ownership token property on the aggregate root entity from the API client's key context.
Authorization metadata in EdFi_Security database allows platform hosts to configure multiple authorization strategies for a given resource/action combination to use ownership based authorization strategy in conjunction with existing relationship based authorization strategies. API Authorization layer identifies multiple matching authorization strategies for a request, and applies multiple sets of filter criteria to apply authorization.
The following steps demonstrate setting up ownership based authorization:
Enabling Ownership Based Authorization
The Ownership based authorization feature is managed on the deployed code by changing the appsettings.json file of the EdFi.Ods.WebApi project. This is the appsettings.json of the "Api" component of the deployed solution. The app setting ApiSettings:Features:OwnershipBasedAuthorization
should be set to the value "true". If the app setting doesn't exist, it should be created.
The following snippet shows the app setting:
"ApiSettings": { ... "Features": [ { "Name": "OwnershipBasedAuthorization", "IsEnabled": true }, ... }
To enable ownership based authorization, the database must be also be updated using the provided scripts. These scripts will set up a new column in all aggregate root entities and necessary to support this feature. All scripts supporting ownership based authorization will exist under a subfolder named "RecordOwnership" inside the "Ods" target database folder (i.e., \Ed-Fi-ODS\Application\EdFi.Ods.Standard\{StandardVersion}\Artifacts\MsSql\Structure\Ods\RecordOwnership). Scripts will be generated for this feature by MetaEd for Ed-Fi Extension projects as well.
Note that in development environments, initdev process automatically deploys these scripts based on the "ApiSettings:Features:OwnershipBasedAuthorization" flag in the appsettings.json file of the EdFi.Ods.WebApi project. This means that a development instance will typically not require any additional database scripts to be run.
In non-development environments, the schemas are already included with most provided backups, but can be applied if working with an older release or reapplying the feature by deploying the necessary change scripts to the target ODS database(s). The exact steps depend on your deployment method:
- If you are using the built-in deployment PowerShell scripts, update the configuration.json to set the "ApiSettings:Features:OwnershipBasedAuthorization" flag to "true". Same changes to configuration.json are needed while installing databases using the EdFi.Suite3.RestApi.Databases NuGet package. Performing a deployment on top of an existing ODS database after setting this flag will correctly execute the ownership based authorization scripts, which performs the necessary updates to enable ownership based authorization functionality.
- If the built-in deployment scripts are not being used, all scripts under the "RecordOwnership" inside the "Ods" target database folder (Ed-Fi-ODS\Application\EdFi.Ods.Standard\{StandardVersion}\Artifacts\MsSql\Structure\Ods\RecordOwnership) must be run against the ODS, including the extension version of the scripts (Ed-Fi-ODS-Implementation\Application\{YourExtensionProject}\Versions\{ExtensionVersion}\Standard\{StandardVersion}\Artifacts\MsSql\Structure\Ods\RecordOwnership).
Existing ODS updates may be required.
Ownership based authorization relies on appropriate ownership tokens marked on aggregate root entities . Once the feature is enabled, these tokens are set during record creation. However, when setting up ownership based authorization on an existing ODS, existing data must also be updated with ownership tokens in order for authorization to work properly.
Setting up Security Metadata
Ownership based authorization feature takes advantage of claims-based authorization to apply the ownership based authorization strategy against specific resources.
Steps to set up security metadata involve:
- Create a new Record Level Ownership claim set
- Insert resource claim actions
- Insert claim set resource claim actions
- Insert claim set resource claim action authorization strategy overrides
USE EdFi_Security GO DECLARE @ActionNames nvarchar(500) DECLARE @ApplicationName NVARCHAR(MAX) DECLARE @ApplicationId INT DECLARE @AuthorizationStrategyName NVARCHAR(255) DECLARE @AuthorizationStrategyId INT DECLARE @ClaimName NVARCHAR(850) DECLARE @ClaimSetName NVARCHAR(255) DECLARE @ClaimSetId INT DECLARE @ResourceClaimId INT -- Set the actions to authorize SET @ActionNames = 'read, update, delete' -- Set the application to create the claim set for SET @ApplicationName = 'Ed-Fi ODS API' -- Set the authorization strategy SET @AuthorizationStrategyName = 'OwnershipBased'; -- Set the resource claim name to authorize SET @ClaimName = 'http://ed-fi.org/ods/identity/claims/student' -- Set the claim set name to create SET @ClaimSetName = 'Record Level Ownership' SELECT @ApplicationId = ApplicationId FROM Applications WHERE ApplicationName = @ApplicationName SELECT @AuthorizationStrategyId = AuthorizationStrategyId FROM AuthorizationStrategies WHERE AuthorizationStrategyName = @AuthorizationStrategyName SELECT @ResourceClaimId = ResourceClaimId FROM ResourceClaims Where ClaimName = @ClaimName -- Create a new claim set INSERT INTO ClaimSets (ClaimSetName, Application_ApplicationId) SELECT @ClaimSetName, @ApplicationId SELECT @ClaimSetId = ClaimSetId FROM ClaimSets WHERE ClaimSetName = @ClaimSetName -- Insert resource claim actions INSERT INTO ResourceClaimActions(ResourceClaimId, ActionId) SELECT @ResourceClaimId, a.ActionID FROM Actions a WHERE a.ActionName IN( SELECT TRIM(value) FROM STRING_SPLIT(@actionNames, ',') ) AND NOT EXISTS( SELECT 1 FROM ResourceClaimActions rca WHERE rca.ResourceClaimID = @ResourceClaimId AND rca.ActionId = a.ActionId ) -- Insert claim set resource claim actions INSERT INTO ClaimSetResourceClaimActions(ClaimSetId, ResourceClaimId, ActionId) SELECT @ClaimSetId, rc.ResourceClaimId, a.actionId FROM ResourceClaimActions rca JOIN ResourceClaims rc on rc.ResourceClaimId = rca.ResourceClaimId JOIN Actions a on a.ActionId = rca.ActionId WHERE rca.ResourceClaimId = @ResourceClaimId -- Insert claim set resource claim action authorization strategy overrides INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides(ClaimSetResourceClaimActionId, AuthorizationStrategyId) SELECT csrca.ClaimSetResourceClaimActionId, @AuthorizationStrategyId FROM ClaimSetResourceClaimActions csrca WHERE csrca.ResourceClaimId = @ResourceClaimId
Configuring the API Client
Steps to configuring the API Client involve:
- Update Application Table to Use Record Level Ownership Claim Set
- (Claim set was created as part of Setting up Security Metadata)
- Create an Ownership Token for each API Client
- Assign the Creator Ownership Token to each API Client
- Assign the Ownership Token to each API Client
USE EdFi_Admin GO DECLARE @ClaimSetName NVARCHAR(255) DECLARE @ApplicationName NVARCHAR(MAX) SET @ClaimSetName = 'Ownership Based' SET @ApplicationName = 'Default Sandbox Application Sample' UPDATE Applications SET ClaimSetName = @ClaimSetName WHERE ApplicationName = @ApplicationName INSERT INTO OwnershipTokens(Description) SELECT client.[Name] + ' Ownership Token' FROM Applications a JOIN ApiClients client ON client.Application_ApplicationId = a.ApplicationId WHERE a.ApplicationName = @ApplicationName UPDATE ac SET ac.CreatorOwnershipTokenId_OwnershipTokenId = ot.OwnershipTokenId FROM OwnershipTokens ot JOIN ApiClients ac ON ot.Description LIKE ac.[Name] + '%' WHERE ac.CreatorOwnershipTokenId_OwnershipTokenId IS NULL INSERT INTO ApiClientOwnershipTokens(ApiClient_ApiClientId, OwnershipToken_OwnershipTokenId) SELECT ApiClientId, CreatorOwnershipTokenId_OwnershipTokenId FROM Applications a JOIN ApiClients client ON client.Application_ApplicationId = a.ApplicationId WHERE a.ApplicationName = @ApplicationName
Verifying a successful setup
In order to verify a successful setup, Swagger UI or Postman can be used to query the API to ensure that aggregate root entities configured to use ownership based authorization are returned correctly.
Technical Details
The tables involved in ownership based authorization are as follows:
EdFi_Security Database
The application of an "ownership-based" authorization strategy is done in an additive fashion. To facilitate this, EdFi_Security database schema has been updated to allow configuration of multiple authorization strategies for the default resource claim/action "tuples" as well as for claim set-specific overrides.
EdFi_Admin Database
In order to authorize individual resource items in the API based on the concept of "ownership", each API client is associated with "CreatorOwnershipTokenId" that is captured with each resource the client creates. The API client's claims information also includes a list of "ApiClientOwnershipTokens" that can be used to identify which resource items they currently "own", and the authorization process will filter results and access against this list against based on the target resource's "CretedByOwnershipTokenId" value.
Ed-Fi ODS Database
Each aggregate root entity table in the ODS has a CretedByOwnershipTokenId field used to assign an ownership token to each record.
Eg. Student Table
Developers' Guide Contents
Find out more about how to develop platforms based on the Ed-Fi ODS / API: