# Access, governance and AI readiness

Rules behind ACC01 to ACC06 and USE01 for admins, the AI connection inventory, and the seven AI readiness checks.

## Admin band (ACC01)

Count company-held top-level admins per critical tool: enabled accounts on a company domain, excluding shared logins.

- 0: FAIL. Nobody inside the company can recover the tool.
- 1: WARN, and FAIL when the tool is a system of record (`system_of_record_for` set). One person is a single point of failure.
- 2 to 4: PASS.
- 5 or more: WARN. Each extra admin is another account that can change everything.

The band is borrowed, not invented for marketing tools. Microsoft's guidance for Entra roles recommends fewer than five Global Administrators and two cloud-only emergency access accounts (page dated 2026-06-01). The CIS Microsoft 365 Foundations Benchmark v4.0.0 (recommendation 1.1.3) asks for more than one and no more than four Global Administrators; Prowler implements it as a Microsoft 365 check, while its Azure check flags 5 or more (checked 2026-11-02). A reviewer may adjust the band in `metrics.md`; the report states the band used.

Critical tools with no seat rows are NOT CHECKED. Ask the tool's admin for a user export with roles.

## Dormant, external and shared accounts

- Dormant admin (USE01 FAIL): an enabled admin with no successful sign-in for 45 days or more. CIS Controls v8 safeguard 5.3 asks for dormant accounts to be disabled or deleted after 45 days where supported. Remove the admin role or disable the account after the owner confirms; the audit drafts the change.
- External admin (ACC02): an enabled admin on a domain outside `--company-domains`. WARN while the company holds its own admins; FAIL when it holds none.
- Agency ownership (INV05): GA4 properties, Tag Manager accounts and ad accounts created under an agency's organisation. FAIL on a critical tool. The company needs at least two admins of its own before the agency leaves.
- Shared or generic logins (ACC03): local parts such as admin, marketing, info, hello, team, ops, growth, sales, support, analytics, it, web, agency, shared. WARN, FAIL when the login holds admin rights. Shared logins break the audit trail and offboarding; replace them with named users.

## MFA on admin accounts (ACC04)

CIS Controls v8 safeguard 6.5 requires MFA for all administrative access accounts where supported; its measure counts admin accounts not configured to require MFA.

- Seat column `mfa`: enforced (the tool requires MFA for this account, or the account can sign in only through SSO that requires MFA), optional (MFA can be skipped or turned off, even if this person turned it on), unknown, or n/a (no interactive sign-in, such as a service user).
- An enabled admin on a critical tool with `mfa` optional: FAIL on a system of record, otherwise WARN. Unknown values: one NOT CHECKED line naming the tools. No `mfa` column: NOT CHECKED.
- Evidence: each tool's security settings (whether it requires two-factor authentication or SSO, and whether password sign-in stays open beside SSO), the user export where it shows MFA per user, and the identity provider's MFA policy for the app. Verify setting names at run time.
- A shared admin login defeats a personal second factor. Replace it with named users (ACC03) before requiring MFA.

## Accounts that outlive the person (ACC05)

CIS Controls v8 safeguard 6.2 asks for a process, preferably automated, that revokes access by disabling accounts on termination, rights revocation or role change; disabling instead of deleting may be needed to preserve audit trails.

- Seat column `idp_status`: join each tool export to the identity provider's user list with status (for example Okta people, Entra users or Google Workspace users; verify the export path at run time) and record active, deactivated (also suspended or deprovisioned), not_in_idp or n/a.
- An enabled tool account whose identity provider user is deactivated: FAIL. A company-domain account with no identity provider user, other than a shared login: WARN, because it is a deleted user or a local account. Blank values: NOT CHECKED. No `idp_status` column: NOT CHECKED.
- Deactivating the identity provider user stops SSO sign-in. It does not stop a local password, an API key or a personal integration in a tool outside SSO.
- Before an account is disabled, list what it owns (workflows, reports, integrations, API keys, scheduled exports) and move each item to a named owner. The audit drafts the list; the tool admin disables the account.

