Professional Microsoft Entra ID Privileged Identity Management Tool
PIMBuddy is a comprehensive, browser-based tool for managing Microsoft Entra ID (formerly Azure AD) Privileged Identity Management (PIM). It provides an intuitive interface for managing PIM groups, role assignments, activations, approvals, and more—all without requiring a backend server.
- Dashboard - Real-time overview of PIM groups, active assignments, and health metrics
- PIM Groups - Create, configure, and manage role-assignable security groups
- Entra Roles - Browse and assign Entra ID directory roles to groups
- Policies - Configure activation duration, MFA requirements, justification, and approval workflows
- My Activations - View and manage your active and eligible role assignments
- Activate eligible roles with justification
- Extend or deactivate active assignments
- Real-time status updates
- Approvals - Review and process pending activation requests
- Approve or deny role activation requests
- Add approval justifications
- Multi-stage approval support
- PIM Activity - Comprehensive audit log of all PIM operations
- Role activations, assignments, and policy changes
- Filterable by date, user, and action type
- Health Check - Proactive monitoring of PIM configuration
- Detect groups without owners
- Identify inactive eligible assignments
- Find missing MFA requirements
- Discover overly permissive activation durations
- Expiring Assignments - Track assignments nearing expiration
- Automated notifications
- Bulk renewal capabilities
- Role Coverage - Analyze role assignment distribution
- Identify single points of failure
- Ensure adequate coverage for critical roles
- PIMMaid - Automated cleanup and maintenance
- Remove stale assignments
- Archive inactive groups
- Optimize policy configurations
- Baseline Deploy - Quick-start PIM configuration
- Deploy recommended baseline policies
- Industry best practices included
- Customizable templates
- Templates - Reusable policy configurations
- Save and apply policy templates
- Share configurations across groups
- Import/Export - Backup and restore capabilities
- Export entire PIM configuration to JSON
- Import configurations for disaster recovery
- Dark/Light Theme - User preference persistence
- Accessibility - WCAG 2.1 AA compliant
- Keyboard navigation (Alt+N, Alt+M, Alt+S shortcuts)
- Screen reader support
- Focus management
- Skip links
- Real-time Updates - Live status indicators
- Responsive Design - Mobile and tablet friendly
- Node.js 18+ (for development)
- Modern web browser (Chrome 80+, Firefox 78+, Edge 80+, Safari 14+)
- Microsoft Entra ID tenant with Premium P2 licensing
- Global Administrator or Privileged Role Administrator access (for initial setup)
- Basic understanding of Microsoft Entra ID
- Familiarity with PIM concepts (eligible vs active assignments)
- Azure App Registration setup
git clone https://github.com/yourusername/PIMBuddy.git
cd PIMBuddy/pimbuddy-webnpm install- Navigate to Azure Portal → Microsoft Entra ID → App registrations
- Click + New registration
- Configure:
- Name:
PIMBuddy - Supported account types: Accounts in this organizational directory only (Single tenant)
- Redirect URI:
- Type:
Single-page application (SPA) - URI:
http://localhost:3000(for development)
- Type:
- Name:
- Click Register
- Note the Application (client) ID and Directory (tenant) ID
In your app registration, go to API permissions and add these Microsoft Graph Delegated permissions:
| Permission | Purpose |
|---|---|
User.Read |
Sign in and read user profile |
Directory.Read.All |
Read directory data |
Group.Read.All |
Read all groups |
Group.ReadWrite.All |
Create and manage groups |
| Permission | Purpose |
|---|---|
PrivilegedAccess.Read.AzureADGroup |
Read PIM for Groups data |
PrivilegedAccess.ReadWrite.AzureADGroup |
Manage PIM for Groups |
PrivilegedEligibilitySchedule.Read.AzureADGroup |
Read eligible assignments |
PrivilegedEligibilitySchedule.ReadWrite.AzureADGroup |
Manage eligible assignments |
PrivilegedAssignmentSchedule.Read.AzureADGroup |
Read active assignments |
PrivilegedAssignmentSchedule.ReadWrite.AzureADGroup |
Manage active assignments |
| Permission | Purpose |
|---|---|
RoleManagement.Read.Directory |
Read Entra role definitions |
RoleManagement.ReadWrite.Directory |
Manage role assignments |
RoleEligibilitySchedule.Read.Directory |
Read eligible role schedules |
RoleEligibilitySchedule.ReadWrite.Directory |
Manage eligible role schedules |
RoleAssignmentSchedule.Read.Directory |
Read active role schedules |
RoleAssignmentSchedule.ReadWrite.Directory |
Manage active role schedules |
Important: Click Grant admin consent for your organization after adding permissions.
Edit pimbuddy-web/src/config/authConfig.js:
export const msalConfig = {
auth: {
clientId: "YOUR_APPLICATION_CLIENT_ID_HERE",
authority: "https://login.microsoftonline.com/YOUR_TENANT_ID_HERE",
redirectUri: "http://localhost:3000"
},
// ... rest of config
};Replace:
YOUR_APPLICATION_CLIENT_ID_HEREwith your Application (client) IDYOUR_TENANT_ID_HEREwith your Directory (tenant) ID
npm run devThe application will open at http://localhost:3000.
- Click Connect in the sidebar
- Sign in with your Microsoft account
- Accept the permission consent prompt
- You're ready to use PIMBuddy!
Build the application for deployment:
npm run buildOutput files are generated in the dist/ folder (approx. 750KB total).
Edit pimbuddy-web/vite.config.js:
import { defineConfig } from 'vite';
export default defineConfig({
root: '.',
base: '/PIMBuddy/', // Replace with your repository name
build: {
outDir: 'dist',
sourcemap: true
},
server: {
port: 3000,
open: true
}
});In your Azure App Registration, add the production redirect URI:
- Go to Authentication → Platform configurations → Single-page application
- Add URI:
https://yourusername.github.io/PIMBuddy/
Also update src/config/authConfig.js:
export const msalConfig = {
auth: {
clientId: "YOUR_CLIENT_ID",
authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
redirectUri: window.location.origin // Dynamic redirect
},
// ... rest
};Option A: Using GitHub Actions (Automated)
Create .github/workflows/deploy.yml:
name: Deploy to GitHub Pages
on:
push:
branches: [ main ]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
cache-dependency-path: pimbuddy-web/package-lock.json
- name: Install dependencies
run: |
cd pimbuddy-web
npm ci
- name: Build
run: |
cd pimbuddy-web
npm run build
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: pimbuddy-web/dist
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4Then:
- Push to GitHub
- Go to repository Settings → Pages
- Source: GitHub Actions
- The workflow will deploy automatically on every push to
main
Option B: Manual Deployment
# Build the project
cd pimbuddy-web
npm run build
# Install gh-pages (if not already installed)
npm install -g gh-pages
# Deploy to gh-pages branch
gh-pages -d distThen enable GitHub Pages:
- Go to repository Settings → Pages
- Source: Deploy from a branch
- Branch:
gh-pages→/ (root) - Save
Your app will be live at https://yourusername.github.io/PIMBuddy/
- Create an Azure Static Web App resource in Azure Portal
- Connect to your GitHub repository
- Configure build:
- App location:
/pimbuddy-web - Output location:
dist
- App location:
- Azure will auto-deploy on commits
- Update your app registration redirect URI with the Azure URL
The dist/ folder can be deployed to:
- Netlify: Drag & drop the
distfolder - Vercel: Import GitHub repository
- AWS S3 + CloudFront: Upload
distcontents - Any static web hosting: Upload
distcontents
- Frontend Framework: Vanilla JavaScript (ES6+)
- Build Tool: Vite 5
- Authentication: MSAL.js 3 (Microsoft Authentication Library)
- API Client: Microsoft Graph Client 3
- Styling: Custom CSS with CSS Variables for theming
┌───────────────────────────────────────────────────────────┐
│ Browser │
├───────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌────────────────┐ ┌──────────────┐ │
│ │ app.js │ │ PageRouter │ │ Accessibility│ │
│ │ (Bootstrap) │ │ (Navigation) │ │ Manager │ │
│ └──────┬───────┘ └────────┬───────┘ └──────────────┘ │
│ │ │ │
│ v v │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Page Components │ │
│ │ Dashboard | Groups | Roles | Activations | etc. │ │
│ └─────────────────────────┬────────────────────────────┘ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Service Layer │ │
│ │ ┌──────────┐ ┌───────────┐ ┌──────────────────┐ │ │
│ │ │authService│ │graphService│ │templateService │ │ │
│ │ └────┬─────┘ └─────┬─────┘ └────────┬─────────┘ │ │
│ └───────┼──────────────┼─────────────────┼────────────┘ │
│ │ │ │ │
│ v │ │ │
│ ┌──────────────┐ │ │ │
│ │ MSAL.js │ │ │ │
│ │ (Auth Tokens)│ │ │ │
│ └──────┬───────┘ │ │ │
│ │ │ │ │
└─────────┼───────────────┼──────────────────┼───────────────┘
│ │ │
v v v
┌────────────────────────────────────────────────────┐
│ Microsoft Graph API │
│ graph.microsoft.com │
│ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │
│ │ Groups │ │ Roles │ │ PIM │ │
│ └─────────────┘ └─────────────┘ └───────────┘ │
└────────────────────────────────────────────────────┘
PIMBuddy/
├── pimbuddy-web/ # Web application
│ ├── index.html # Entry point
│ ├── package.json # Dependencies
│ ├── vite.config.js # Build configuration
│ ├── src/
│ │ ├── app.js # Application bootstrap
│ │ ├── config/
│ │ │ └── authConfig.js # MSAL configuration
│ │ ├── core/
│ │ │ ├── PageRouter.js # SPA routing
│ │ │ ├── AccessibilityManager.js
│ │ │ └── CacheManager.js # Local caching
│ │ ├── pages/
│ │ │ ├── DashboardPage.js
│ │ │ ├── GroupsPage.js
│ │ │ ├── RolesPage.js
│ │ │ ├── ActivationsPage.js
│ │ │ ├── ApprovalsPage.js
│ │ │ ├── ActivityPage.js
│ │ │ ├── ExpiringPage.js
│ │ │ ├── HealthCheckPage.js
│ │ │ ├── CoveragePage.js
│ │ │ ├── PimmaidPage.js
│ │ │ ├── BaselinePage.js
│ │ │ ├── TemplatesPage.js
│ │ │ ├── ExportPage.js
│ │ │ └── SettingsPage.js
│ │ ├── services/
│ │ │ ├── authService.js # Authentication
│ │ │ ├── graphService.js # Graph API calls
│ │ │ ├── templateService.js
│ │ │ ├── pimmaidService.js
│ │ │ └── baselineService.js
│ │ ├── utils/
│ │ │ ├── uiComponents.js # Reusable UI
│ │ │ ├── errorHandling.js
│ │ │ ├── pagination.js
│ │ │ ├── bulkOperations.js
│ │ │ └── security.js
│ │ └── styles/
│ │ └── main.css # Application styles
│ └── dist/ # Build output (generated)
├── Modules/ # PowerShell modules (legacy)
├── GUI/ # WPF GUI (legacy)
└── README.md # This file
- PKCE Flow: Uses Proof Key for Code Exchange (no client secrets in browser)
- Token Storage: Session storage (cleared on tab close)
- Least Privilege: Requests only required permissions
- Admin Consent: Required for organization-wide permissions
- No Backend: All API calls direct to Microsoft Graph
- In-Transit Encryption: HTTPS only (enforced)
- No Data Persistence: No PII stored locally (except session tokens)
- CSP Headers: Content Security Policy recommended for production
- Review and approve all permission requests
- Use Conditional Access policies for PIMBuddy app
- Enable MFA for all privileged accounts
- Regularly audit PIM activity logs
- Implement break-glass accounts
- Navigate to PIM Groups
- Click + Create Group
- Fill in:
- Display Name: Group name
- Description: Purpose of the group
- Owner: Select an owner (yourself or another user)
- Click Create
- The group is created as role-assignable and PIM-enabled
- Navigate to Entra Roles
- Find the role you want to assign
- Click Assign Group
- Select:
- Group: The PIM group
- Assignment Type:
- Permanent Eligible (Recommended): Users can activate anytime
- Time-Bound Eligible: Eligible for a specific duration
- Permanent Active
⚠️ : Users always have the role (bypasses PIM) - Time-Bound Active: Active for a specific duration
- Duration (if time-bound): e.g., "P30D" for 30 days
- Justification: Business reason
- Click Assign
- Navigate to My Activations
- Find your eligible role
- Click Activate
- Provide:
- Duration: How long you need the role (max: policy limit)
- Justification: Why you need it
- Ticket Number (if required by policy)
- Click Activate
- If approval is required, status shows "Pending Approval"
- Once approved, role becomes active
- Navigate to Approvals
- Review pending requests
- Click Review on a request
- Choose Approve or Deny
- Provide justification
- Click Submit
- Navigate to Health Check
- Click Run Health Check
- Review findings:
- ❌ Critical: Immediate action required
⚠️ Warning: Should be addressed- ✅ Passed: No issues
- Click View Details for remediation steps
- Click Export Report to save results
- Navigate to Baseline Deploy
- Review recommended settings:
- Max activation duration: 8 hours
- MFA required on activation
- Justification required
- Approval required for Global Admin
- Select groups to apply baseline
- Click Deploy Baseline
- Confirm deployment
- Alt + N: Focus navigation menu
- Alt + M: Focus main content
- Alt + S: Focus search (if available on page)
- Tab / Shift+Tab: Navigate between elements
- Enter / Space: Activate buttons and links
- Escape: Close modals and dialogs
Cause: Authentication issue
Solution:
- Check
authConfig.jshas correct client ID and tenant ID - Verify redirect URI matches in Azure app registration
- Clear browser cache and cookies
- Try signing in again
Cause: Missing API permissions
Solution:
- Check all required permissions are granted
- Ensure admin consent was granted
- Wait 5-10 minutes for permissions to propagate
- Sign out and sign in again
Cause: Redirect URI mismatch
Solution:
- Go to Azure App Registration → Authentication
- Ensure redirect URI exactly matches your deployment URL
- For GitHub Pages:
https://yourusername.github.io/PIMBuddy/ - Case-sensitive, including trailing slash
Cause: API permissions or filtering
Solution:
- Verify
Group.Read.Allpermission is granted - Check if you have any groups in your tenant
- Try refreshing the page (Ctrl+R)
- Check browser console for errors (F12)
Cause: Node version or dependency issues
Solution:
# Check Node version (should be 18+)
node --version
# Clear node modules and reinstall
rm -rf node_modules package-lock.json
npm install
# Try building again
npm run buildWe welcome contributions! To contribute:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow existing code style and conventions
- Add comments for complex logic
- Test thoroughly before submitting
- Update README if adding new features
- Ensure accessibility compliance (WCAG 2.1 AA)
This project is licensed under the MIT License.
MIT License
Copyright (c) 2026 PIMBuddy Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- Issues: Report bugs via GitHub Issues
- Discussions: Ask questions in GitHub Discussions
- Documentation: See
/docsfolder for detailed guides
- Microsoft Graph API team for excellent documentation
- MSAL.js team for robust authentication library
- Entra ID PIM team for powerful privileged access management
- Community contributors
- Multi-tenant support
- Azure Resource PIM support
- Advanced analytics and reporting
- Custom policy templates marketplace
- Mobile app (React Native)
- PowerShell module integration
- Automated compliance reports
Built with ❤️ for secure identity management