azp-cli
v1.4.0
Published
Terminal app to manage Azure PIM role activations
Maintainers
Readme
Azure PIM CLI (azp-cli)
A command-line interface tool for managing Azure Privileged Identity Management (PIM) role activations directly from your terminal.
Features
- 🔐 Role Activation - Quickly activate eligible Azure PIM roles
- 🔓 Role Deactivation - Deactivate active roles when no longer needed
- 📋 Interactive Menu - User-friendly menu-driven interface
- ✨ Beautiful UI - Polished terminal experience with spinners and colors
- 🔄 Multi-role Support - Activate or deactivate multiple roles at once
- 📊 Status Tracking - Real-time feedback on activation/deactivation status
- 💾 Presets - Save and reuse activation/deactivation configurations
- 🚀 Non-interactive Mode - CLI flags for scripting and automation
- 🔔 Update Notifications - Automatic update checks with configurable behavior
- 📤 JSON Output - Machine-readable output for integration with other tools
Prerequisites
Before using azp-cli, ensure you have:
- Node.js (v18 or higher)
- Azure CLI installed and configured
- Azure account with PIM-eligible roles
Azure CLI Setup
# Install Azure CLI (if not installed)
# See: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
# Login to Azure
az login
# Verify you're logged in
az account showInstallation
Global Installation (Recommended)
# Using npm
npm install -g azp-cli
# Using pnpm
pnpm add -g azp-cli
# Using yarn
yarn global add azp-cliAfter installation, the azp command will be available globally.
From Source (Development)
# Clone the repository
git clone https://github.com/tapanmeena/azp-cli.git
cd azp-cli
# Install dependencies
pnpm install
# Build the project
pnpm build
# Link globally for development
npm linkUsage
Running the CLI
# After global installation
azp
# Or with specific commands
azp activate
azp deactivate
azp preset list
azp update
# Development mode (from source)
pnpm devCommands
| Command | Alias | Description |
| ------------ | --------- | -------------------------------------- |
| activate | a | Activate a role in Azure PIM (default) |
| deactivate | d | Deactivate a role in Azure PIM |
| preset | - | Manage reusable presets |
| update | upgrade | Check for a newer version |
| help | - | Display help information |
Preset Subcommands
| Command | Description |
| --------------- | -------------------------------------------- |
| preset list | List all available presets |
| preset show | Show details of a specific preset |
| preset add | Add a new preset (interactive wizard) |
| preset edit | Edit an existing preset (interactive wizard) |
| preset remove | Remove a preset |
Updates
You can check if a newer version is available:
azp update
# alias
azp upgradeNotes:
azp updateexits with code0when up-to-date,2when an update is available, and1on error.--output jsonreturns a structured response suitable for scripts.- By default,
azp activateandazp deactivatewill also show a short “update available” hint (text mode only) at most once per day. - Disable update checks via
AZP_NO_UPDATE_NOTIFIER=1(orAZP_DISABLE_UPDATE_CHECK=1).
The update-check cache is stored alongside presets in your config directory:
- macOS/Linux:
~/.config/azp-cli/update-check.json(or$XDG_CONFIG_HOME/azp-cli/update-check.json) - Windows:
%APPDATA%\azp-cli\update-check.json
Non-interactive Mode (Automation)
Use flags to activate or deactivate PIM roles directly without going through the interactive menu, perfect for scripting and CI/CD workflows.
Activation Examples
# Activate a single role by name (non-interactive)
azp activate --no-interactive --yes \
--subscription-id <SUBSCRIPTION_GUID> \
--role-name "Owner" \
--duration-hours 2 \
--justification "Break-glass for incident" \
--output json
# Activate multiple roles (repeat --role-name)
azp activate --no-interactive --yes \
--subscription-id <SUBSCRIPTION_GUID> \
--role-name "Contributor" \
--role-name "User Access Administrator"
# If a role name matches multiple eligible roles (different scopes),
# --no-interactive will error unless you explicitly allow activating all matches
azp activate --no-interactive --yes \
--subscription-id <SUBSCRIPTION_GUID> \
--role-name "Contributor" \
--allow-multiple
# Preview what would happen without submitting requests
azp activate --no-interactive --dry-run \
--subscription-id <SUBSCRIPTION_GUID> \
--role-name "Contributor" \
--output jsonDeactivation Examples
# Deactivate specific roles
azp deactivate --no-interactive --yes \
--subscription-id <SUBSCRIPTION_GUID> \
--role-name "Owner" \
--justification "Task completed"
# Deactivate across all subscriptions (omit subscription-id)
azp deactivate --no-interactive --yes \
--role-name "Contributor" \
--allow-multipleAvailable Flags
Common flags (activate/deactivate):
--no-interactive- Disable interactive prompts-y, --yes- Skip confirmation prompts--subscription-id <id>- Target subscription (optional for deactivate)--role-name <name>- Role name(s) to target (can be repeated)--allow-multiple- Allow multiple role matches--dry-run- Preview without submitting--output <text|json>- Output format (default: text)--quiet- Suppress non-essential output
Activation-specific:
--duration-hours <n>- Duration (1-8 hours, default varies by role)--justification <text>- Justification for activation
Deactivation-specific:
--justification <text>- Justification for deactivation (optional)
Presets
Presets let you save your daily activation/deactivation routines (subscription + role names + duration + justification) and reuse them with --preset <name>.
Presets file location
By default, presets are stored in a per-user config file:
- macOS/Linux:
~/.config/azp-cli/presets.json(or$XDG_CONFIG_HOME/azp-cli/presets.json) - Windows:
%APPDATA%\azp-cli\presets.json
Override the location with:
AZP_PRESETS_PATH=/path/to/presets.json
Preset contents
A preset can define one or both blocks:
activate:subscriptionId,roleNames[],durationHours,justification,allowMultipledeactivate:subscriptionId(optional),roleNames[],justification,allowMultiple
justification supports simple templates:
${date}→YYYY-MM-DD${datetime}→ ISO timestamp${userPrincipalName}→ resolved from Microsoft Graph/me
Common Workflows
# Create a preset (interactive wizard)
azp preset add daily-ops
# Create a preset with Azure integration (fetches subscriptions/roles)
azp preset add daily-ops --from-azure
# Edit a preset (interactive wizard)
azp preset edit daily-ops
# List all presets
azp preset list
# Show one preset details
azp preset show daily-ops
# Remove a preset
azp preset remove daily-ops
# Use a preset (flags still override preset values)
azp activate --preset daily-ops --yes
# Non-interactive run using the preset
azp activate --preset daily-ops --no-interactive --yes --output json
# Deactivate using a preset
azp deactivate --preset daily-ops --no-interactive --yesDefaults
When you create a preset via azp preset add, you can optionally set it as the default for activate and/or deactivate.
- Default presets are applied automatically when you run one-shot flows and you haven’t explicitly provided the required flags.
- Example: after setting a default activate preset,
azp activate --no-interactive --yescan work without specifying--subscription-id/--role-name.
Example Session
╔════════════════════════════════════════════════════╗
║ Azure PIM CLI - Role Activation Manager ║
╚════════════════════════════════════════════════════╝
✔ Authentication successful
┌─ User Information ──────────────────────────────────
│ Name: John Doe
│ Email: [email protected]
└──────────────────────────────────────────────────────
✔ Found 3 subscription(s)
? What would you like to do?
❯ ▶ Activate Role(s)
◼ Deactivate Role(s)
✕ ExitRole Activation Flow
- Select a subscription from your available Azure subscriptions
- Choose one or more eligible roles to activate
- Specify activation duration (1-8 hours)
- Provide a justification for the activation
- Confirm and activate
Role Deactivation Flow
- View all currently active roles across subscriptions
- Select roles to deactivate
- Confirm deactivation
Development
Available Scripts
# Run in development mode with hot reload
pnpm dev
# Build the TypeScript project
pnpm build
# Run the built application
pnpm start
# Lint the codebase
pnpm lintChangelog & releases
This repo uses Keep a Changelog format in CHANGELOG.md.
Recommended commit messages
For best results, use Conventional Commits:
feat: ...(new feature) → minor bumpfix: ...(bug fix) → patch bumpchore: ...,docs: ...,refactor: ...(no bump unless breaking)
Cutting a release
Make sure
CHANGELOG.mdhas up-to-date entries under Unreleased.Run one of the following:
# Automatically determines next version from commits, updates CHANGELOG.md,
# bumps package.json, and creates a git tag.
pnpm release
# Preview what would change
pnpm release:dry
# Force a specific bump if needed
pnpm release -- --release-as patch
pnpm release -- --release-as minor
pnpm release -- --release-as major- Push commits + tags:
git push --follow-tags- Publish to npm (if desired):
npm publish
# or
pnpm publishProject Structure
azp-cli/
├── src/
│ ├── index.ts # CLI entry point and command definitions
│ ├── auth.ts # Azure authentication handling
│ ├── azure-pim.ts # Azure PIM API operations
│ ├── cli.ts # Interactive menu and user flows
│ ├── presets.ts # Preset configuration and storage
│ ├── presets-cli.ts # Preset wizard flows
│ ├── ui.ts # Terminal UI utilities (spinners, formatting)
│ └── update-check.ts # Update notification system
├── package.json
├── tsconfig.json
└── README.mdTech Stack
- TypeScript - Type-safe JavaScript
- Commander.js - CLI framework
- Inquirer.js - Interactive prompts
- Ora - Elegant terminal spinners
- Chalk - Terminal string styling
- Azure SDK - Azure service integration
Troubleshooting
"Azure CLI not found" Error
Ensure Azure CLI is installed and accessible in your PATH:
az --versionAuthentication Errors
Make sure you're logged in to Azure CLI:
az loginVerify your account has PIM-eligible roles:
az account showCheck if you have the necessary permissions in Azure AD
No Subscriptions Found
- Verify your Azure account has access to subscriptions
- Try refreshing your Azure CLI login:
az login --refresh
License
This project is licensed under the ISC License.
Author
Tapan Meena - [email protected]
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
