Files
claudetools/session-logs/2026-07/2026-07-01-mike-remediation-tool-sharepoint-access-bb-32492.md
Mike Swanson 7f897ce93f sync: auto-sync from GURU-5070 at 2026-07-01 13:09:08
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-07-01 13:09:08
2026-07-01 13:10:01 -07:00

11 KiB

User

  • User: Mike Swanson (mike)
  • Machine: GURU-5070
  • Role: admin

Session Summary

Continuation of the 2026-07-01 Peaceful Spirit session (deletion investigation + Admin1/Admin2 ACL hardening already saved to clients/peaceful-spirit/session-logs/2026-07/2026-07-01-mike-pst-deletion-scope-shelton-admin-acl.md, commit 6f676672). This log covers the work after that save: the Peaceful Spirit wiki full recompile, a Birth Biologic Syncro ticket, and a remediation-tool tooling+documentation fix that unblocks SharePoint access.

First, ran /wiki-compile client:peaceful-spirit --full — the article was stale (2026-06-04) and missing the June two-DC DFS rebuild, the deletion investigation, and the ACL work. Delegated synthesis to a Sonnet subagent (12 source logs + live Syncro data), reviewed the draft, fixed HTML-entity artifacts, staged + applied, updated the index. Committed e583bf43.

Second, handled Syncro ticket #32492 (Birth Biologic, "Setting for SharePoint", assigned Winter, converted from a lead). Annise Neidrich asked how to stop employees from creating SharePoint sites (the new "Discover/Publish/Build" nav worried Brandy) without losing the ability to edit their "Staff Portal" site. Diagnosed the underlying misconception: site creation and site editing are separate permissions. Investigated the tenant's live settings via the remediation-tool (read-only) and found both site-creation levers open.

Third — and the largest piece — resolved recurring remediation-tool friction. The Graph /admin/sharepoint/settings call returned accessDenied, which initially read as "no SharePoint access." Mike pushed back (certs are in the vault for a reason). Validated empirically by decoding each Graph tier's token roles claim: the Tenant Admin app holds Sites.FullControl.All (Graph AND SharePoint resource). The real blockers were (a) SharePoint app-only REJECTS client_secret tokens ("Unsupported app only token") and requires a CERTIFICATE, and (b) get-token.sh had no SharePoint resource tier. Proved cert-based SharePoint access end-to-end (REST + CSOM), then fixed the tooling: added sharepoint/sharepoint-admin tiers to get-token.sh (cert-forced, tenant resource auto-resolved), wrote a reference doc with the live per-tier permission map + gotchas + CSOM examples, updated SKILL.md, logged the friction, and saved a reference memory. Committed 6f7f939a.

Finally, posted the customer reply on #32492 as Mike (comment 421624836, customer-visible, emailed), then set the ticket to Waiting on Customer. Implementation of the actual lockdown is ready but gated on the client's go-ahead.

Key Decisions

  • Root-level (general) session log — this session spans harness tooling (remediation-tool) + Birth Biologic (a Syncro ticket) + a wiki rebuild; no single client/project owns it.
  • Validated app permissions by decoding the token roles claim rather than trusting the accessDenied — this is the authoritative source and disproved the "no access" read.
  • Added SharePoint tiers to get-token.sh instead of a one-off script — makes SharePoint a first-class, reusable capability of the remediation-tool, and cert-forces it so the secret gotcha can't recur. Auto-resolves the tenant-specific resource host via Graph /sites/root.
  • Documented the full per-tier permission map + the two SharePoint gotchas in a reference doc and a memory, with a "don't declare no-access without checking" discipline — the recurring friction was the point, not just this one ticket.
  • Answered #32492 in plain language (no CSOM/group-setting mechanics) — Annise is an ops consultant, not IT. Set Waiting on Customer since the fix needs her go-ahead.
  • Did NOT implement the site-creation lockdown — it's a tenant write to live client config; gated behind explicit client approval + a preview.

