Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions docs/content/docs/authz/permission.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -81,26 +81,35 @@ Permissions in Frontier follow a hierarchical structure, where higher-level perm

Frontier allow the its platform administrators (Superusers) to create permissions to meet specific authorization requirements beyond the predefined set of permissions. Custom permissions allow for more granular control over access to resources and actions within an application or system. They enable organizations to define and enforce fine-grained access policies tailored to their unique needs.

When creating custom permissions, administrators typically define the name and scope (namespace) of the permission. The name should be descriptive and indicative of the action or resource it governs. The scope determines where the permission applies, such as the platform(making it available across all the organizations in Frontier), organization, project or group.
When creating a custom permission, an administrator gives it a `key` in the form `service.resource.verb`. The key names the service, the resource the permission acts on, and the action it grants. For example, `potato.cart.delete` grants the delete action on the cart resource of the potato service.

:::note
The permissions can either be created dynamically when the Frontier is running, or can either be provided in the server configurations.
Custom permissions are created through the [reconcile flow](../reconcile.md) (a `kind: Permission` desired-state file) or through the [CreatePermission admin API](../apis/admin-service-create-permission). The older way of listing them in the server config file has been removed.
:::

For example, let's say you have an e-commerce application where users can manage their shopping carts. To control access to cart-related actions, you can create custom permissions in the **potato/cart** namespace.
For example, let's say you have an e-commerce application where users can manage their shopping carts. To control access to cart-related actions, you can create custom permissions for the cart resource.

Sample custom permission requirements:

| **Permission Name** | **Permission Title** | **Namespace** | **Description** |
| ------------------- | -------------------- | ------------- | ---------------------------------------------------------- |
| **delete** | Cart Delete | potato/cart | Grants the ability to delete items from the shopping cart. |
| **update** | Cart Update | potato/cart | Allows updating the contents of the shopping cart. |
| **get** | Cart Get | potato/cart | Enables retrieving the details of the shopping cart. |
| **Key** | **Permission Title** | **Description** |
| -------------------- | -------------------- | ---------------------------------------------------------- |
| `potato.cart.delete` | Cart Delete | Grants the ability to delete items from the shopping cart. |
| `potato.cart.update` | Cart Update | Allows updating the contents of the shopping cart. |
| `potato.cart.get` | Cart Get | Enables retrieving the details of the shopping cart. |

