Approve or deny Privilege Manager elevation requests directly from Microsoft Teams
End-to-end flow from Privilege Manager to the Teams channel, powered by Azure services.
Delinea Privilege Manager ^ | REST API (poll, approve, deny, revoke) v Azure App Service (Python / aiohttp) |-- ApprovalPoller polls every 60s, posts cards proactively |-- PrivManBot handles Action.Submit from card buttons |-- AdminGuard Azure AD group check for admin commands |-- ScheduleStore auto-approve schedule (Azure Key Vault) ^ | Bot Framework channel v Azure Bot Service ---- Microsoft Teams (Adaptive Cards with inline actions)
Everything happens inside the Teams card. No context switching, no portal hopping.
Act on elevation requests directly from Adaptive Cards without leaving Teams.
Choose One Time, 15 min, 30 min, 1 hour, 2 hours, 4 hours, or 8 hours.
Revoke approvals or modify the duration after the fact, directly from the card.
Cards update in-place to show "Approved by X", "Denied by X", or "Revoked by X".
The bot posts cards to the channel automatically when new approval requests arrive.
Automatically approve requests outside business hours with configurable schedule.
Restrict autoapprove configuration to members of an Azure AD security group.
Conversation references survive app restarts so the bot never loses track of channels.
A single script creates all Azure resources, configures settings, and deploys the code.
Automatically deploys to Azure on every push to main via GitHub Actions.
Built on Azure services and the Bot Framework for production-grade reliability.
Clean separation between the bot layer, the PrivMan API client, deployment scripts, and Teams manifest.
privman-api-teams/ |-- azure_bot/ # Azure Bot Framework bot | |-- app.py # aiohttp entrypoint, routes, starts poller | |-- admin_guard.py # Azure AD group-based admin restriction | |-- bot.py # PrivManBot (TeamsActivityHandler) | |-- cards.py # Adaptive Card builders | |-- command_parser.py # Parse autoapprove chat commands | |-- config.py # Environment variable config | |-- conversation_store.py # Persist ConversationReference to JSON | |-- poller.py # Async polling + proactive card posting | |-- schedule_store.py # Key Vault-backed auto-approve schedule |-- privman_client/ # PrivMan API client library | |-- client.py # PrivManClient (auth, pending, approve, deny, revoke) | |-- models.py # ApprovalRequest dataclass | |-- exceptions.py # Custom exceptions |-- scripts/ | |-- deploy_azure.sh # Automated Azure deployment (creates everything) |-- teams_manifest/ # Teams app manifest template | |-- manifest.json # Template with placeholders | |-- color.png # 192x192 app icon | |-- outline.png # 32x32 outline icon |-- .github/workflows/ | |-- deploy.yml # GitHub Actions CD pipeline |-- requirements-azure.txt # Python dependencies |-- startup.sh # Azure App Service startup command |-- .env.example # Environment variable template |-- .gitignore
From zero to a working Teams approval bot in minutes with the automated deployment script.
Clone the repo and navigate into the project directory.
Execute ./scripts/deploy_azure.sh and follow the prompts. The script creates all Azure resources (resource group, AD app registration, App Service, Bot, Key Vault), configures settings, deploys the code, and generates the Teams manifest ZIP.
Open Teams, go to Apps, then Manage your apps, then Upload a custom app. Select the generated privman-bot-teams.zip and add the bot to your approvals channel.
Send any message to the bot (e.g., @PrivMan Approvals hello) to save the conversation reference. This enables proactive card posting.
The bot polls Privilege Manager every 60 seconds. When a new elevation request arrives, an interactive Adaptive Card appears in the channel. Select a duration and click Approve or Deny.