# Teams App

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FZCQNF3bUB067hlRPuW6I%2FKeeper%2BMicrosoft-teams.png?alt=media&#x26;token=e4240750-cfc9-41b0-86ed-3fece21308e4" alt=""><figcaption></figcaption></figure>

The **Keeper Teams App** helps achieve zero standing privilege and streamlines credential workflow requests and approvals directly from Teams. The customer hosts the Teams agent and Commander Service Mode, ensuring that zero knowledge is maintained with end-to-end encryption.

This document describes the installation of the Keeper Teams App using a streamlined setup method that requires the use of Keeper Secrets Manager. If you don't have a Secrets Manager or KeeperPAM license, please contact your Keeper account manager.

## Features

<table><thead><tr><th width="309.94140625">Feature</th><th>Description</th></tr></thead><tbody><tr><td><strong>Record Access Requests</strong></td><td>Request access to specific Keeper records with justification, custom permissions and access time limits. This includes standard vault records and KeeperPAM resources.</td></tr><tr><td><strong>Folder Access Requests</strong></td><td>Request access to specific Keeper Shared Folders with justification, custom permissions and access time limits.</td></tr><tr><td><strong>One-Time Share Requests</strong></td><td>Request for a one-time share, password reset or other dynamic password generation with a self-destructing share link. The one-time share can also be editable, offering bi-directional sharing capabilities.</td></tr><tr><td><strong>Endpoint Privilege Manager Approvals</strong></td><td>Keeper Endpoint Privilege Manager (KEPM) just-in-time elevation approvals in realtime through a dedicated Teams channel.</td></tr><tr><td><strong>SSO Cloud Device Approvals</strong></td><td>Perform approvals of SSO Cloud devices directly through Teams, if the Keeper Automator service is not deployed.</td></tr></tbody></table>

***

## Prerequisites

#### System Requirements

To maintain zero knowledge and full end-to-end encryption, the Keeper Teams App and Commander Service Mode containers are hosted by each customer on their own infrastructure to interact with the Microsoft Teams cloud service. Commander is used locally to help set everything up.

<table><thead><tr><th width="262.71484375">Requirement</th><th>Details</th></tr></thead><tbody><tr><td>Linux VM</td><td>Any VM in the cloud or on-prem which can establish https/443 outbound connections to Teams and Keeper services.</td></tr><tr><td>Docker</td><td>Docker is the recommended method for setting up the service</td></tr><tr><td>Keeper Commander</td><td>Latest Keeper Commander needs to be install</td></tr><tr><td>Keeper Secrets Manager</td><td>Either Keeper Secrets Manager or KeeperPAM license used for retrieving the secret configuration data</td></tr><tr><td>Microsoft Azure Tenant</td><td>Requires admin access to register apps in Azure AD</td></tr><tr><td>Microsoft Teams</td><td>Teams workspace with permissions to install custom apps</td></tr></tbody></table>

{% hint style="warning" %}
Important: The `teams-app-setup` command requires Keeper Secrets Manager (KSM) to be activated. If KSM is not available, please contact your account manager.
{% endhint %}

## Setup Steps

In the below setup instructions, we'll be using Commander and Teams-App Docker Images ([keeper/commander](https://hub.docker.com/r/keeper/commander) and [keeper/teams-app](https://hub.docker.com/r/keeper/teams-app)). This integration also leverages Keeper Secrets Manager to secure the configurations used by the services.

Follow these eight steps to configure the Teams app:

