> ## Documentation Index
> Fetch the complete documentation index at: https://docs.valedo.uniwave.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Entra app registrations

> App IDs, identifier URIs and configuration values of the deployed Valedo app registrations and GitHub deployment identities.

These values were printed by `infra/entra-deployment-{env}.sh` (see [Deployment → Entra app registrations](https://docs.valedo.uniwave.ai/developers/deployment.md#entra-app-registrations)). App IDs and the tenant ID are identifiers, not secrets. They stay the same on redeploy because the script matches registrations by `uniqueName`.

Publisher tenant ID (both environments): `ed5c1757-0275-4beb-a5ea-072c938da4e2`

## dev

| Registration | `uniqueName` | App (client) ID | Identifier URI |
| - | - | - | - |
| Valedo (dev) | `valedo-dev` | `beb8f931-a493-4612-bf8f-7e7c4ae6364f` | `api://dev.valedo.uniwave.ai/beb8f931-a493-4612-bf8f-7e7c4ae6364f` |
| Valedo Marketplace (dev) | `valedo-marketplace-dev` | `11e33e28-8a3e-4f01-9e22-fa400dc13c4a` | — |
| Valedo Publisher Console (dev) | `valedo-publisher-dev` | `60edfa44-ceb7-4c87-852d-1552cdb4221e` | `api://60edfa44-ceb7-4c87-852d-1552cdb4221e` |

Customer tenant admin consent (sent by the onboarding flow):

```text theme={null}
https://login.microsoftonline.com/{customer-tenant-id}/v2.0/adminconsent?client_id=beb8f931-a493-4612-bf8f-7e7c4ae6364f&scope=https://graph.microsoft.com/.default&redirect_uri={adminConsentRedirectUri}
```

## prod

| Registration | `uniqueName` | App (client) ID | Identifier URI |
| - | - | - | - |
| Valedo | `valedo-prod` | `d6729f24-e55f-414f-ad25-c433d8b3f383` | `api://valedo.uniwave.ai/d6729f24-e55f-414f-ad25-c433d8b3f383` |
| Valedo Marketplace | `valedo-marketplace-prod` | `3ff75e6e-b726-40f5-a442-a019d18a8e6f` | — |
| Valedo Publisher Console | `valedo-publisher-prod` | `4e042c3f-aab0-49fb-aa04-ffe32737f667` | `api://4e042c3f-aab0-49fb-aa04-ffe32737f667` |

Customer tenant admin consent (sent by the onboarding flow):

```text theme={null}
https://login.microsoftonline.com/{customer-tenant-id}/v2.0/adminconsent?client_id=d6729f24-e55f-414f-ad25-c433d8b3f383&scope=https://graph.microsoft.com/.default&redirect_uri={adminConsentRedirectUri}
```

## Registration settings

What `infra/entra.bicep` configures on each registration. The purpose of each app and the credential decision are in README §4.7.

| Setting | `Valedo` | `Valedo Marketplace` | `Valedo Publisher Console` |
| - | - | - | - |
| `signInAudience` | `AzureADMultipleOrgs` | `AzureADMyOrg` | `AzureADMyOrg` |
| Identifier URI | `api://valedo.uniwave.ai/<appId>` (dev: `api://dev.valedo.uniwave.ai/<appId>`; falls back to `api://<appId>` while the domain is not verified) | none | `api://<appId>` |
| Access token version | 2 | 2 | 2 |
| Exposed scope | `access_as_user` (admins and users can consent) | none | `access_as_user` (admin consent only) |
| Pre-authorized clients | `ea5a67f6-b6f3-4338-b240-c655ddc3cc8e` (all Office endpoints, legacy Office SSO) | — | — |
| App roles (`allowedMemberTypes: User`) | `Valedo.Admin`, `Valedo.User` | — | `Valedo.Publisher.Admin`, `Valedo.Publisher.Support`, `Valedo.Publisher.Finance` |
| SPA redirect URIs | `brk-multihub://valedo.uniwave.ai` (nested app authentication), `https://admin.valedo.uniwave.ai`, localhost for dev | — | `https://console.valedo.uniwave.ai`, localhost for dev |
| Web redirect URI | admin-consent callback of the onboarding flow | — | — |
| Graph delegated permissions | `openid`, `profile`, `offline_access`, `User.Read` | — | `openid`, `profile`, `offline_access`, `User.Read` (tenant-wide grant) |
| Graph application permissions | `User.Read.All`, `GroupMember.Read.All` (README §4.6 Spike; parameter) | — | — |
| Assignment required on the service principal | **No** — every mailbox user must get add-in tokens | — | **Yes** — only staff with a `Publisher.*` role sign in |
| Credential | prod: client secret in Key Vault `valedo-client-secret` (interim); dev: none; target: federated (managed identity) or certificate | prod: client secret in Key Vault `valedo-marketplace-client-secret` (interim); dev: none; target: federated (managed identity) or certificate | none (SPA + bearer-only API) |

Scope and app-role IDs are deterministic (`guid()` of app, environment and value) and must never change once issued; Graph permission IDs are looked up from the Graph service principal at deploy time, not hard-coded.

## Where the values go

The Entra deployment (`infra/entra-deployment-{env}.sh` / `.ps1`, also run by `deploy.yml`) writes these values as `AzureAd__*` app settings of the environment's two web apps, merged with their other settings, so App Service needs no manual configuration. Locally, set them as user secrets (below).

| Setting | Valedo.API (`src/Valedo.Api`) | Publisher API (`src/Valedo.Publisher.Api`) |
| - | - | - |
| `AzureAd:Instance` | `https://login.microsoftonline.com/` | `https://login.microsoftonline.com/` |
| `AzureAd:TenantId` | `organizations` (multi-tenant) | Publisher tenant ID |
| `AzureAd:ClientId` | Valedo app ID | Publisher Console app ID |
| `AzureAd:Audience` | Valedo identifier URI | Publisher identifier URI |

### Client secrets

In prod, the `Valedo` and `Valedo Marketplace` apps have a client secret, stored only in that environment's Key Vault ([Deployment → Client secrets](https://docs.valedo.uniwave.ai/developers/deployment.md#client-secrets)). Dev has none: its apps have no client secrets and `uw-kv-valedo-weu-dev` holds none. Reference prod secrets from App Service or Functions settings with a versionless Key Vault reference, never copy the value.

| Environment | Key Vault | `Valedo` secret | `Valedo Marketplace` secret |
| - | - | - | - |
| dev | `uw-kv-valedo-weu-dev` | none | none |
| prod | `uw-kv-valedo-weu` | `valedo-client-secret` | `valedo-marketplace-client-secret` |

Example setting value for prod: `@Microsoft.KeyVault(SecretUri=https://uw-kv-valedo-weu.vault.azure.net/secrets/valedo-client-secret)`.

The Marketplace app ID goes into Partner Center (technical configuration of the SaaS offer) and into the webhook token validation settings `MarketplaceWebhook__TenantId` and `MarketplaceWebhook__AppId` of Valedo.API (set by `infra/entra.bicep`). The Worker calls the Fulfillment API as this app without a secret: its user-assigned identity `{prefix}-id-worker-valedo-…` is a federated credential of the app (added by the Entra deployment), and the settings are `Marketplace__TenantId`, `Marketplace__ClientId` (written by `infra/entra.bicep`) and `Marketplace__ManagedIdentityClientId` (written by `infra/modules/functions.bicep`). Locally there is no managed identity and dev has no secrets, so the Worker runs its other jobs and Marketplace events wait; to test the Fulfillment calls locally, use an app with a secret in `Marketplace__ClientSecret` in `local.settings.json` (never committed). Add the values to the Postman environments and the SPA settings of the portals too.

### Local development (user secrets)

Locally, both APIs use the **dev** registrations from .NET user secrets (`UserSecretsId` `valedo-api` and `valedo-publisher-api`), which override `appsettings.Development.json`:

```bash theme={null}
dotnet user-secrets set "AzureAd:Instance" "https://login.microsoftonline.com/" --project src/Valedo.Api
dotnet user-secrets set "AzureAd:TenantId" "organizations" --project src/Valedo.Api
dotnet user-secrets set "AzureAd:ClientId" "beb8f931-a493-4612-bf8f-7e7c4ae6364f" --project src/Valedo.Api
dotnet user-secrets set "AzureAd:Audience" "api://dev.valedo.uniwave.ai/beb8f931-a493-4612-bf8f-7e7c4ae6364f" --project src/Valedo.Api

dotnet user-secrets set "AzureAd:Instance" "https://login.microsoftonline.com/" --project src/Valedo.Publisher.Api
dotnet user-secrets set "AzureAd:TenantId" "ed5c1757-0275-4beb-a5ea-072c938da4e2" --project src/Valedo.Publisher.Api
dotnet user-secrets set "AzureAd:ClientId" "60edfa44-ceb7-4c87-852d-1552cdb4221e" --project src/Valedo.Publisher.Api
dotnet user-secrets set "AzureAd:Audience" "api://60edfa44-ceb7-4c87-852d-1552cdb4221e" --project src/Valedo.Publisher.Api
```

Check with `dotnet user-secrets list --project <project>`.

## GitHub deployment identities

Used by `.github/workflows/deploy-environment.yml` through OpenID Connect; each has one federated credential with subject `repo:uab-uniwave@129962912/Valedo@1440127505:environment:{env}` and no client secret. The organization issues OIDC subjects with immutable owner and repository IDs, so the plain `repo:uab-uniwave/Valedo:…` form fails with `AADSTS700213`. The client IDs are the `AZURE_CLIENT_ID` and `AZURE_INFRA_CLIENT_ID` variables of the GitHub environment ([Environment variables](https://docs.valedo.uniwave.ai/developers/deployment.md#environment-variables)).

| Registration | Environment | Client ID | Access |
| - | - | - | - |
| `github-valedo-deploy-dev` | dev | `668feadd-5979-475f-a4c5-b4cc7ad61fc4` | Website Contributor on `uw-app-valedo-weu-dev` and `uw-app-publisher-valedo-weu-dev` |
| `github-valedo-infra-dev` | dev | `d1c34bb2-bf88-4740-940d-e1926252d844` | Contributor and Role Based Access Control Administrator on `uw-rg-valedo-weu-dev`; Graph `Application.ReadWrite.All`, `DelegatedPermissionGrant.ReadWrite.All` |
| `github-valedo-deploy-prod` | prod | `7e9f7360-e06c-4615-b78f-1e37551142b8` | Website Contributor on `uw-app-valedo-weu` and `uw-app-publisher-valedo-weu` |
| `github-valedo-infra-prod` | prod | `9bba0cda-47aa-4e33-b6d1-fb85b6ea5b69` | Contributor and Role Based Access Control Administrator on `uw-rg-valedo-weu`; Graph `Application.ReadWrite.All`, `DelegatedPermissionGrant.ReadWrite.All` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.