Time-Based Checks
You can grant people access to resources for a specific length of time by adding an expiration time to their role or permission assignment. You can also think of this as the ability to grant permissions temporarily.
Implement the logic
We add a rule to say that a user has a role if they have a role assignment that has not expired.
The has_role_with_expiry
fact is like the usual has_role
fact, but the fourth argument is the
expiration time, expressed as an integer representing seconds since the Unix epoch.
On a *nix system, date +%s
will give you the current Unix time in seconds.
@current_unix_time
is a constant you can use in rules that will resolve to
the current Unix time at the time your query is evaluated.
To implement access expiration, we compare the expiration time with the current time.
actor User { }resource Repository { roles = ["member"]; permissions = ["read"]; "read" if "member";}has_role(actor: Actor, role: String, repo: Repository) if expiration matches Integer and has_role_with_expiry(actor, role, repo, expiration) and expiration > @current_unix_time;
Test it out
To test this, we grant Alice the "member" role until 2033, while Bob's role expired in 2022.
Given those time-bound roles, Alice has access but Bob does not.
test "access to repositories is conditional on expiry" { setup { # Alice's access expires in 2033 has_role_with_expiry(User{"alice"}, "member", Repository{"anvil"}, 2002913298); # Bob's access expired in 2022 has_role_with_expiry(User{"bob"}, "member", Repository{"anvil"}, 1655758135); } assert allow(User{"alice"}, "read", Repository{"anvil"}); assert_not allow(User{"bob"}, "read", Repository{"anvil"});}