## Restricted Google scopes (INV02 and ACC06)

Google classifies these Gmail and Drive scopes as restricted (Gmail and Drive API scope pages, checked 2026-11-06): mail.google.com, gmail.readonly, gmail.compose, gmail.insert, gmail.modify, gmail.metadata, gmail.settings.basic, gmail.settings.sharing, drive, drive.readonly, drive.activity, drive.activity.readonly, drive.meet.readonly, drive.metadata, drive.metadata.readonly and drive.scripts. drive.file is non-sensitive: it reaches only files the user opens or creates with the app. Verify the lists at run time.

- stack_inventory.py reads the scope URLs in "Requested Services with Scopes".
- An unregistered app holding a restricted scope: INV02 FAIL, to IT security the same day. Any other unregistered app: INV02 WARN, naming calendar, contacts, directory, admin, Sheets, Docs or gmail.send scopes as sensitive.
- A registered app holding a restricted scope: ACC06 WARN until its owner confirms the need, who needs it and whether a narrower scope would do (for example drive.file instead of drive).
- When the export has no scope column, Gmail or Drive in Requested Services counts as restricted until the scopes show otherwise.

## Microsoft 365 app grants (INV02 and ACC06, by hand)

The same AI note-takers reach mailboxes through Entra consents, and `--oauth` reads only the Google file. On Microsoft 365 the agent records these two checks by hand.

- Read each enterprise application's delegated and application permission grants, by the route in [evidence-sources.md](evidence-sources.md).
- Treat these as the restricted-equivalent set: Mail.Read, Mail.ReadWrite, Mail.Send, Files.Read.All, Files.ReadWrite.All, Sites.Read.All and full_access_as_app, an Exchange Online application permission. The set is this audit's rule, not a Microsoft class (Microsoft Graph permissions reference and the EWS OAuth page, checked 2026-11-06). Verify the names at run time.
- An application with no register row holding one of them: record INV02 FAIL, tell the user the same day as an "Act now" item, and send it to IT security. Any other unregistered application with users: record INV02 WARN.
- A registered application holding one of them: record ACC06 WARN until its owner confirms the need, who needs it and whether a narrower permission would do.
- Mark these records "script not run". The script's own INV02 and ACC06 lines speak only for the files it read, so they neither clear nor replace a hand record.

## Change history

- Record where each critical tool keeps its change history and for how long. Anything older than the retention window is NOT CHECKED, not clean.
- HubSpot's account audit log records user actions with subscription-dependent categories; its main views show the last 30 days and it does not capture every automated property update. Verify live.
- Salesforce keeps configuration changes in Setup Audit Trail: the Setup page shows the 20 most recent, the download covers the past 180 days and older records are deleted (checked 2026-11-06). GA4 and Tag Manager keep change history per property or container; verify their retention live.

## Ownership minimum

- One accountable role per critical system, a named backup, and someone with authority to pause and resume a customer-facing flow in an incident.
- Check the roles against real permissions: an accountable owner who cannot sign in is not an owner.
- Ownership design and handover packs belong to martech-raci-and-handover (planned).

## Personal data and DPAs

- INV07 warns when `personal_data` is yes and `dpa_on_file` is not yes. The privacy owner decides; the audit only shows the gap.
- An unknown app holding a restricted Google scope (mail or all Drive files) goes to IT security the same day, outside the plan. One with calendar or contacts access only is registered or removed through the plan.

## AI connection inventory

List every assistant, agent or MCP server that can read or write CRM, ads, analytics or warehouse data, including the ones people connected with their own sign-in. The Google accessed apps CSV finds many of them, and the Entra enterprise app grants do the same on Microsoft 365: an AI notes or writing app holding restricted Gmail or Drive scopes, or the Microsoft equivalents, is an INV02 FAIL until registered, and one with calendar access only is an INV02 WARN. On Salesforce, hosted MCP connections run through External Client Apps, which Connected Apps OAuth Usage leaves out, so read them from the Connect REST API ([evidence-sources.md](evidence-sources.md)).