1. [Register Azure AD Application](#step-1.-register-azure-a-d-application)
2. [Create Azure Bot Registration](#step-2.-create-azure-bot-registration)
3. [Create Approvals Channel](#step-2.-create-approvals-channel)
4. [Commander service mode setup](#step-4.-commander-service-mode-setup)
5. [Run Teams App Setup Command](#step-5.-run-teams-app-setup-command)
6. [Deploy to Docker Environment](#step-6.-deploy-to-docker-environment)
7. [Configure Messaging Endpoint](#step-7.-configure-messaging-endpoint)
8. [Upload teams App package](#step-8.-upload-teams-app-package)

***

### Step 1. Register Azure AD Application

In this section, you will create an Azure AD Application in your Microsoft 365 tenant to authenticate the Teams bot.

* Sign in to the [Azure Portal](https://portal.azure.com) as a Global Administrator or Application Administrator
* Navigate to **Azure Active Directory** → **App registrations**

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FS3CfTxnQ0q953jQvSmoZ%2Fapp%20reg%201.png?alt=media&#x26;token=91c5d7b4-ea40-482f-844e-52ca33890ff7" alt=""><figcaption></figcaption></figure>

* Click **New registration -> All applications**

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2Flak81eHnFFr3d3ame1i6%2Fapp%20reg%202.png?alt=media&#x26;token=93f42cea-4005-479d-aae9-5035c3654464" alt=""><figcaption></figcaption></figure>

* Configure the application:\
  \- **Name:** `keeper-security-teams` \
  \- **Supported account types:** "Accounts in this organizational directory only"\
  \- **Redirect URI:** Leave blank for now

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FzB0BpMcdEWnsc8AcqCAj%2Fapp%20reg%203.png?alt=media&#x26;token=dec4858e-69dd-4816-925e-2fe0b521bf79" alt=""><figcaption></figcaption></figure>

<div align="center"><figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FoSOtQDxW2rKicQ5aleaW%2Fapp%20reg%204.png?alt=media&#x26;token=c2bba20e-d28f-43d8-85c9-19cda9227e06" alt=""><figcaption></figcaption></figure></div>

* Click **Register**
* After creation, note the following values from the **Overview** page:

  * **Application (client) ID** - Save this as `AZURE_CLIENT_ID`
  * **Directory (tenant) ID** - Save this as `AZURE_TENANT_ID`&#x20;

  <figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FdluqpByEmaYj7BPhQMmu%2Fapp%20reg%205.png?alt=media&#x26;token=ac0bb90d-bc75-4e0f-a364-6fd47b2de8d1" alt=""><figcaption></figcaption></figure>
* Configure **API Permissions**:

  * Go to Manage → **API permissions** → **Add a permission**

  <figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FQijf4bDtJXjiM6jqUfGY%2Fapp%20reg%206.1.png?alt=media&#x26;token=cd4f3cf9-b745-4ab6-8dd9-c9912c468cb9" alt=""><figcaption></figcaption></figure>

  * Select **Microsoft Graph** → **Application permissions**

  <figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FsjHAPiukSoPMT3Jk9wWR%2Fapp%20reg%206.2.png?alt=media&#x26;token=e5efee61-5e17-42b0-b21e-24d11906ce4b" alt=""><figcaption></figcaption></figure>

  * Add the following permissions:
    * `ChannelMessage.Read.All`
    * `User.Read.All`&#x20;

  <figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FjgnR7FY0JE29B8lsmGM9%2Fapp%20reg%206.3.png?alt=media&#x26;token=bbb06480-0e6c-41e0-bf94-f1f917e7ae98" alt=""><figcaption></figcaption></figure>

  * Click **Grant admin consent for MSFT**

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FiY9JDlQWmJc4fa0ZaH5T%2Fapp%20reg%206.4.png?alt=media&#x26;token=d35d6e45-8a68-4bf1-afa1-19970ab49278" alt=""><figcaption></figcaption></figure>

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FIsPlNZM9mWfVniuaCVUL%2Fapp%20reg%206.5.png?alt=media&#x26;token=0d1e74aa-f533-496d-9bba-18d18f53d9b4" alt=""><figcaption></figcaption></figure>

* Create a **Client Secret**:
* Go to **Certificates & secrets** → **Client secrets**

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FdAAm7DcYGHLIbA6Rvuf5%2Fapp%20reg%207.png?alt=media&#x26;token=e8caf995-9a22-4f4a-a21e-b38087a50135" alt=""><figcaption></figcaption></figure>

* Click **New client secret**
* Description: `Keeper Teams App`
* Expiration: Select appropriate duration (recommend 24 months)
* Click **Add**
* **Copy the Value immediately** - Save this as `AZURE_CLIENT_SECRET`

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FdeV3k7F7ZGqDUMIwzxK7%2Fapp%20reg%208.png?alt=media&#x26;token=ea09cbcf-b669-4ead-92b4-9dd46016f331" alt=""><figcaption></figcaption></figure>

After creating the app, collect these credentials:

<table><thead><tr><th width="219.890625">Credential</th><th>Location</th></tr></thead><tbody><tr><td>CLIENT_ID</td><td>App Registration → Overview → Application (client) ID</td></tr><tr><td>TENANT_ID</td><td>App Registration → Overview → Directory (tenant) ID</td></tr><tr><td>Signing Secret</td><td>App Registration → Certificates &#x26; secrets →Client secrets(Value)</td></tr></tbody></table>

{% hint style="info" %}
Save the Generated Client ID, Tenant ID  and **Signing Secret value** for **Step 4.**
{% endhint %}

***

### Step 2. Create Azure Bot Registration

* In the Azure Portal, search for Bot Services  -> click **Create a resource**

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FOWpGQXXfXmilH3q2ugal%2Fbot%20service%201.png?alt=media&#x26;token=383080b6-6666-4808-8b7d-5ad5c7612d14" alt=""><figcaption></figcaption></figure>

* Search for Bot Services and click **Create**

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2F1gtoaXtuTuvsB8yTiMqx%2Fbot%20service%202.png?alt=media&#x26;token=3938cbda-93ee-405b-89be-1e38ce3b06f8" alt=""><figcaption></figcaption></figure>

* Configure the bot:

  * **Bot handle:** `keeper-security-bot` (must be unique)
  * **Subscription:** Select your subscription
  * **Resource group:** Create new or use existing
  * **Pricing tier:** Free (F0) for testing, Standard (S1) for production
  * **Type of App:** Single Tenant
  * **Creation type:** Use existing app registration
  * **App ID:** Enter the Application (client) ID and tenant ID from Step 1

  <figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FjgGvH0zLSlLawVOdL3cP%2Fbot%20service%203.png?alt=media&#x26;token=9b47da18-a01c-42b7-809d-172bce29bf51" alt=""><figcaption></figcaption></figure>
* Click **Review + create** → **Create**

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2F69B9ZRYlDnThL2BII8Ym%2Fbot%20service%204.png?alt=media&#x26;token=c87596c9-c589-4e0a-bbc6-8cd288a4ebe9" alt=""><figcaption></figcaption></figure>

* Note the **Microsoft App ID** (same as Application ID from Step 1) - Save this as `BOT_ID`

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FZZAw08Scs4VCHPmfgzxI%2Fbot%20service%205.png?alt=media&#x26;token=a4fefddb-3946-4e7d-aa3c-e8ce77c05906" alt=""><figcaption></figcaption></figure>

***

### Step 3. Create Approvals Channel <a href="#step-2.-create-approvals-channel" id="step-2.-create-approvals-channel"></a>

* In Microsoft Teams, create a new Private channel (e.g., `#keeper-vault-approvers`)
  * Right-click on your Team → **Add channel**
  * **Channel name:** `keeper-vault-approvers`
  * **Privacy:** Private - Only specific teammates can access
  * Click **Create**
* Get the **Team ID** and **Channel ID**:

  * Open Teams in a web browser
  * Navigate to the approvals channel
  * Click on the channel name -> will open a popup like below

  <figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FsqSbGtb8o0bPerXGpFMJ%2FScreenshot%202026-03-23%20at%2012.05.10%E2%80%AFPM.png?alt=media&#x26;token=8d0ce6d1-48a7-44b6-bf1f-a8a466c827bd" alt=""><figcaption></figcaption></figure>

  * Copy the link and open in a new tab
  * The URL will look like: `https://teams.microsoft.com/l/channel/19%3A...@thread.tacv2/...?groupId=<TEAM_ID>&tenantId=...`
  * Extract the `groupId` as **Team ID**
  * **Channel ID:** The value between `/channel/` and the channel name, URL-decoded\
    Replace `%3A` with `:` and `%40` with `@`\
    \
    Example (before): `19%3AXSD5456476qe-a915_bN8WU7qScl7687678nj1Ya0e0RM1%40thread.tacv2`\
    Example (after): `19:XSD5456476qe-a915_bN8WU7qScl7687678nj1Ya0e0RM1@thread.tacv2`

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2Fhbu8QfsjkAYTQi1sHZhX%2FScreenshot%202026-03-23%20at%207.34.24%E2%80%AFPM.png?alt=media&#x26;token=81d8aae3-b959-4536-a341-bd95f3f70f65" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Save the **Channel ID and Team ID** for **Step 5.**
{% endhint %}

### Step 4. Commander Service Mode Setup

To enable the service to authenticate and execute commands within the Keeper tenant, an authorized **Keeper Commander configuration file** must be created. This configuration can be generated on a host computer or workstation.

* [Install Keeper Commander](https://docs.keeper.io/en/keeperpam/commander-cli/commander-installation-setup) locally on your machine
* If required, create a new Keeper service account dedicated to this integration, ensuring it has access to the relevant records and folders and the ability to perform record and folder sharing.
* Login to Commander with the Keeper Service account `(serviceuser@company.com)`

```
keeper shell
My Vault> login serviceuser@company.com
```

* Complete the authentication process including any 2FA requirements. Once you are fully authenticated, proceed to Step 4.

***

### Step 5. Run Teams App Setup Command

The `teams-app-setup` command generates a `docker-compose.yml` file which you will use to operate the Teams App and Commander Service Mode services.

From the Commander shell, type:

```
teams-app-setup
```

**Command Line Options**

The `teams-app-setup` command supports the following optional flags for customization:

| Parameter                       | Description                                    | Default Value                           |
| ------------------------------- | ---------------------------------------------- | --------------------------------------- |
| --folder-name (optional)        | Name for the shared folder                     | Commander Service Mode - Teams App      |
| --app-name (optional)           | Name for the Secrets Manager app               | Commander Service Mode - KSM App        |
| --config-record-name (optional) | Name for the Commander config record           | Commander Service Mode Docker Config    |
| --teams-record-name (optional)  | Name for the Teams config record               | Commander Service Mode Teams App Config |
| --config-path (optional)        | Path to config.json file                       | \~/.keeper/config.json                  |
| --timeout (optional)            | Device timeout setting                         | 30d                                     |
| --skip-device-setup (optional)  | Skip device registration if already configured | false                                   |

Example with Custom Names:

```
teams-app-setup --folder-name "My Teams Integration" --timeout 7d
```

The command will guide you through the following prompts:

#### **Phase 1: Docker Service Mode Setup**

It automatically configures KSM and uploads the config file required for setting up service mode via Docker.

```bash
Phase 1: Running Docker Service Mode Setup
═══════════════════════════════════════════════════════════
    Docker Setup
═══════════════════════════════════════════════════════════

[1/7] Checking device settings...
  ✓  Device already registered
  ✓  Persistent login already enabled
  ✓  Setting logout timeout to 30d...

[2/7] Creating shared folder 'Commander Service Mode - Teams App'...
  ✓  Shared folder created successfully

[3/7] Creating record 'Commander Service Mode Docker Config'...
  ✓  Record created successfully

[4/7] Uploading config.json attachment...
  ✓  Config file uploaded successfully

[5/7] Creating Secrets Manager app 'Commander Service Mode - KSM App'...
  ✓  App created successfully

[6/7] Sharing folder with app...
  ✓  Folder shared with app

[7/7] Creating client device and generating config...
  ✓  Client device created successfully

✓ Docker Setup Complete!
```

**Service Configuration**

Configure the Commander Service port:

<table><thead><tr><th width="155.578125">Prompt</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>Port</td><td>Port number for Commander Service Mode (1024-65535).</td><td>8900</td></tr></tbody></table>

#### **Phase 2: Teams App Integration Setup**

Enter the Teams credentials obtained from **Steps 1 and 2**:

<table><thead><tr><th width="222.23046875">Prompt</th><th width="310.171875">Description</th><th>Example</th></tr></thead><tbody><tr><td>Teams Client ID (required)</td><td>Azure App Registration Application (client) ID</td><td>2efdee8-6a0a-0...</td></tr><tr><td>Client Secret (required)</td><td>Azure App Registration secret value</td><td>f16241e1-b52a-24...</td></tr><tr><td>Tenant ID (required)</td><td>Azure AD Directory (tenant) ID</td><td>a1b2c3d4e5f6...</td></tr><tr><td>Teams Approvals Channel ID (required)</td><td>The channel ID from Step 3.(Required)</td><td>19:OfBgL.....x41@thread.tdf..</td></tr><tr><td>Approvals Team ID (required)</td><td>The channel ID from Step 3.(Required)</td><td>9336604b-038e-4...</td></tr><tr><td>Teams bot port</td><td>Port on which the Teams bot will listen for incoming requests</td><td>eg: 3978</td></tr><tr><td>Enable PEDM? (optional)</td><td>Enable Endpoint Privilege Manager approvals (y/n).</td><td>y</td></tr><tr><td>PEDM Polling Interval (optional)</td><td>How often to check for PEDM requests in seconds. Default: 120.</td><td>120</td></tr><tr><td>Enable Device Approvals?(optional)</td><td>Enable SSO Cloud device approvals (y/n).</td><td>y</td></tr><tr><td>Device Approval Polling Interval (optional)</td><td>How often to check for device approvals in seconds. Default: 120.</td><td>120</td></tr></tbody></table>

{% hint style="info" %}
In order to process Endpoint Privilege Manager approvals and SSO Cloud approvals, the Teams App service user must have administrative permissions "Manage Endpoint Privilege" and "Managing the Keeper Admin Console.
{% endhint %}

After the command executes successfully, it automatically performs the following actions:

* Configures persistent device authentication
* Creates a Shared Folder named **“Commander Service Mode – Teams App”**
* Creates a KSM application with access to the shared folder
* Creates a client device and generates a Base64-encoded configuration value
* Creates a Docker Config record and uploads the `config.json` file from the `.keeper` directory
* Creates a Teams App Config record containing the Teams App credentials.

```bash
✓ Teams App Integration Setup Complete!

Resources Created:
  Phase 1 - Commander Service:
    • Shared Folder: Commander Service Mode - Teams App
    • KSM App: Commander Service Mode - KSM App (with edit permissions)
    • Config Record: XXXXXX
    • KSM Base64 Config: ✓ Generated
  Phase 2 - Teams App:
    • Teams Config Record: XXXXXX
    • Approvals Channel: XXXXXX
    • PEDM Integration: false
    • Device Approval: false
```

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2F4KJaw50JbS4HoAgFQznn%2Fteams%20vault%20data%20store.png?alt=media&#x26;token=35d42912-d0d8-4dc4-a2cc-67224313043f" alt=""><figcaption></figcaption></figure>

* Upon successful execution, a `docker-compose.yml` is generated containing both the Commander Service Mode and Teams App services, ready for deployment.

{% code overflow="wrap" %}

```yaml
services:
  commander-teams:
    container_name: keeper-service-teams
    ports:
    - 127.0.0.1:8900:8900
    image: keeper/commander:latest
    command: service-create -p 8900 -c 'search,share-record,share-folder,record-add,one-time-share,epm,pedm,device-approve,get,server' -f json -q y -ur lm8vnKnG5yYyjPmtL91IQQ --ksm-config
    healthcheck:
      test:
      - CMD-SHELL
      - python -c "import sys, urllib.request; sys.exit(0 if urllib.request.urlopen('http://localhost:8900/health', timeout=2).status == 200 else 1)"
      interval: 60s
      timeout: 3s
      start_period: 10s
      retries: 30
    restart: unless-stopped
  teams-app:
    container_name: keeper-teams-app
    image: keeper/teams-app:latest
    ports:
    - 3978:3978
    environment:
      KSM_CONFIG: KSM_CONFIG_BASE64_CODE
      COMMANDER_RECORD: RECORD_UID_OR_TITLE
      TEAMS_RECORD: TEAMS_RECORD_UID_OR_TITLE
    depends_on:
      commander-teams:
        condition: service_healthy
    restart: unless-stopped

```

{% endcode %}

Once setup is complete, ensure that the Commander session is terminated and the local `.keeper/config.json` file is deleted to prevent device token conflicts.

```
My Vault> quit
$ rm ~/.keeper/config.json
```

***

### Step 6. Deploy to Docker Environment

In this section, you will set up a Docker Compose environment on a Linux virtual machine or host where the Commander Service will run.

* Launch a Linux VM or prepare a Linux host and connect to it via SSH.
* Install `docker` and `docker-compose` (refer to the installation instructions [here](https://docs.keeper.io/en/keeperpam/privileged-access-manager/references/installing-docker-on-linux))
* Transfer the generated `docker-compose.yml` file from Step 4 to the target Linux server.

Start up the services on the host machine:

```
docker compose up -d
```

**Service Startup Sequence**

The services start sequentially:

1. Commander Service starts first, generates an API key, and saves it along with the service URL to the vault record
2. Health checks validate the Commander service is running
3. Teams App starts after health checks pass, automatically retrieving the API key and service URL from the vault record

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2Fs1ZrniCgf4OxJ5aoVqwh%2FTEMS-SERVICE-MODE%20VAULT.png?alt=media&#x26;token=c8e8907e-6993-4e21-ac04-a4881313954c" alt=""><figcaption></figcaption></figure>

**Verify Successful Startup**

Monitor the logs to make sure everything starts up.

* Check container status:

```bash
$ docker ps
NAME              STATUS                    PORTS
keeper-service    Up (healthy)              127.0.0.1:<port> -> <port>/tcp
keeper-teams-app  Up  
```

* View Commander Service logs:

```bash
$ docker logs keeper-service
[2026-01-21 10:00:00] Starting Commander Service Mode...
Generated API key: ****nQ= (stored in vault record: <CONFIG_VAULT_RECORD>)
Commander Service starting on <SERVICE_URL>/api/v2
Keeper Commander Service initialization complete
```

{% hint style="info" %}
The API key is redacted in Docker logs for security. Both services communicate securely via the shared vault record.
{% endhint %}

* View Teams App logs:

```
docker logs keeper-teams-app
```

If everything is successful, you'll see the messages below:

```cobol
[INFO] [KeeperClient] KeeperClient initialized {"baseUrl":"http://commander-teams:4001/api/v2"}
[INFO] [ChannelService] Loaded 4 conversation references from file
[INFO] [ChannelService] Loaded 10 activity IDs from file
[INFO] [ChannelService] Loaded 17 approval status entries from file
[INFO] [ChannelService] Channel service initialized
[INFO] [Server] Health check endpoint available at http://localhost:3979/api/health
[INFO] @teams/app/http listening on port 3978 :rocket:
[INFO] [KeeperBot] ============================================================
[INFO] [KeeperBot] Starting Keeper Commander Teams Bot
[INFO] [KeeperBot] ============================================================
[INFO] [KeeperBot] Keeper Service Mode is accessible
[INFO] [KeeperBot] ============================================================
[INFO] [Server] Bot started, app listening on port 3978
[INFO] [Server] Configuration loaded from KSM: keeper, teams, pedm, deviceApproval
[INFO] [PedmPoller] Disabled in config
[INFO] [KeeperBot] EPM poller started
[INFO] [DevicePoller] Disabled in config
[INFO] [KeeperBot] Device approval poller started
```

***

### Step 7. Configure Messaging Endpoint

After the bot is deployed and running, you need to configure the messaging endpoint so Microsoft Teams can communicate with your bot.

1. Install and authenticate ngrok in the Linux VM

```bash
curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
  | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null \
  && echo "deb https://ngrok-agent.s3.amazonaws.com buster main" \
  | sudo tee /etc/apt/sources.list.d/ngrok.list
sudo apt update && sudo apt install -y ngrok
ngrok config add-authtoken <YOUR_NGROK_AUTH_TOKEN>
```

> Get your auth token from the [ngrok dashboard](https://dashboard.ngrok.com/get-started/your-authtoken). Reserve a static domain under **Domains** in the dashboard.

2. Start ngrok

```bash
ngrok http YOUR_BOT_PORT --domain=<YOUR_STATIC_DOMAIN>
```

3. Set the messaging endpoint in Azure
   1. Go to the [Azure Portal](https://portal.azure.com) → your **Azure Bot** resource
   2. Navigate to **Settings** → **Configuration**
   3. Set **Messaging endpoint** to: `https://<YOUR_STATIC_DOMAIN>/api/messages`
   4. Click **Apply**
4. **Verify**

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2F6bKkOUfblOy66uSfNGwa%2FScreenshot%202026-03-23%20at%201.32.14%E2%80%AFPM.png?alt=media&#x26;token=dc63f02b-0444-4e2b-94d6-d862296194d3" alt=""><figcaption></figcaption></figure>

```bash
curl https://<YOUR_STATIC_DOMAIN>/api/health
```

### Step 8. Upload Teams app package

In this section, After the Docker services are running, upload the Teams app package to your Microsoft Teams environment.

* Download the app package template from the [releases page](https://github.com/Keeper-Security/teams-integration)
* Extract the ZIP file, which contains:

  ```
  teams-integration/appPackage/
  ├── manifest.json
  ├── color.png
  └── outline.png
  ```
* Edit `manifest.json` and replace the placeholders:

  * Replace `${{TEAMS_APP_ID}}` with your **Azure Client ID** (from Step 1)

  eg:-

  <figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FjNzKZtCE879NMpVGfXV2%2FScreenshot%202026-03-24%20at%201.54.37%E2%80%AFPM.png?alt=media&#x26;token=8a09f241-3a19-470d-8412-781b8354ca4c" alt=""><figcaption></figcaption></figure>

  * Replace `${{BOT_ID}}` with your **Bot ID** (same Azure Client ID)

  eg:-

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FWNF9SUmADlgjmIEykWLF%2FScreenshot%202026-03-25%20at%2012.51.35%E2%80%AFAM.png?alt=media&#x26;token=342cb979-5ac3-4094-953f-62b5662aefec" alt=""><figcaption></figcaption></figure>

* Repackage the files into a ZIP:

```bash
cd /path/to/your/appPackage-folder
zip -j keeper-teams-app.zip manifest.json color.png outline.png
```

* Upload to Teams Admin Center:

  * Sign in to [Microsoft Teams Admin Center](https://teams.cloud.microsoft)
  * Navigate to **Teams apps** → **Manage apps**
  * Click **Upload an app** → Select Upload an app to your organization's app catalogue
  * Select your `keeper-teams-app.zip` file
  * then, click upload

  <figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FVS7Mn1ciJ35MitrnexaR%2FScreenshot%202026-03-23%20at%207.11.02%E2%80%AFPM.png?alt=media&#x26;token=126ce554-9c61-4088-83f8-a0caf678fcf0" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
**Troubleshooting:** If the upload fails with **"Something went wrong"**, you can enable the Teams channel directly from the terminal then upload the zip file again.

```bash
# Run this Command in the terminal
az login
az rest --method put \
  --url "https://management.azure.com/subscriptions/$(az account show --query id -o tsv)/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.BotService/botServices/<BOT_NAME>/channels/MsTeamsChannel?api-version=2022-09-15" \
  --body '{"location":"global","properties":{"channelName":"MsTeamsChannel","properties":{"isEnabled":true}}}'
```

Replace `<RESOURCE_GROUP>` with your Azure resource group name and `<BOT_NAME>` with your Azure Bot resource name.
{% endhint %}

* After upload the Zip file -> Install the App to Your Team

  * In Microsoft Teams, navigate to your team
  * Click **...** next to the team name → **Manage team**
  * Go to the **Apps** tab

  <figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FdCXf4WnsiJ4vDd05mYQ6%2FScreenshot%202026-03-24%20at%2012.28.51%E2%80%AFPM.png?alt=media&#x26;token=a838b3af-9fd0-4dea-b32c-ff74924ab4c3" alt=""><figcaption></figcaption></figure>

  * Click **More apps** (bottom right)

  <figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FrUtdbfFvkCRk5UCADyZX%2FScreenshot%202026-03-24%20at%2012.29.35%E2%80%AFPM.png?alt=media&#x26;token=6c2bcadf-7afd-4159-b76e-1b0937cbf8e1" alt=""><figcaption></figcaption></figure>

  * Search for **Keeper Security** and click open **with your approver team/channel.**

  Once the app is installed at the team level, the bot needs to be initialized in the approvals channel so it can route approval requests there.

  * It will auto-redirect you to channel or Navigate to the **keeper-vault-approvers** private channel.
  * Mention your bot name with this command, @keeper Security /channel-status.

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FYHmzgwNbixNm31zbzAqV%2FScreenshot%202026-03-24%20at%2012.30.11%E2%80%AFPM.png?alt=media&#x26;token=f9e8440f-070f-45fe-be5e-3d0a5eaecdab" alt=""><figcaption></figcaption></figure>

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2Fx0wplAbH9zqZGpwI2GTo%2FScreenshot%202026-03-24%20at%2012.22.20%E2%80%AFPM.png?alt=media&#x26;token=82c38615-c20d-4f50-a45f-59989a2814aa" alt=""><figcaption></figcaption></figure>

Thats it now end users can start raise requests.

***

### Command Reference for Requesting User

{% hint style="warning" %}
Important: Unlike Slack, where requests can be made from any channel or direct message, the Keeper Security Teams bot only accepts request commands in a **1:1 personal chat** with the bot. Commands sent in team channels, group chats, or direct messages with other users will not be processed.

To start a conversation with the bot:

1. Search for **Keeper Security** in the Teams search bar
2. Select the bot from the results
3. Send your command in the personal chat (e.g., `keeper-request-record "record" "justification"`)
   {% endhint %}

#### keeper-request-record

Request access to a specific Keeper record.

Syntax: &#x20;

```
keeper-request-record "record-uid-or-description" <justification>

Example:-
keeper-request-record kR3cF9Xm2Lp8NqT1uV6w Emergency server access
keeper-request-record "prod db EU region" Need to run migration
```

#### keeper-request-folder

Request access to a shared folder.

Syntax:

```
keeper-request-folder "folder-uid-or-description" <justification>

Example:-
keeper-request-folder kF8zQ2Nm5Wx9PtR3sY7a Need staging access
keeper-request-folder "Staging Team Folder" Need staging access
```

#### keeper-one-time-share

Request a one-time share link for a record.

Syntax:

```
keeper-one-time-share "record-uid-or-description" <justification>

Example:-
keeper-one-time-share kR3cF9Xm2Lp8NqT1uV6w Need to share with contractor John
keeper-one-time-share "AWS Production Password" Sharing with vendor
```

***

## Screenshots

The below screenshots demonstrate the core features of the Keeper Teams App.

#### Interacting with the Teams App bot for Requests (Requesting User View)

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2F4jn7V3vpyXd6hvFEhueg%2Fend-user-interaction.png?alt=media&#x26;token=125eed27-9b09-4da7-bbe1-79391ae1c1e5" alt=""><figcaption></figcaption></figure>

***

#### Requesting Access to a Record (no UID provided)

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FWYvIUJBLyurZ0obfPTN0%2FScreenshot%202026-02-27%20at%2011.49.03%E2%80%AFAM.png?alt=media&#x26;token=fc226305-3b3d-4b37-90fe-eed5076625ed" alt=""><figcaption></figcaption></figure>

***

#### Requesting Access to a Record with UID provided - (Admin View)

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FqGrZhRk6J6WnYqAejd2i%2FRecord%20access%20withj%20no%20UID.png?alt=media&#x26;token=eb7b94e3-24ec-4d40-9ace-395636b953a6" alt=""><figcaption></figcaption></figure>

***

#### Record Access Request - (Admin View)

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FAnbpsA6Uw5FDjn9w9WZz%2FRecord%20access%20approval%20card%20screen.png?alt=media&#x26;token=0c483441-af5a-4643-b7c6-41c665eadb9e" alt=""><figcaption></figcaption></figure>

***

#### Requesting Access to a Folder - After Approved (Admin View)

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2Fsr1txhemsTNnxcngRmQO%2FFolder%20access%20request%20approved%20screen.png?alt=media&#x26;token=c0b05ff4-7002-4bb9-b28e-67fc254cc017" alt=""><figcaption></figcaption></figure>

***

#### Folder Access Request  with UID- (Admin View)

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FfvkY4mkvAVUpYBNq7Txc%2Ffolder%20access%20request%20with%20uid.png?alt=media&#x26;token=ec8a8aae-3d73-4d25-a37b-f0f2e6e49069" alt=""><figcaption></figcaption></figure>

***

#### One-time Share Request - (Admin View)

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FvKOXX9ACBxWz8mW3ofDb%2FOne-time-share%20approval%20card%20screen.png?alt=media&#x26;token=d35d8a74-0de8-4faa-b654-adfd77ee11a5" alt=""><figcaption></figcaption></figure>

***

#### One-Time Share - Admin View with New Record Creation

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2Ffp4f2pGvxxqNfXxeK7EE%2FCreate-new-record-screen.png?alt=media&#x26;token=085b40b3-4a33-4698-887c-84bb18dc3603" alt=""><figcaption></figcaption></figure>

***

#### One-Time Share - Requesting User View with after approved

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FG42E3ne6kCLJSwcB33yh%2FOne-time-share%20approved%20screen(Requesting%20user%20view).png?alt=media&#x26;token=840dd10f-c40c-4463-be67-abe155368a1e" alt=""><figcaption></figcaption></figure>

***

#### Endpoint Privilege Manager - Approval for Elevation

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FdoRiaAJUhrUSNZKdyhRO%2FEPM%20request%20approval%20card%20screen.png?alt=media&#x26;token=4737c26e-6405-4632-be1c-1e1da3a66bef" alt=""><figcaption></figcaption></figure>

***

#### SSO Cloud Device Approval - Admin View

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FCXp8rBc5cNBqTN3EFDD2%2Fcloud-sso-device-approval%20request%20screen.png?alt=media&#x26;token=b8360753-fd2f-42b6-a594-164b7872a85a" alt=""><figcaption></figcaption></figure>

***

## Updates

#### Updating the Commander Service Mode and Teams app Container

To update to the latest version of Commander or the Teams App, follow the steps below to stop the service, update the containers and start up the new containers.

```bash
docker compose down
docker compose pull
docker compose up -d
```

***

## Troubleshooting

#### Startup Errors

<table><thead><tr><th>Error</th><th width="230.42578125">Cause</th><th>Solution</th></tr></thead><tbody><tr><td>Commander Service Mode is prompting for master password</td><td>Multiple config.json files are attached to the Vault record</td><td>Follow steps 4-5 to run the <code>teams-app-setup</code> command with new folder name again to create a new JSON config file. </td></tr><tr><td>[WARN] Warning: Cannot reach Keeper Service Mode</td><td>Service Mode not running or wrong URL</td><td>Verify the <code>service URL</code> in the vault record is as expected</td></tr><tr><td>BotFrameworkAdapter initialization failed</td><td>Invalid bot credentials</td><td>Verify <code>MICROSOFT_APP_ID</code> and <code>MICROSOFT_APP_PASSWORD</code></td></tr><tr><td>Azure AD authentication error</td><td>Invalid tenant or client credentials</td><td>Verify <code>AZURE_TENANT_ID</code>, <code>AZURE_CLIENT_ID</code>, and <code>AZURE_CLIENT_SECRET</code></td></tr></tbody></table>

***

#### Teams API Errors

| Error                      | Cause                                        | Solution                                               |
| -------------------------- | -------------------------------------------- | ------------------------------------------------------ |
| Conversation not found     | Invalid team or channel ID                   | Verify `TEAMS_TEAM_ID` and `TEAMS_CHANNEL_ID`          |
| Authorization denied (401) | Bot not properly configured or token expired | Regenerate client secret and update configuration      |
| Forbidden (403)            | Missing API permissions                      | Ensure Graph API permissions are granted admin consent |
| Channel not found          | Bot not added to channel                     | Add the bot to the approvals channel                   |
| Activity not found         | Message was deleted or activity ID invalid   | This may occur when updating old cards; can be ignored |

***

#### Service Mode Errors

| Error                              | Cause                                             | Solution                                                    |
| ---------------------------------- | ------------------------------------------------- | ----------------------------------------------------------- |
| Failed to submit command: HTTP 403 | API key invalid or missing                        | Verify api\_key in config vault record matches service mode |
| Failed to submit command: HTTP 404 | Wrong API endpoint version                        | Use V2 endpoint: /api/v2/ (not /api/v1/)                    |
| Failed to submit command: HTTP 405 | Using wrong HTTP method                           | Ensure Service Mode is running with queue enabled           |
| Command timed out or failed        | Service Mode overloaded or command not registered | Register command in Service Mode; increase timeout          |
| No request\_id received from API   | Service Mode not using queue/async mode           | Restart Service Mode with queue enabled (V2)                |

***

#### Access Grant Errors

| Error                                        | Cause                                              | Solution                                                                       |
| -------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------ |
| Record Not Found                             | Invalid UID or record deleted                      | Verify the record UID exists in Keeper vault                                   |
| Folder Not Found                             | Invalid folder UID                                 | Verify the folder UID exists in Keeper vault                                   |
| Invalid UID Type (record vs folder)          | Used wrong command for item type                   | Use `/keeper-request-folder` for folders, `/keeper-request-record` for records |
| This user already has time-limited access... | Conflict with existing share                       | Revoke existing access first, then grant new permission                        |
| Share permissions require permanent access   | Trying to use duration with Can Share/Edit & Share | Share permissions (Can Share, Edit & Share, Change Owner) are always permanent |
| User share...failed                          | Permission conflict on folder                      | User may have incompatible existing access; revoke and re-grant                |

***

#### Search & Modal Errors

| Error                                    | Cause                                   | Solution                                                                |
| ---------------------------------------- | --------------------------------------- | ----------------------------------------------------------------------- |
| No records found matching...             | Search query too specific or no matches | Try broader search terms; check record exists in vault                  |
| Search command timed out                 | Service Mode slow or vault very large   | Increase max\_wait in \_poll\_for\_result() or use more specific search |
| Error processing search modal submission | Modal data corrupted or expired         | Close modal and try again; check logs for specific error                |
| Modal shows "Searching..." forever       | Poll result never returned              | Check Service Mode logs; verify search command is registered            |

***

#### One-Time Share Errors

| Error                                                   | Cause                                   | Solution                                                             |
| ------------------------------------------------------- | --------------------------------------- | -------------------------------------------------------------------- |
| one-time share links can not be created for PAM records | Commander doesn't support               | Request for non-pam records                                          |
| Share link created but URL not found in response        | Unexpected Service Mode response format | Check Service Mode version; verify one-time-share command registered |
| Failed to create one-time share                         | Record may not be shareable             | Verify user has share permissions on the record                      |

***

#### Record Creation Errors

| Error                                         | Cause                                    | Solution                                                   |
| --------------------------------------------- | ---------------------------------------- | ---------------------------------------------------------- |
| Failed to create record                       | Missing required fields or command error | Ensure title, login, and password are provided             |
| Record created but UID could not be retrieved | Search after creation failed             | Record exists but search timed out; manually search for it |

***

#### KEPM Errors

| Error                               | Cause                                | Solution                                                                                                       |
| ----------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
| No data returned                    | KEPM feature not enabled             | Enable KEPM in your Keeper enterprise settings. Ensure that your service user has necessary admin permissions. |
| KEPM sync failed                    | Service Mode can't reach KEPM server | Check network connectivity and KEPM configuration                                                              |
| Failed to approve/deny KEPM request | Request may have expired             | Check if request is still pending; it may have auto-expired                                                    |

### References

* [Commander CLI Overview](https://docs.keeper.io/en/keeperpam/commander-cli)
* [Commander Service Mode](https://docs.keeper.io/en/keeperpam/commander-cli/service-mode-rest-api)
* [Endpoint Privilege Manager](https://docs.keeper.io/en/keeperpam/endpoint-privilege-manager)
* [SSO Connect Cloud](https://app.gitbook.com/s/-MB_i6vKdtG6Z2n6zWgJ/)