Problems Encountered

  • Graph /admin/sharepoint/settings accessDenied misread as "no SharePoint access." Root cause: no app holds SharePointTenantSettings.Read.All (that Graph route needs it), but the apps DO hold Sites.FullControl.All. Resolved by using the SharePoint CSOM/REST admin API instead of the Graph settings endpoint.
  • SharePoint REST/CSOM returned "Unsupported app only token" with a client_secret token. SharePoint Online requires certificate-based app-only tokens. Resolved by using the vault cert (client_assertion); proved with /_api/web/title -> "Tenant Administration".
  • get-token.sh had no SharePoint resource tier (all tiers map to Graph/EXO/Defender fixed scopes). Added sharepoint/sharepoint-admin; the SharePoint resource host is tenant-specific so it's resolved at runtime from Graph /sites/root (recursive get-token call), overridable via SP_RESOURCE_ENV.
  • Sonnet wiki draft HTML-escaped some chars (&/</>). Fixed in the staged file before applying; verified no entities and no raw secrets leaked.
  • get-token.sh reads the GLOBAL ~/.claude/identity.json (which lacks vault_path on this box); set VAULT_ROOT_ENV=D:/vault to point it at the vault. (Repo identity has vault_path; global does not.)

Configuration Changes

  • .claude/skills/remediation-tool/scripts/get-token.sh — added sharepoint and sharepoint-admin tiers (Tenant Admin app, cert-forced, tenant SharePoint resource auto-resolved from Graph /sites/root; SP_RESOURCE_ENV override). Added SP_KIND init + a resource-resolution block. Syntax-checked (bash -n).
  • .claude/skills/remediation-tool/references/app-permissions-and-sharepoint.md (NEW) — live-decoded per-tier application-permission map, the two SharePoint gotchas (cert requirement; Graph settings scope not held), CSOM/REST usage examples, and the "verify before declaring no-access" discipline.
  • .claude/skills/remediation-tool/SKILL.md — added the SharePoint tier rows + a prominent full-365-coverage note pointing at the new reference.
  • .claude/memory/reference_remediation_tool_365_access.md (NEW) + MEMORY.md index line.
  • wiki/clients/peaceful-spirit.md — full recompile (two-DC DFS, deletion investigation, ACL model, new Patterns). wiki/index.md — updated peaceful-spirit row + date (note: index later also updated by another machine's linter; left intact).
  • errorlog.md — one --friction entry (remediation-tool no-access-vs-cert).
  • Syncro #32492 — comment 421624836 posted (customer-visible, emailed); status -> Waiting on Customer.
  • No local vault changes.

Credentials & Secrets

  • No new credentials. Used the ComputerGuru Tenant Admin app (709e6eed-0711-4875-9c44-2d3518c47063, vault msp-tools/computerguru-tenant-admin.sops.yaml) — has BOTH client_secret and a certificate (cert_thumbprint_b64url + cert_private_key_pem_b64). SharePoint requires the cert, not the secret. Read-only Graph/SharePoint queries against Birth Biologic; no writes to the tenant.
  • Syncro API key: mike per-user token (skill-managed). No secrets exposed in the ticket.

Infrastructure & Servers

  • Birth Biologic M365 tenant: 19a568e8-9e88-413b-9341-cbc224b39145. SharePoint host birthbiologic.sharepoint.com (admin birthbiologic-admin.sharepoint.com).
    • SelfServiceSiteCreationDisabled = false (self-service site creation ENABLED).
    • M365 Group creation: unrestricted — GET /groupSettings returned 0 entries (no Group.Unified override) => default EnableGroupCreation = true.
    • AllowClassicPublishingSiteCreation = false; SharingCapability = 2 (external+guest).
  • remediation-tool per-tier app roles (decoded 2026-07-01):
    • investigator (bfbc12a4-...): Directory.Read.All, User.Read.All, Sites.Read.All, AuditLog.Read.All, Application.Read.All, Organization.Read.All, Policy.Read.All, Mail.Read, MailboxSettings.Read, BitlockerKey.Read.All, IdentityRisky* (some ReadWrite), UserAuthenticationMethod.Read.All.
    • user-manager (64fac46b-...): Directory.ReadWrite.All, Group.ReadWrite.All, User.ReadWrite.All, Device.ReadWrite.All, User.RevokeSessions.All, UserAuthenticationMethod.ReadWrite.All, Organization.Read.All.
    • tenant-admin (709e6eed-...): Application.ReadWrite.All, AppRoleAssignment.ReadWrite.All, RoleManagement.ReadWrite.Directory, Directory.ReadWrite.All, Policy.ReadWrite.ConditionalAccess, Sites.FullControl.All, Sites.ReadWrite.All (Graph) + Sites.FullControl.All (SharePoint resource 00000003-0000-0ff1-ce00-000000000000), User.ReadWrite.All, SecurityEvents.Read.All.

Commands & Outputs

  • Decode a tier's granted app permissions: bash get-token.sh <tenant> <tier> then base64url-decode the JWT payload middle segment and read .roles.
  • SharePoint token (cert): bash .claude/skills/remediation-tool/scripts/get-token.sh <tenant> sharepoint-admin -> aud 00000003-0000-0ff1-ce00-000000000000, roles ["Sites.FullControl.All"]. curl /_api/web/title -> {"value":"Tenant Administration"}.
  • Read tenant settings: CSOM POST <admin>/_vti_bin/client.svc/ProcessQuery with the Tenant object constructor TypeId {268004ae-ef6b-4e9b-8425-127220d84719} + SelectAllProperties. (Secret token => "Unsupported app only token"; cert token => full property set.)
  • Graph group-creation check: GET /groupSettings (empty value array = defaults = anyone can create).
  • Syncro comment: POST /tickets/113276544/comment (jq-built body, <br> line breaks, hidden:false, do_not_email:false) -> comment 421624836. Status PUT {"status":"Waiting on Customer"}.
  • VAULT_ROOT_ENV=D:/vault required for get-token.sh on this box (global identity.json lacks vault_path).

Pending / Incomplete Tasks

  1. #32492 (Birth Biologic) — Waiting on Customer. On Annise's go-ahead, implement the lockdown (preview + explicit YES): (a) SelfServiceSiteCreationDisabled=true via sharepoint-admin tier CSOM SetProperty; (b) restrict M365 Group creation to an approved security group via user-manager (Graph Group.Unified directory setting). Neither affects Staff Portal edit rights.
  2. Optional Graph parity: add SharePointTenantSettings.Read.All/.ReadWrite.All to the Tenant Admin app so the Graph /admin/sharepoint/settings route works too (currently CSOM-only). Uses patch-tenant-admin-manifest.sh + re-consent.
  3. Carryover from the Peaceful Spirit thread (see the peaceful-spirit log): ~3,342-file deletion copy-back (awaiting Mara go), Shelton notes (year-ago restore point purged), PST-SERVER2 flapping diagnosis, ~200 GB PST-Recovery staging cleanup.

Reference Information

  • Syncro #32492 id 113276544; Birth Biologic customer 17983014; assigned Winter (1737); comment 421624836.
  • Commits this save-window: e583bf43 (wiki peaceful-spirit), 6f7f939a (remediation-tool docs+fix). Earlier this session: 6f676672 (peaceful-spirit deletion log).
  • Reference doc: .claude/skills/remediation-tool/references/app-permissions-and-sharepoint.md.
  • Memory: .claude/memory/reference_remediation_tool_365_access.md.
  • SharePoint Tenant CSOM TypeId: {268004ae-ef6b-4e9b-8425-127220d84719}. SharePoint resource appId: 00000003-0000-0ff1-ce00-000000000000.