This project demonstrates how to implement Role-Based Access Control (RBAC) in an Astro web application using Permit.io. It features a simple blog application where users with different roles (Admin, Employee) have varying levels of access to read, update, and delete blog posts.
Note: This example focuses on the frontend integration. Optionally, it assumes a separate backend service (like the corresponding Meteor example) is running and handling potentially other aspects (AI, database, ...).
- Frontend permission checks using Permit.io.
- Conditionally enabling/disabling actions (Edit/Delete) based on user permissions fetched from an API route.
- Integration with the Permit.io SDK via a dedicated API endpoint.
Astro is a modern framework for building fast websites. As applications grow, managing user permissions becomes crucial. While Astro doesn't have built-in RBAC, integrating an authorization layer ensures that authenticated users can only perform actions appropriate for their role.
Implementing authorization logic from scratch is complex and time-consuming. Permit.io simplifies this by providing a decoupled authorization layer with an intuitive interface to manage policies, roles, and resources outside your application code. This leads to cleaner code, easier management, and consistent access control.
- Node.js: Ensure you have Node.js (version recommended by Astro) installed.
- Astro Familiarity: Basic understanding of Astro concepts is helpful.
- Permit.io Account: You'll need a free Permit.io account to configure the authorization policies.
Key files and directories in this project:
/
├── public/
│ └── favicon.svg
├── src/
│ ├── components/
│ │ └── BlogList.jsx # React component displaying blogs and handling edit/delete actions with permission checks
│ ├── layouts/
│ │ └── Layout.astro # Main Astro layout
│ ├── pages/
│ │ ├── api/
│ │ │ └── getPermissions.json.js # API route that uses Permit.io SDK to check permissions
│ │ ├── blog/ # Markdown files for blog posts
│ │ └── index.astro # Main page, renders BlogList
│ ├── styles/
│ │ └── global.css
│ ├── utils/
│ │ ├── blogs.js # Sample blog data
│ │ └── user.json # Sample user data (including key for permission checks)
│ └── env.d.ts
├── .env # (Needs to be created) For storing API keys
├── astro.config.mjs
├── package.json
└── README.md
Follow these steps in your Permit.io dashboard to set up the necessary authorization rules for this demo. Ensure you are working within the Default Project and production environment.
-
Create Resource:
- Navigate to
Policy->Resources. - Click
Create Resource. - Name:
Blog - Key:
Blog - Actions:
read,create,update,delete - Click
Create Resource.
- Navigate to
-
Create Roles:
- Navigate to
Policy->Roles. - Click
Create Role. - Role 1:
- Name:
Admin - Key:
Admin - Permissions: (Leave blank for now, we'll set in the Policy Editor)
- Name:
- Click
Create Role. - Role 2:
- Name:
Employee - Key:
Employee - Permissions: (Leave blank for now)
- Name:
- Click
Create Role. - Note: Differentiate these from the default
adminrole if necessary.
- Navigate to
-
Define Policy:
- Navigate to
Policy->Policy Editor. - Configure permissions for the
Blogresource:Adminrole: Checkread,create,update,delete.Employeerole: Checkread.
- Click
Save ChangesorPublish Changes.
- Navigate to
-
Create Tenant:
- Navigate to
Directory->Tenants. - Click
Create Tenant. - Name:
blog-tenant - Key:
blog-tenant(auto-generated usually) - Description:
A tenant for our blog - Click
Create Tenant.
- Navigate to
-
Create User:
- Navigate to
Directory->Users. - Click
Create User. - Key:
demo-user(or choose your own) - Email:
[email protected](use a real or placeholder email) - First Name:
Demo - Last Name:
User - Assign the user to the
blog-tenant. - Assign the
Employeerole initially for the demo. - Click
Create User.
- Navigate to
-
Clone the Repository:
# If you haven't already, clone the main permit.io examples repo git clone https://github.com/hermitonl/astro cd astro
-
Install Dependencies:
npm install
-
Configure Environment Variables:
- Create a
.envfile in theastro/directory. - Go to your Permit.io Settings -> API Keys and generate a new API Key with
ReadandWritepermissions for theDefault Projectandproductionenvironment. - Copy the API Key.
- Add the following line to your
.envfile, replacing<YOUR_PERMIT_API_KEY>with the key you just copied:PERMIT_TOKEN="<YOUR_PERMIT_API_KEY>"
- Create a
Start the Astro development server:
npm run devNavigate to http://localhost:4321 in your browser.
The application will load, and the BlogList component will fetch permissions via the /api/getPermissions.json route when you attempt to edit or delete posts.
This project is configured for deployment to Vercel using the @astrojs/vercel/serverless adapter.
-
Prerequisites:
- Ensure your code is pushed to a GitHub/GitLab/Bitbucket repository.
- Sign up for a free Vercel account and connect it to your Git provider.
-
Import Project:
- On your Vercel dashboard, click "Add New..." -> "Project".
- Select the repository containing this project.
-
Configure Project:
- Root Directory: Vercel needs to know the code is in the
astro/subdirectory. Click "Edit" next to "Root Directory" and set it toastro. - Framework Preset: Vercel should automatically detect "Astro".
- Build & Output Settings: These should be detected automatically (Build Command:
npm run build, Output Directory:.vercel/output). You typically don't need to change these. - Node.js Version: The required Node.js version ("18.x") is specified in
package.jsonand should be used automatically by Vercel. - Environment Variables:
- Expand the "Environment Variables" section.
- Add a variable with the Name
PERMIT_TOKENand paste your Permit.io API Key into the Value field. - Ensure it's available for all environments.
- Root Directory: Vercel needs to know the code is in the
-
Deploy:
- Click the "Deploy" button. Vercel will build and deploy your site.
-
Access: Once complete, Vercel will provide the URL for your live deployment.
- API Route (
src/pages/api/getPermissions.json.js): This server-side route uses the Permit SDK (permit.check()) to determine the permissions for the currently hardcoded user (demo-userwithin theblog-tenant) regarding theBlogresource. In a real application, you would replace the hardcoded user key with the identifier of the logged-in user. - Frontend Components (
src/components/BlogList.jsx): This React component fetches permissions from the API route. Based on the returned permissions (read,update,delete), it conditionally renders UI elements like "Edit" and "Delete" buttons next to each blog post.
- The
BlogList.jsxcomponent renders blog posts with "Edit" and "Delete" buttons. - When a user clicks "Edit" or "Delete", the component calls the
/api/getPermissions.jsonAPI route, passing theuser.key(fromsrc/utils/user.json) and theoperation('update' or 'delete'). - The
getPermissions.json.jsAPI route uses thepermitioSDK and thePERMIT_TOKENto callpermit.check(user, operation, resource)against the Permit.io PDP. - The API route returns
{ "status": "permitted" }or{ "status": "not-permitted" }. - The
BlogList.jsxcomponent receives the response. If permitted, it updates the UI state (edits or deletes the post). If not permitted, it does nothing, effectively blocking the action.
This application demonstrates access control based on the user's assigned role in Permit.io.
- Setup: Ensure the user (
demo-useror the key you created) is assigned theEmployeerole in the Permit.io dashboard (Directory->Users-> Edit User -> Role Assignments). - Run the App:
npm run devand openhttp://localhost:4321. - Observe: You should see the list of blog posts. However, the "Edit" and "Delete" buttons should not be visible, as the
Employeerole only hasreadpermission for theBlogresource.
- Update Role: Go to your Permit.io dashboard (
Directory->Users-> Edit User -> Role Assignments). Change the user's role fromEmployeetoAdmin. Save the changes in Permit.io. - Restart/Refresh App: You might need to stop (
Ctrl+C) and restart the dev server (npm run dev) or simply refresh the browser page (http://localhost:4321) for the permission changes to take effect (as the permissions are fetched on load). - Observe: You should now see the "Edit" and "Delete" buttons next to each blog post, as the
Adminrole hasread,update, anddeletepermissions. (Note: The actual edit/delete functionality is not implemented in this basic demo, but the UI reflects the permissions).
This demonstrates how you can dynamically control user capabilities in your Astro application by managing roles and policies centrally in Permit.io without changing your application code.
| Command | Action |
|---|---|
npm install |
Installs dependencies |
npm run dev |
Starts local dev server at localhost:4321 |
npm run build |
Build your production site to ./dist/ |
npm run preview |
Preview your build locally, before deploying |