This is how the [resource config file](https://github.com/raystack/frontier/blob/7cae6bf86e99fe96650c6dcd4e8207cb916b8184/test/e2e/smoke/testdata/resource/potato.yaml#L4) will look like
This is how the desired-state file for these permissions looks:

```yaml
apiVersion: v1
kind: Permission
spec:
- key: potato.cart.delete
- key: potato.cart.update
- key: potato.cart.get
```

:::info
While creating permissions, it is important to note that the namespace is appended to the permission name to generate a permission slug. For instance, the **delete** permission name will be appended with namespace **potato/cart**, to generate the final permission slug as **potato_cart_delete** in Frontier. This naming convention is used to ensure uniqueness and organization of permissions within Frontier. While creating a role, we pass the list of these permission slugs being binded to that role.
Frontier turns a permission key into a slug by replacing the dots with underscores. So `potato.cart.delete` becomes the slug `potato_cart_delete`. When you create a role, you bind it to these permission slugs.
:::

## Managing Permission
Expand Down
7 changes: 1 addition & 6 deletions docs/content/docs/authz/policy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,7 @@ between the principal and the object.

We maintain spiceDB schema in [base_schema.zed](https://github.com/raystack/frontier/blob/4434204940f3a599b7e0ef399679f381db46c09a/internal/bootstrap/schema/base_schema.zed)
file in Frontier. The schema is then used to build the base set of permissions on predefined namespaces. Some permissions are
hardcoded in the schema, but Frontier allows custom permission set on Project resources. Custom permissions are dynamically
generated at frontier boot-up by merging them in the SpiceDB schema. To create custom permissions on a project resource
a [rule set](https://github.com/raystack/frontier/blob/ccf00da8a636f363546b1dbe6c7933323c369dca/internal/bootstrap/testdata/compute_service.yml)
can be configured in the [config.yaml](https://github.com/raystack/frontier/blob/7fca56ef567791bf4ea1280aa3f9b4ae997b1bf5/config/sample.config.yaml#L29)
file. Same is also exposed in the [Frontier API](../apis/admin-service-create-permission.api.mdx) to create
custom permissions on a project resource.
hardcoded in the schema, but Frontier allows custom permission set on Project resources. Custom permissions are managed through the [reconcile flow](../reconcile.md) (a `kind: Permission` desired-state file) or the [CreatePermission admin API](../apis/admin-service-create-permission). Creating one merges it into the SpiceDB schema, so the permission is ready to use in roles right away. The older way of declaring them in the server config file has been removed.

Frontier models roles as collection of permissions which can be created/updated/deleted dynamically at run time.

Expand Down
14 changes: 8 additions & 6 deletions docs/content/docs/basics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ app:

# platform level administration
admin:
# email list of users which needs to be converted as superusers
# if the user is already present in the system, it is promoted to su
# if not, a new account is created with provided email id and promoted to su
users:
- test@example.com
# bootstrap seeds a superuser service account from config. Automation such as
# the GitOps reconcile flow logs in as it, so there is always a superuser
# without needing an existing one. Log in with:
# Authorization: Basic base64(client_id:client_secret).
bootstrap:
client_id: ""
client_secret: ""
# smtp configuration for sending emails
mailer:
smtp_host: sandbox.smtp.mailtrap.io
Expand Down Expand Up @@ -85,7 +87,7 @@ to host frontier at somewhere like auth.example.com and main app at anywhere in
- app.authentication.session.hash_secret_key: random 32 char key
- app.authentication.session.block_secret_key: random 32 char key
- app.cors_origin: url of the frontend to allow cross-origin request
- admin.users: list of emails we want to be promoted as instance admins
- admin.bootstrap: client_id and client_secret for the bootstrap superuser service account that automation logs in as
- app.mailer.*: all these details are used to send the email to user. Get test configurations from `mailtrap.io` for testing.
- db.url: local database instance credentials in following form
- `postgres://<username>:<password>@<hostname>:<hostport>/<database_name>?sslmode=disable`
Expand Down
16 changes: 9 additions & 7 deletions docs/content/docs/configurations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,15 @@ app:
validity: 15m
# platform level administration
admin:
# Email list of users which needs to be converted as superusers
# if the user is already present in the system, it is promoted to su
# if not, a new account is created with provided email id and promoted to su.
# UUIDs/slugs of existing users can also be provided instead of email ids
# but in that case a new user will not be created.
users: []
# bootstrap seeds a superuser service account from config, using a client_id
# and client_secret. Automation such as the GitOps reconcile flow logs in as
# it, so there is always a superuser without needing an existing one. The
# account is created and promoted on every boot, and the secret is rotated if
# you change it here. Log in with: Authorization: Basic base64(client_id:client_secret).
# Leave both empty to turn this off.
bootstrap:
client_id: ""
client_secret: ""
# smtp configuration for sending emails
mailer:
smtp_host: smtp.example.com
Expand Down Expand Up @@ -346,7 +349,6 @@ If everything goes well, you should see something like this:

```bash
2023-05-17T00:02:54.324+0530 info frontier starting {"version": "v0.5.1"}
2023-05-17T00:02:54.331+0530 debug resource config cache refreshed {"resource_config_count": 0}
2023-05-17T00:02:54.333+0530 info Connected to spiceDB: localhost:50051
2023-05-17T00:02:54.339+0530 info metaschemas loaded {"count": 4}
```
12 changes: 8 additions & 4 deletions docs/content/docs/reference/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ List of supported environment variables
Export the current state of a kind as a desired-state YAML file, printed to
stdout. The output is the format `frontier reconcile` reads: reconciling it
changes nothing. Supported kinds: `PlatformUser`, `Permission`, `Role`,
`Preference`, `Webhook`. See the
`Preference`, `Webhook`, `BillingProduct`, `BillingPlan`, and `MetaSchema`. See the
[Reconcile guide](../reconcile.md) for the file format and the flow.

```
Expand Down Expand Up @@ -250,10 +250,14 @@ Make platform resources match a desired-state YAML file, through the admin
API. Supported kinds: `PlatformUser` (anyone listed is added, anyone not
listed is removed), `Permission` (custom permissions), `Role`
(platform-level roles), `Preference` (platform settings, where a setting
left out of the file resets to its default), and `Webhook` (webhook endpoints).
left out of the file resets to its default), `Webhook` (webhook endpoints),
`BillingProduct` (billing products and their prices), `BillingPlan` (billing
plans and the products they bundle), and `MetaSchema` (metadata validation
schemas, where a schema left out resets to its shipped default).
Deleting a permission, a custom role, or a webhook needs an explicit
`delete: true` on its entry; nothing is deleted by omission, and a predefined
role cannot be deleted. Use
`delete: true` on its entry; nothing is deleted by omission, a predefined
role cannot be deleted, and a billing product or plan cannot be deleted
through the API. Use
`frontier export` to print the current state in this file format, and see the
[Reconcile guide](../reconcile.md) for the full flow.

Expand Down
18 changes: 11 additions & 7 deletions docs/content/docs/reference/configurations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,15 @@ app:
validity: 15m
# platform level administration
admin:
# Email list of users which needs to be converted as superusers
# if the user is already present in the system, it is promoted to su
# if not, a new account is created with provided email id and promoted to su.
# UUIDs/slugs of existing users can also be provided instead of email ids
# but in that case a new user will not be created.
users: []
# bootstrap seeds a superuser service account from config, using a client_id
# and client_secret. Automation such as the GitOps reconcile flow logs in as
# it, so there is always a superuser without needing an existing one. The
# account is created and promoted on every boot, and the secret is rotated if
# you change it here. Log in with: Authorization: Basic base64(client_id:client_secret).
# Leave both empty to turn this off.
bootstrap:
client_id: ""
client_secret: ""
# smtp configuration for sending emails
mailer:
smtp_host: smtp.example.com
Expand Down Expand Up @@ -271,7 +274,8 @@ Configuration to allow authentication in Frontier.

| **Field** | **Description** | **Example** | **Required** |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------- | ------------ |
| **app.admin.users** | Email list of users to be converted as superusers. <br/> If the user is already present, they will be promoted to superuser. | | Optional |
| **app.admin.bootstrap.client_id** | Client id of the bootstrap superuser service account. Automation such as the GitOps reconcile flow logs in as it. Leave empty to turn it off. | | Optional |
| **app.admin.bootstrap.client_secret** | Client secret of the bootstrap superuser service account. The secret is rotated when you change it. | | Optional |

### Database Configurations

Expand Down
5 changes: 2 additions & 3 deletions docs/rfcs/0001-declarative-reconcile.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ file with the live server, prints a plan, and applies the difference through the
be seeded from a running server.

This document sets the rules every kind follows. The kinds are PlatformUser, Permission, Role,
Preference, and Webhook. New kinds plug in under the same rules without changing the commands
Preference, Webhook, MetaSchema, BillingProduct, and BillingPlan. New kinds plug in under the same rules without changing the commands
or the file format.

## At a glance
Expand All @@ -42,7 +42,7 @@ means and whether you can delete it:
flowchart TD
r["A resource the kind manages"] --> q{"Can reconcile<br/>create and delete it?"}
q -->|"yes"| o["Object<br/>Permission, Webhook, custom Role<br/>on the server but not in the file: the plan fails<br/>to delete one, set delete: true"]
q -->|"no"| v["Value<br/>PlatformUser, Preference, predefined Role<br/>always exists, so no delete flag<br/>not in the file: back to its default"]
q -->|"no"| v["Value<br/>PlatformUser, Preference, predefined Role, MetaSchema<br/>always exists, so no delete flag<br/>not in the file: back to its default"]
```

The kinds split cleanly, except Role, which is both: a custom role is an object, a predefined
Expand Down Expand Up @@ -286,7 +286,6 @@ roles, committed as the desired-state files, then dropping the setting from the
comes from the running server instead of the CLI's compiled copy. This removes the
image-version coupling.
- Passing the auth token without putting it in the process arguments.
- Billing plans as a kind, replacing the boot-time plans loader.
- Removing relation-based ownership from the base schema, so narrowing a predefined role
restricts everyone who holds it.

Expand Down
Loading