# `role` — a package's name for the app's own roles

> A package cannot know an app's `[Role]` enum, and an app has exactly one. `role` is how a package names it anyway: a column or setting typed `role` holds a member of the app's enum, and `role.Authenticator` in a package's policy is that enum's `Authenticator` member — bound when the package is compiled into the app. In app source, write the enum's own name.

<!-- id: security-role-type · area: security · stability: preview · html: https://osysharp.com/reference/security/role-type/ -->

## Summary        {#summary}
A kit that grants roles — [The Identity kit — who signs in, and which of the app's roles they hold](https://osysharp.com/reference/security/identity-kit/)'s `RoleGrant`, [The UserAccounts kit — sign-in done properly, once](https://osysharp.com/reference/security/accounts-kit/)'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:

```osy syntax
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      {#signature}
```osy syntax
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    {#description}

### What it binds to                           {#binding}
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)](https://osysharp.com/reference/security/role-grants/)). `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                            {#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                        {#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 using `role` needs one; the refusal names the package.
- **A member the app's enum lacks.** `role.Authenticator` over an enum with no `Authenticator` is refused, listing
  the members the enum has — which is why every people-aware kit asks the app for an `Authenticator` member.

## Examples       {#examples}

### An app's roles, held in the kit's grant table   {#example-grant}
```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](https://osysharp.com/reference/security/identity-kit/) — `RoleGrant`, the kit table whose column is `role`
- [The UserAccounts kit — sign-in done properly, once](https://osysharp.com/reference/security/accounts-kit/) — `SignupRole` and `FirstAccountRole`, settings typed `role`
- [role grants (and the first admin)](https://osysharp.com/reference/security/role-grants/) — how a grant row becomes a role the rules answer
