# Gotchas — Permissions, Roles, Consent

## App identity

- **App ID (client_id):** `fabb3421-8b34-484b-bc17-e46de9703418`
- **Internal name (home tenant / registration):** Claude-MSP-Access
- **Display name in customer tenants:** **ComputerGuru - AI Remediation**
- **Client secret:** SOPS vault `msp-tools/claude-msp-access-graph-api.sops.yaml` -> field `credentials.credential`

When searching customer admin portals for the service principal (role assignments, app role assignments, conditional access exclusions), **search for "ComputerGuru - AI Remediation"** — not "Claude-MSP-Access".

## Per-tenant prerequisites

Graph API permissions alone are not enough. Most privileged operations require directory roles on the service principal *in that tenant*:

| Operation | Required directory role |
|---|---|
| Password reset, user property updates | User Administrator |
| Exchange REST (hidden inbox rules, mailbox permissions, SendAs, transport rules, Get-Mailbox) | Exchange Administrator |
| Conditional Access policy reads/writes | Conditional Access Administrator OR Security Administrator |
| Teams policies | Teams Administrator |

### How to assign a role to the SP in a customer tenant

1. Sign into the customer's Entra admin center as Global Admin:
 `https://entra.microsoft.com/#@{customer-domain}`
2. Identity -> Roles & admins -> All roles -> select the role (e.g., Exchange Administrator).
3. Add assignments -> search **"ComputerGuru - AI Remediation"** -> Assign (Active, permanent — service principals cannot activate eligible assignments).

## Admin consent

When you add new Graph scopes to the app manifest in the home tenant, each customer tenant must re-consent for those scopes to flow into tokens.

**Admin consent URL (per tenant):**

```
https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id=fabb3421-8b34-484b-bc17-e46de9703418&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient
```

- Customer admin must sign in as Global Admin of that tenant.
- The consent page lists all permissions in the current manifest; admin clicks Accept.
- Redirect lands on a blank Microsoft "native client" page that looks like an error — **that is normal**. Consent is recorded on Accept, not on redirect success.
- Verify consent took effect by checking `/servicePrincipals/{sp-id}/appRoleAssignments` — the timestamps on new grants should be `today`.

## Diagnosing "required scopes are missing"

Token returned 403 with `"required scopes are missing in the token"`:

1. Decode the JWT payload (2nd segment, base64url) and check the `roles` claim.
2. If the scope you expected is not in `roles`:
   - Confirm the scope is in the app's API permissions in the home tenant (not just selected in the picker — must be saved).
   - Grant admin consent in the home tenant.
   - Re-run the customer admin consent URL above.
3. If the scope IS in `roles` but you still get 403: check for a missing directory role (see table above).

## Diagnosing Exchange REST 403

- Invalid token scope: make sure you requested `https://outlook.office365.com/.default` (not the Graph scope).
- Missing Exchange Administrator role on the SP in that tenant.
- Propagation delay: newly assigned role can take up to 15 minutes to reach Exchange Online. If you just assigned it, wait and retry.

## Common, benign "failures" in sign-in logs

- `error 50140` "Keep me signed in interrupt" — KMSI prompt, not a real failure.
- `error 65001` "has not consented to use the application" — this fires during onboarding consent and when a user (or admin) signs in before granting consent. If the `appDisplayName` is **ComputerGuru - AI Remediation**, those are our own consent attempts, not attacker activity.
- `error 50126` from the sysadmin account during our onboarding is typo/retry noise — check `ipAddress` matches Mike's known IPs before flagging.

## Tenants where the app is already set up (as of 2026-04-16)

| Tenant | Tenant ID | Directory roles assigned | Notes |
|---|---|---|---|
| Valleywide Plastering | 5c53ae9f... | User Administrator | |
| Dataforth | 7dfa3ce8... | User Administrator, Exchange Administrator | |
| Cascades Tucson | 207fa277-e9d8-4eb7-ada1-1064d2221498 | User Administrator, Exchange Administrator | IdentityRiskyUser scope still not consented as of 2026-04-16 |
| Grabblaw | 032b383e-96e4-491b-880d-3fd3295672c3 | none | Consent broken (2026-03-31); Reyna needs full access to Jsosa mailbox |

Keep this table updated when you roll out to a new tenant.
