# Roles & Grants

Libec uses roles to implement a hierachal set of granular permissions attached to a certificate. This is intended to allow issuing certificates with various embedded permissions, which can be verified up to a trust root without needing to query any third party.

Roles are defined as a set of period-delimited strings, where each string is considered to be a child of the string to its left. The rightmost string may optionally be '\*' - this is a wildcard match.

As an example, the role of `com.example.myPond.goFishing` might allow the user to go fishing in the pond, but not feed the fish, or stir the water. In contrast, the role `com.example.myPond.*` would allow the user to do anything to the pond, or anything subordinate to it (i.e. the user is also considered to have `com.example.myPond.lilyPad.locateFrog`).

In order for a role to be considered valid, the certificate's signer must have either the same role, or a parent / wildcard role which matches it, defined as a grant. In order for a grant to be considered valid, the certificate's signer must have the same grant, or a parent / wildcard grant which matches it, defined as a grant.

This means that a certificate may also delegate granting authority for any role it is capable of granting.

A certificate with the flag `EC_CERT_TRUSTED` may define any role or grant, with no higher authority required to validate it. Such roles and grants must be explicitly defined in the certificate; by default a certificate defines nothing at all.

## API

* [ec\_role\_add()](/roles_and_grants.md#ec-role-add)
* [ec\_role\_grant()](/roles_and_grants.md#ec-role-grant)
* [ec\_role\_has()](/roles_and_grants.md#ec-role-has)
* [ec\_role\_has\_grant()](/roles_and_grants.md#ec-role-has-grant)

### ec\_role\_add()

`ec_record_t *ec_role_add(ec_cert_t *c, char *role);`

Add a role to a certificate. Returns the new role record on success, NULL otherwise. The created record will be automatically freed when the certificate is destroyed.

```c
#include <ec.h>
...
ec_record_t *r = ec_role_add(c, "com.example.myPond.goFishing");
if(r == NULL) {
    //failed to add role
}
...
```

### ec\_role\_grant()

`ec_record_t *ec_role_grant(ec_cert_t *c, char *role);`

Allow a certificate to grant a role. Returns the new grant record on success, NULL otherwise. The created record will be automatically freed when the certificate is destroyed.

```c
#include <ec.h>
...
ec_record_t *g = ec_role_grant(c, "com.example.myPond.*");
if(g == NULL) {
    //failed to add grant for role
}
...
```

### ec\_role\_has()

`ec_err_t ec_role_has(ec_cert_t *c, char *role);`

Check whether a certificate holds the given role. Returns EC\_OK on success, or a nonzero error code otherwise.

If the certificate holds a matching wildcard role, this is considered sufficient (e.g. if a certificate holds `com.example.*`, it is also considered to hold `com.example.myPond.goFishing`).

```c
#include <ec.h>
...
if(ec_role_has(c, "com.example.myPond") == EC_OK) {
    //certificate holds the com.example.myPond permission
}
...
```

### ec\_role\_has\_grant()

`ec_err_t ec_role_has_grant(ec_cert_t *c, char *role);`

Check whether a certificate is allowed to grant the given role. This does ***not*** imply that the certificate also holds this role; grants and roles may be held independantly.

If the certificate holds a matching wildcard grant, this is considered sufficient (e.g. if a certificate defines a grant for `com.example.*`, it may also grant `com.example.myPond.goFishing`).

```c
#include <ec.h>
...
if(ec_role_has_grant(c, "com.example.myPond.goFishing") == EC_OK) {
    //certificate may grant com.example.myPond.goFishing
}
...
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://libec.erayd.net/roles_and_grants.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
