> For the complete documentation index, see [llms.txt](https://docs.dorg.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dorg.pro/install-dorg/maintenance/rotate-entra-id-app-registration-secrets.md).

# Rotate Entra ID App Registration secrets

Operational guide to renew the client secrets of the three DORG App Registrations and propagate them to Container Apps and Keycloak **without** running a full deploy.

Secrets created by the `apps/entra` stack expire after **2 years** (Microsoft Graph `addPassword` default). Create new secrets and update consumers before expiry.

### App Registration → consumers

| App Registration            | Consumer                            | Where it is used                                                          |
| --------------------------- | ----------------------------------- | ------------------------------------------------------------------------- |
| **DorgGraphAuth**           | Container App **orchestrator**      | [ACA ](#user-content-fn-1)[^1]secret `teams-authentication-client-secret` |
| **DorgGraphAuth**           | Container App **dashboard-gateway** | ACA secret `dashboard-graph-client-secret`                                |
| **DorgKeycloakEntraBroker** | **Keycloak** (IdP `entra-id`)       | Client secret of the Microsoft / Entra Identity Provider (Admin UI)       |
| **DorgMetricsCollector**    | Container App **dashboard-gateway** | ACA secret `dashboard-ai-secret`                                          |

### Prerequisites

* Entra ID access with permission to manage App Registrations (e.g. Application Administrator).
* **Contributor** (or equivalent) on the Container Apps resource group.
* Keycloak admin credentials (realm `master`), typically:
  * username: `KC_BOOTSTRAP_ADMIN_USERNAME` on the Keycloak Container App
  * password: ACA secret `keycloak-admin-password`
* Public Keycloak URL: `https://auth.<DNS_BASE_DOMAIN>` (e.g. `https://auth.david.mycompany.com`).
* Realm name: usually `DORG_USER_EMAIL` with `@` replaced by `-` (e.g. `user@company.com` → `user-company.com`).

### Recommended procedure (overlap, no downtime)

1. Create **new** secrets in Entra (keep the old ones active).
2. Update Container Apps and Keycloak with the new values.
3. Verify Entra SSO login, Teams/Graph, and Console (costs / Azure AI).
4. Only after verification, **delete** the old secrets from Entra.
5. Also update `.env` (and/or Pulumi config) so later deploys do not restore expired values.

***

### 1. Create new secrets in Entra ID

For **each** of the three apps (`DorgGraphAuth`, `DorgKeycloakEntraBroker`, `DorgMetricsCollector`):

1. Open [Microsoft Entra admin center](https://entra.microsoft.com) → **Identity** → **Applications** → **App registrations** → **All applications**.
2. Open the app (search by display name).
3. **Certificates & secrets** → **Client secrets** → **New client secret**.
4. Set a description (e.g. `dorg-rotate-2026-08`) and expiry (typical max: 24 months).
5. **Add**, then copy the **Value** immediately (shown only once).

Store the three values securely until the procedure is finished.

If several DORG installations share the same App Registration, propagate the new secret to **every** instance (each resource group / Container Apps set).

***

### 2. Update Container Apps

ACA names depend on the stack identifier (typical prefixes: `orchestrator-…`, `dashboard-gw-…`). In the Portal: Resource Group → **Container Apps**.

#### 2.1 Orchestrator — **DorgGraphAuth** secret

**Azure Portal**

1. Open the **orchestrator** Container App.
2. **Containers** → edit / **Edit and deploy** (or **Secrets**, depending on the UI).
3. In **Secrets**, update `teams-authentication-client-secret` with the new **DorgGraphAuth** secret.
4. Create a new revision and wait until it is Healthy.

**Azure CLI**

```bash
az containerapp secret set \
  --name <orchestrator-app-name> \
  --resource-group <resource-group> \
  --secrets teams-authentication-client-secret="<NEW_DORGGRAPHAUTH_SECRET>"
```

If the revision does not pick up the secret change on its own:

```bash
az containerapp revision restart \
  --name <orchestrator-app-name> \
  --resource-group <resource-group> \
  --revision <active-revision-name>
```

#### 2.2 Dashboard Gateway — **DorgGraphAuth** secret (Graph)

```bash
az containerapp secret set \
  --name <dashboard-gw-app-name> \
  --resource-group <resource-group> \
  --secrets dashboard-graph-client-secret="<NEW_DORGGRAPHAUTH_SECRET>"
```

Use the **same** new **DorgGraphAuth** secret as on the orchestrator.

#### 2.3 Dashboard Gateway — **DorgMetricsCollector** secret

```bash
az containerapp secret set \
  --name <dashboard-gw-app-name> \
  --resource-group <resource-group> \
  --secrets dashboard-ai-secret="<NEW_DORGMETRICSCOLLECTOR_SECRET>"
```

You can update both gateway secrets in one call:

```bash
az containerapp secret set \
  --name <dashboard-gw-app-name> \
  --resource-group <resource-group> \
  --secrets \
    dashboard-graph-client-secret="<NEW_DORGGRAPHAUTH_SECRET>" \
    dashboard-ai-secret="<NEW_DORGMETRICSCOLLECTOR_SECRET>"
```

Then confirm the active **dashboard-gateway** revision is Healthy.

***

### 3. Update Keycloak (Admin UI) — **DorgKeycloakEntraBroker** secret

This updates the OIDC IdP `entra-id` used for Microsoft / Entra login.

1. Open the Keycloak **Admin Console** (typical URL: `https://auth.<mydorgdomain>/admin/`, or the Administration Console link on the welcome page).
2. Sign in with the **`master`** realm admin (bootstrap admin from deploy).
3. In the top-left realm selector, switch to the DORG instance **realm** (do not stay on `master`; e.g. `user-company.com`).
4. Side menu: **Identity providers**.
5. Open the **Microsoft** provider / alias **`entra-id`** (OIDC).
6. In the client credentials section:
   * **Client ID**: leave unchanged (must remain the **DorgKeycloakEntraBroker** Client ID).
   * **Client secret**: paste the **new** secret created in Entra for **DorgKeycloakEntraBroker**.
7. **Save**.

#### Verify SSO

1. Open a private browser session.
2. Go to the Console or any login endpoint that uses Entra SSO.
3. Complete sign-in with a tenant user.
4. If you see `AADSTS7000215` / “Invalid client secret”, Keycloak still has the wrong secret: recheck step 7.

***

### 4. Persist values for future deploys

Also update the installer / deploy machine `.env` (and any Pulumi overrides). Otherwise a later deploy may republish old secrets on Container Apps:

| `.env` variable                             | App Registration        |
| ------------------------------------------- | ----------------------- |
| `TEAMS_AUTHENTICATION_CLIENT_SECRET`        | DorgGraphAuth           |
| `REALM_ENTRA_IDP_CLIENT_SECRET`             | DorgKeycloakEntraBroker |
| `DASHBOARD_GRAPH_CLIENT_SECRET` (if used)   | DorgGraphAuth           |
| `DASHBOARD_AZUREAI_CLIENT_SECRET` (if used) | DorgMetricsCollector    |

If you use the Pulumi `entra` stack with `existing*ClientId`, a new `pulumi up` of that stack may create **additional** additive passwords on the App Registration. Prefer the manual rotation described here, or explicitly align consumers to the secret exported by the latest entra run.

***

### 5. Cleanup in Entra

After successful tests:

1. Return to each App Registration → **Certificates & secrets**.
2. Delete the **old** client secrets (expired or replaced).
3. Leave only the secret now in production (and any secrets still used by other shared DORG instances).

***

### Troubleshooting

| Symptom                                        | Likely cause                                      | Action                                                                |
| ---------------------------------------------- | ------------------------------------------------- | --------------------------------------------------------------------- |
| `AADSTS7000215` / wrong client secret at login | Keycloak or Container App still on the old secret | Re-align Admin UI / ACA secret; wait for new revision                 |
| SSO OK but Console costs / Azure AI fails      | `dashboard-ai-secret` not updated                 | Update **DorgMetricsCollector** secret on dashboard-gateway           |
| Teams / Leonardo callback fails                | Orchestrator still on old GraphAuth secret        | Update `teams-authentication-client-secret`                           |
| After deploy Keycloak “reverts”                | Should not: realm import is ignore-existing       | If the realm was recreated from scratch, reset the IdP in Admin UI    |
| Multiple DORGs on the same tenant              | Shared secret on the App Registration             | Propagate the new secret to all instances before deleting the old one |

[^1]: Azure Container Application


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.dorg.pro/install-dorg/maintenance/rotate-entra-id-app-registration-secrets.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
