sync: auto-sync from GURU-5070 at 2026-07-06 13:43:08

Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-07-06 13:43:08
This commit is contained in:
2026-07-06 13:43:38 -07:00
parent 3cc9b22594
commit b20985d241
5 changed files with 368 additions and 221 deletions

View File

@@ -0,0 +1,105 @@
## User
- **User:** Mike Swanson (mike)
- **Machine:** GURU-5070
- **Role:** admin
## Session Summary
Birth Biologic reported (warranty) that users "can no longer move files within SharePoint" — Move/Copy
options greyed out and drag-drop silently failing. Investigated the migrated Quality library and
confirmed Mike's hypothesis: **every migrated folder/file is authored by `SharePoint App`** (the app-only
service principal that ran the Datto->SharePoint Graph/SPMT uploads) — there is no human owner on any of
it. By contrast, a folder a real user created (`Quality General`, author **Julie Beck**) is normal and
movable. This is the whole problem: SharePoint disables Move/Copy/Rename on items whose author is a
system/app account, so users can manage their own content but not the app-migrated content.
Ruled out the other candidate causes via Graph and (once authenticated correctly) SharePoint REST:
**no retention/records labels** on the items; **library `ForceCheckout=false`** and **`EnableModeration=false`**
(no require-checkout, no content approval); **no files checked out** (`CheckoutUserId` null on all sampled
items); and **inheritance is intact** with the **Members group granted `write`** — the Quality staff (Julie
Beck, Brandy Burgess, Mary Ster, Vicki Fountain, Alicia Meneely, Kristin Steen + sysadmin/operations) are
all Members, so they *have* Edit. That leaves the app authorship as the sole cause.
The investigation stalled twice on SharePoint access before landing on the correct method. Using the
Tenant Admin app's **client_secret** against SharePoint REST returned `Unsupported app only token`; I
initially (wrongly) concluded app-only SP REST was blocked and wrote a memory saying to fall back to
delegated/PnP. Mike corrected this: the app suite has a dedicated SharePoint tier — SharePoint app-only
**requires the certificate, not the secret**. Minting via `get-token.sh birthbiologic.com sharepoint`
produced a cert token with `roles=["Sites.FullControl.All"]` and SP REST worked immediately. Rewrote the
memory to the correct cert-based guidance.
The fix was scoped but not yet executed (awaiting Mike's go + target-owner decision): re-stamp
`Author`/`Editor` on the app-owned items to a real user via cert-based CSOM `SystemUpdate` (SystemUpdate
so it does not bump Modified dates — matters for a QMS/compliance library), test on one folder, have a
Quality user confirm Move works, then run across all migrated libraries (Quality, Admin, Donor Services,
Supply — all migrated the same way, so all affected). Mike also raised standardizing all M365 app-only
auth on cert (recommended — cert is resource-agnostic and kills the secret-vs-cert friction).
## Key Decisions
- **Diagnosis = app/System-Account authorship**, not permissions/checkout/retention — all three ruled out
with live data; the `SharePoint App` vs `Julie Beck` author contrast is the tell.
- **Fix via CSOM `SystemUpdate`** (not a plain REST MERGE) to preserve Modified dates on QMS records.
- **Do not bulk-run yet** — test-on-one + user confirmation first; this is a live client library.
- **Recommend cert-only for all M365 app-only tasks** — a cert works for Graph/EXO too, is MS best
practice, and removes the secret-vs-cert branching that wasted time this session.
## Problems Encountered
- **Used the client_secret for SharePoint** -> `Unsupported app only token`; wrongly concluded "no app-only
SP access" and wrote a misleading memory. Correct method: the **cert** tier via
`get-token.sh <tenant> sharepoint` (`Sites.FullControl.All`). Memory rewritten; logged as a correction.
- **Group lookup by `Quality Systems Department` returned empty first** because I filtered on an assumed
rename; the group is still named `Quality Systems Department`. Re-queried with `startswith(displayName,'Quality')`.
- **`/tmp` path tripped the block-tmp-path hook** on a Bash call (Git-Bash `/tmp` mismatch); reran with a
scratchpad path.
## Configuration Changes
- No changes to the BirthBio tenant/SharePoint yet (investigation only; the re-author fix is pending go).
- Repo: rewrote `.claude/memory/reference_m365_app_sharepoint_rest_vs_graph.md` (secret->cert correction) +
updated its `MEMORY.md` index line. Added this session log. (BUG-024/musl log from earlier today is separate.)
## Credentials & Secrets
- No new secrets. SharePoint access = **Tenant Admin app CERT** (vault `msp-tools/computerguru-tenant-admin.sops.yaml`:
`cert_thumbprint_b64url` + `cert_private_key_pem_b64`), minted by remediation-tool `get-token.sh <tenant> sharepoint`.
The app's `client_secret` (same entry) is Graph/EXO only — rejected by SharePoint.
- **Gap flagged:** BirthBio's `sysadmin@birthbiologic.com` **M365** password is NOT in the SOPS vault (only the
Google Workspace one is, `clients/birth-biologic/google-workspace.sops.yaml`). Mike says the M365 sysadmin
creds are in **1Password** for BirthBio. Not needed for the fix (cert tier suffices), but worth vaulting.
## Infrastructure & Servers
- **Tenant:** birthbiologic.com / `19a568e8-9e88-413b-9341-cbc224b39145`.
- **Tenant Admin app:** `709e6eed-0711-4875-9c44-2d3518c47063` (secret = Graph/EXO; CERT = SharePoint `Sites.FullControl.All`).
- **QSD site:** `https://birthbiologic.sharepoint.com/sites/QualitySystemsDepartment`; site id `3173c017-58bd-406a-8858-2c969667336f`;
drive `b!F8BzMb1YakCIWCyWlmczb09LHqtxDxVMpLT6kAwYmsM7NUY4oPLSRq7ng3tJq-E9`.
- **QSD M365 group:** `QualitySystemsDepartment@birthbiologic.com`, id `166dbc15-f60b-4dfc-9581-236980032da4`;
Members (=site Edit): sysadmin, Julie Beck, Brandy Burgess, Mary Ster, Vicki Fountain, Alicia Meneely, Kristin Steen, Operations.
- **Documents library:** `ForceCheckout=false`, `EnableModeration=false`, `EnableVersioning=true`, `EnableMinorVersions=false`.
## Commands & Outputs
- Mint SP cert token: `cd .claude/skills/remediation-tool && bash scripts/get-token.sh birthbiologic.com sharepoint`
-> token roles `["Sites.FullControl.All"]`. (`sharepoint-admin` tier = the `-admin.sharepoint.com` resource.)
- Ownership (Graph): `GET /drives/{drive}/root/children?$select=name,createdBy,lastModifiedBy` -> all `SharePoint App`.
- Author contrast (SP REST): `GET .../lists/getbytitle('Documents')/items?$select=FileLeafRef,CheckoutUserId,Author/Title,Editor/Title&$expand=Author,Editor`
-> migrated = `SharePoint App`, `Quality General` = `Julie Beck`; `CheckoutUserId` null throughout.
- Secret-vs-cert: SP REST with the **secret** token -> `Unsupported app only token`; with the **cert** token -> works.
## Pending / Incomplete Tasks
- **Execute the fix (warranty):** re-stamp `Author`/`Editor` on app-owned items to a real user via cert CSOM
`SystemUpdate`. **Decision needed from Mike:** target owner (`sysadmin@` neutral, or a Quality lead like
Julie/Brandy). Test one folder -> Quality user confirms Move -> bulk across Quality, Admin, Donor Services, Supply.
- **Cert-only standardization (follow-up):** switch `get-token.sh` to cert-first for every tier; register the
cert on any secret-only apps; retire secrets. Prevents this recurring.
- **Vault the BirthBio `sysadmin@` M365 password** (currently only in 1Password).
## Reference Information
- Authoritative SP access doc: `.claude/skills/remediation-tool/references/app-permissions-and-sharepoint.md` + `app-suite.md`.
- Memory: `.claude/memory/reference_m365_app_sharepoint_rest_vs_graph.md` (corrected to cert).
- Wiki: `wiki/clients/birth-biologic.md` (File Storage / SharePoint Site Map; QSD site+drive IDs already recorded there).
- Symptom class: greyed-out Move/Copy/Rename + silent drag-drop fail on items authored by `SharePoint App`/`System Account`.