Skip to content

feat(microsoft): scaffold zero-config client_id + better setup error - #41

Merged
rrader26 merged 1 commit into
mainfrom
feat/microsoft-client-id-default
May 13, 2026
Merged

feat(microsoft): scaffold zero-config client_id + better setup error#41
rrader26 merged 1 commit into
mainfrom
feat/microsoft-client-id-default

Conversation

@rrader26

Copy link
Copy Markdown
Contributor

Summary

Two changes to make `createMicrosoftPlugin()` work zero-config once the ThinkFleet-owned Azure AD app is registered, and dramatically better UX in the meantime.

1. `THINKFLEET_DEFAULT_CLIENT_ID` placeholder

New constant in `auth.ts`, currently `''` — intentional placeholder. The resolution chain is already wired:

```
explicit config.clientId
→ AGENTMARK_MS_CLIENT_ID env var
→ THINKFLEET_DEFAULT_CLIENT_ID baked default
```

Filling in the constant later is a one-line PR (literally one string replacement). The hard work of getting the resolution order right is done now.

Why the placeholder isn't filled in yet: I can't register an Azure AD app under ThinkFleet's tenant — that requires Microsoft account credentials and admin access I don't have. The PR that fills in the real id will be ~3 lines: replace the empty string, bump the doc, ship.

⚠️ Constraint flagged in the code: never hardcode a tenant-specific client id. The default must be multi-tenant or zero-config falls apart for users on other tenants.

2. Actionable error message

Old:

Microsoft Graph client ID is not set. Register an Azure AD app...

New:
```
Microsoft Graph client ID is not set.

One-time setup:

  1. Open https://entra.microsoft.com → App registrations → New registration
  2. Account types: "Accounts in any organizational directory and
    personal Microsoft accounts"
  3. Authentication → Advanced settings → "Allow public client flows" → Yes
  4. API permissions → Add → Microsoft Graph → Delegated:
    Mail.Send, Mail.ReadWrite, Files.ReadWrite, offline_access, User.Read
  5. Grant admin consent

Then either:

  • Set AGENTMARK_MS_CLIENT_ID= in your environment, OR
  • Pass `clientId: ""` to createMicrosoftPlugin()
    ```

When this error fires (and it will, on every fresh install until #2 ships or the operator brings their own app), the human gets a working recipe instead of having to dig through docs.

Test plan

  • `pnpm build` clean
  • `pnpm test` — 491 pass / 10 skip (existing case-insensitive `/client ID is not set/` regex assertion still passes against the new message)
  • Follow-up PR once Azure AD app is registered: fill in `THINKFLEET_DEFAULT_CLIENT_ID` constant

🤖 Generated with Claude Code

… client id

Two changes to make createMicrosoftPlugin() work zero-config once the
ThinkFleet-owned Azure AD app is registered:

1. New constant `THINKFLEET_DEFAULT_CLIENT_ID` in auth.ts — currently
   empty string (intentional placeholder), but the resolution order is
   already wired up:

       explicit config.clientId
         → AGENTMARK_MS_CLIENT_ID env var
         → THINKFLEET_DEFAULT_CLIENT_ID baked default

   Filling in the constant later is a one-line PR.

2. Massively improved error message when client_id is missing. The old
   one was "Register an Azure AD app". The new one walks the user
   through the actual portal flow + the exact permission set they
   need to grant.

   ```
   Microsoft Graph client ID is not set.

   One-time setup:
     1. Open https://entra.microsoft.com → App registrations → New registration
     2. Account types: "Accounts in any organizational directory and
        personal Microsoft accounts"
     3. Authentication → Advanced settings → "Allow public client flows" → Yes
     4. API permissions → Add → Microsoft Graph → Delegated:
        Mail.Send, Mail.ReadWrite, Files.ReadWrite, offline_access, User.Read
     5. Grant admin consent

   Then either:
     - Set AGENTMARK_MS_CLIENT_ID=<your-app-id> in your environment, OR
     - Pass `clientId: "<your-app-id>"` to createMicrosoftPlugin()
   ```

   The first time an agent hits this error, the human gets a working
   recipe instead of having to dig through docs.

Constraint flagged in the code: NEVER hardcode a tenant-specific
client id. The default must be multi-tenant or zero-config falls
apart for users on other tenants.

Tests unchanged — the existing /client ID is not set/i regex assertion
still passes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rrader26
rrader26 merged commit ac13e6c into main May 13, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants