Time-Aware Grants
Authorization in the SDK depends on three things: the app, the actor and the moment. Every grant carries the window in which it holds.
What carries a window
| Grant | Table |
|---|---|
| a role for a partner | sdk_role_assignments |
| an ability given directly | sdk_ability_assignments |
| a group membership | sdk_group_assignments |
The links between roles, groups and abilities (sdk_ability_role, sdk_group_role, sdk_ability_group) carry no window. They are the catalog, not grants.
Each grant row has valid_from and valid_until. The defaults are now and 9999-12-31 23:59:59. Both bounds are inclusive: a grant holds at the moment t when valid_from <= t <= valid_until.
One moment per request
When the SDK builds the context for a request, it fixes the moment once, as SdkContext::at(), and resolves the actor's abilities for that moment, as SdkContext::abilities(). Every check in the request uses the same moment. Grants are not cached, so a change is visible with the next request.
Granting and ending
In the Partners app, Assign role, Grant ability and Add to group each start now and run open-ended. The app refuses a second identical grant while the first is active (422).
Revoke and Remove don't delete anything. They set valid_until to now, so the history stays, and the same grant can be given again later as a new row. Because the upper bound is inclusive, a grant ended at 10:15:00 still holds at exactly 10:15:00, and not after.
The Partners app always grants from now on. A grant with a future start or a fixed end is a row with those dates.
Looking at another moment
ui5:explain --atshows what someone held at any moment, with the source and window of each grant.- In tests, the scenario builder's
at()sets the moment (Testing Authorization). - Resolution Engine shows the query that applies the windows.