Summary#
A kit that grants roles — The Identity kit — who signs in, and which of the app's roles they hold's RoleGrant, The UserAccounts kit — sign-in done properly, once's SignupRole — must
hold a member of an enum it has never seen: the app's [Role] enum. role is that enum, from inside a package:
namespace Acme.Door; // a package
[RoleGrant] public entity Grant { [Required] Principal Member; [Required] role Role; }
policy IsDoorman => Grant.Any(g => g.Member == user && g.Role == role.Authenticator);
[AppSetting("Door")] public class DoorSetup { public role? NewRole = null; }The app fills it with its own enum's members: app.Door = new DoorSetup { NewRole = AppRole.Member };.
Signature#
role Name; // a column: a member of the app's [Role] enum, stored as the enum is
role? Name; // optional
public role? Name = null; // a field of a package class ([AppSetting] included)
role.<Member> // a member, by name — in a package's policies, rules and AuthBootstrap
policy HoldsRoleIn(Organization o, role r) => …; // a parameter: the caller passes AppRole.X
public bool HoldsIn(Principal p, Organization o, role r) { … }Description#
What it binds to#
When the app compiles, each role column is linked to the app's [Role] enum, so a row the package writes is a grant
of the app's role and resolves like any other (role grants (and the first admin)). role.Authenticator in a package's policy is
checked against the app's enum when the app compiles — a policy naming role.X is lowered in the app's pass, where the
enum is known.
As a parameter#
A package's policy or function may take a role, and the app passes a member of its own enum —
allow create where HoldsRoleIn(Company, AppRole.Buyer);. The parameter is the app's enum by the time the app
compiles, so passing a member of any other enum is refused like any mismatched argument.
Where it is refused#
- In app source. The app knows its enum, so it writes it:
role Role;in an app is refused, naming the replacement from the app's own enum —AppRole Role;. - In an app with no
[Role]enum. A package usingroleneeds one; the refusal names the package. - A member the app's enum lacks.
role.Authenticatorover an enum with noAuthenticatoris refused, listing the members the enum has — which is why every people-aware kit asks the app for anAuthenticatormember.
Examples#
An app's roles, held in the kit's grant table#
```osy title="the kit's role column holds the app's AppRole" test app=security-role-type
app Desk {
use Osysharp.Identity;
model "model/**/*.osy";
}
using Osysharp.Identity;
[Role] enum AppRole { Authenticator, Agent, Lead } // the ONE role enum — the kit's role is this
policy IsLead => RoleGrant.Any(g => g.Member == user && g.Role == AppRole.Lead);
// Leads grant roles — the kit's grant table is Extensible, so the app decides who may. partial entity RoleGrant { security { allow create when IsLead; } }
void MakeLead(Principal who) { new RoleGrant { Member = who, Role = AppRole.Lead }; }
## See also {#see-also}
- [The Identity kit — who signs in, and which of the app's roles they hold](/reference/security/identity-kit/) — `RoleGrant`, the kit table whose column is `role`
- [The UserAccounts kit — sign-in done properly, once](/reference/security/accounts-kit/) — `SignupRole` and `FirstAccountRole`, settings typed `role`
- [role grants (and the first admin)](/reference/security/role-grants/) — how a grant row becomes a role the rules answer