Record per connection:

- System and environment (production or sandbox).
- Publisher, and server or app name.
- Client (which assistant).
- Identity it runs as, by role. Never the token.
- Scopes or permissions granted.
- The layer that enforces read-only: the vendor's read-only switch, an API key or token scope, a role or IAM policy, or only the client's allowlist. A client confirmation prompt is not enforcement.
- Approver, logging, the off switch and who can use it.
- Owner and the date checked.

The agent-write-safety skill's connection inventory has the same fields; use it when a write is ever proposed.

Excessive agency rule (OWASP LLM06:2025 names excessive functionality, permissions and autonomy as root causes):

- An AI connection on a personal admin login: FAIL.
- An AI connection with write access and no approval step: FAIL.
- Prevention: least privilege, human approval for high-impact actions, and authorisation enforced in the downstream system rather than in the prompt.

## Seven AI readiness checks, in fix order

Rate each check fix, partly or ready, with the evidence. Answer three questions per check:

- Tracking accuracy: is there a written tracking plan? Was the key journey tested end to end in the last six months? Do counts agree with the source of truth, or are the gaps explained by category?
- Identity resolution: do the tools share one user or account ID? Can one person be traced from first visit to payment? Are pre-signup visits joined to the known person?
- Warehouse models: is there one place where the data comes together? Are the joins modelled and tested (unique keys, relationships)? Does the refresh run on a schedule with an owner?
- Metric definitions: is there one written definition of revenue and of a customer? Are CAC, MQL, pipeline and churn written down with formula, population and owner? Do reports and agents read them from one shared definition layer?
- Context docs: are the ideal customer profile and naming rules written down? Are playbooks and compliance rules documented with owners and dates? Can AI tools read them, and is anything obsolete removed?
- Access and permissions: does each AI tool have its own limited login? Is access granted per team, with an owner? Is there an inventory of AI connections with approvers?
- MCP readiness: are the core tools connected on purpose, by a named owner? Are connections read-only by default? Is there one place to switch access off?

Status rule, applied in this order:

- fix: no answer is yes, or the first question fails for tracking, identity or metric definitions.
- ready: all three answers are yes, with evidence.
- partly: anything else.

Blocking rules:

- fix on tracking, identity or metric definitions blocks AI answers on cross-tool metrics such as CAC or pipeline by channel.
- fix on access and permissions blocks every write-capable connection.
- Readiness is per question and permitted action. A single-source sessions report can be ready while cross-channel CAC is not; one good demo does not approve every workflow.
- Never average the seven into a score. List the blocking gaps separately.

Before trusting any AI answer, test it on questions with known answers, a request with missing data, and an action it must refuse. Repeat after a connector, model, definition or permission change.

## Optional: maturity per traced workflow

Use only when leadership asks for levels. Assess one workflow at a time across six areas: purpose and ownership; customer data and identity; integration and execution; measurement and decisions; reliability, access and preferences; people and operating capacity.

- Levels: 1 ad hoc, 2 repeatable, 3 connected and controlled, 4 measured in operation, 5 adaptable. Record the highest level the evidence supports; partial evidence means the lower level.
- "unassessed" means not checked. It is not level 1.
- Never average the six areas. A high measurement level cannot offset broken suppression.
- Planning targets, not benchmarks: level 2 for routine work, level 3 for consequential handoffs, level 4 where failure is costly or hard to notice.

Record format (fictional):

```yaml
workflow: trial_onboarding_reminder
area: integration_and_execution
assessment_status: assessed
observed_level: 2
desired_level: 3
required_outcome: no reminder after recorded activation
evidence:
  - type: staging_trace
    coverage: standard signup with one workspace
    result: routine transfer completed
missing_evidence:
  - customer in more than one workspace
  - preference change before send
next_action: verify these cases with sending disabled
owner_role: marketing_ops
```
