Skip to content

Team accounts for AI coding tools are an identity control first and a payment method second. The CTO Scorecard Q3 maximum needs named accounts owned by the organization, logins technically bound to it, tested joiner/mover/leaver controls, and a monthly reconciliation of seats and spend. A corporate invoice alone does not earn it.

This page is for the CTO or VP Engineering who owns AI tooling spend, and for the tech lead who runs the monthly seat review. The usual starting point: finance pays for 60 Claude and Codex seats, the identity provider (IdP) lists 52 active engineers, two leavers still have working logins, and three people expense personal plans because the approved seat “ran out of usage”. Nobody can say which of those accounts the company’s data terms actually cover.

  • An eligibility matrix that maps roles and workflows to seat types and data classes, so nobody buys the top tier by default.
  • Managed login settings for Claude Code and Codex that reject personal or foreign-organization accounts on company machines.
  • A joiner/mover/leaver runbook with an offboarding drill that produces evidence.
  • A reconciliation script that compares your IdP export with each vendor’s seat export and fails on orphaned or leaver seats.
  • Acceptance criteria your security and finance reviewers can sign off without auditing every account by hand.

The CTO scorecard offers four answers to “How do you govern AI service accounts, access lifecycle, data terms, and spend?”. The table shows what each one leaves open.

AnswerScoreWhat stays unmanaged
Developers pay personally, no reimbursement0Everything: data terms, access, offboarding, cost
Personal invoice reimbursement1Data terms and offboarding; the account belongs to the employee
Centrally purchased individual plans (Pro, Max)2Identity binding, SSO, audit; the company pays but cannot revoke or inspect
Centrally governed accounts with named owners, joiner/mover/leaver controls, reviewed data terms, and auditable spend3Nothing structural, provided the controls below are tested

The gap between 2 and 3 is identity binding. An individual plan that the company pays for is still an individual account. You cannot deprovision it from your IdP, and the organization-level data settings do not apply to it. Team and enterprise plans exist to close that gap. Which plan and tier fits is a procurement decision covered in buying AI coding tools. Current plan prices live on one page, the pricing analysis.

Set up the account lifecycle in five steps

Section titled “Set up the account lifecycle in five steps”
  1. Write the eligibility matrix. List each role, the workflows it runs with agents, and the highest data class it touches. Derive the seat type from usage evidence, not seniority. The template in the next section is the artifact to adopt.

  2. Review the service before the first seat. For each tool and plan, record the product, plan, identity controls (SSO, SCIM), data retention, training use, subprocessors, region, and contract owner. Verify the plan, not the brand. For example, Anthropic lists SCIM, the Compliance API, and zero data retention (ZDR) as Enterprise features, and its analytics dashboard as Team and Enterprise (Claude Code feature-availability page, checked 2026-09-26). The data review itself follows data privacy and enterprise policies.

  3. Provision named accounts through the IdP. Use SSO everywhere the plan offers it, SCIM where the plan supports it, MFA, and no shared credentials. Then bind the tools on company machines to your organization with managed settings (see Bind every login to your organization). Without that binding, a developer can sign in with a personal account and the seat you pay for sits idle.

  4. Reconcile access and spend monthly. Compare the IdP export, each vendor’s seat export, last-active dates, and the invoice. Run the reconciliation script below and file the output with the invoice.

  5. Offboard, then prove it. Revoke access in the IdP, remove the vendor seat, transfer owned artifacts (shared projects, scheduled routines, API keys tied to the person), rotate credentials the person could reach, and keep the audit record. Rehearse this with a test account every quarter.

Copy this table into your tooling policy and fill it from real usage data. The seat names are examples from current Claude and Codex plans. Anthropic describes its Team Premium seat as giving “5x more usage than standard seats” (claude.com/pricing, checked 2026-09-26), which is why the matrix assigns tiers by workload rather than by title.

RoleApproved agent workflowsHighest data classTool and seat typeRequired controlsOwner
Product engineerLocal agent sessions, PR reviewInternal sourceClaude Team plan, Standard seat, or Codex on a Business workspaceSSO, managed login bindingEngineering manager
Platform engineerLong-running and parallel agent runs, CI agentsInternal source, infrastructure configClaude Team plan, Premium seat (or Enterprise equivalent)SSO, managed settings, CI identity per agent identity and secretsPlatform lead
Data engineerAgent sessions against warehouse schemasConfidentialEnterprise plan only, with the retention setting your data review requiresSSO, SCIM, reviewed retention, MCP least privilegeData lead
ContractorAgent sessions in one repositoryInternal sourceSeat on your workspace, never their own accountSSO, end date in the IdP, no API keysContract owner

Buying team seats does not stop a developer from signing in with a personal account on the same laptop. The fix is a managed setting that rejects any login outside your organization. The full cross-tool policy (models, MCP servers, plugins, permission floors) lives in enforcing one policy across every coding agent. This section covers only the account binding.

Deploy these keys in a device-managed source: managed-settings.json (on Linux and WSL, /etc/claude-code/managed-settings.json), a macOS configuration profile, or the Windows policy registry.

{
"forceLoginMethod": "claudeai",
"forceLoginOrgUUID": "YOUR_ORG_UUID"
}

YOUR_ORG_UUID is the organization ID shown in the claude.ai admin settings for your Team or Enterprise organization. With the keys in a managed source, Claude Code reports an error for a claude.ai login to any other organization and exits at startup if the credential in use belongs to an unlisted one. It also blocks sessions that authenticate with ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, or apiKeyHelper, because it cannot verify organization membership for an environment credential.

Four gaps to know (Claude Code authentication docs, checked 2026-09-26 against v2.1.283):

  • Server-managed settings from the claude.ai console reach only accounts already signed in to your organization, so they cannot redirect a first login. Put the keys in the device-managed source, and also in server-managed settings if you use them, because the managed sources do not merge.
  • The interactive /login screen pre-selects the method without enforcing it, so a developer can still complete a Claude Console login there, and Claude Code does not check which organization a Console credential belongs to, at login or at startup. Pair the binding with Console workspace controls, or remove Console access for developers.
  • claude setup-token and /install-github-app enforce only forceLoginMethod, so they can mint a token in a different organization.
  • Cloud provider sessions (Amazon Bedrock and others) and Anthropic profile or federation credentials are not checked against your organization; they are blocked only while an API-key credential is also on the machine. Restrict them with cloud IAM and your identity provider.

Reconcile seats against the IdP every month

Section titled “Reconcile seats against the IdP every month”

Seat exports and invoices drift from the IdP within weeks: leavers keep seats, contractors outlive their contracts, and people get a second seat in the same tool after a rename. The script below compares one IdP export with any number of vendor seat exports and exits non-zero when it finds an orphaned or leaver seat, so you can run it in a scheduled CI job. It matches people by email, so a rename that changes the email shows up as ORPHANED for the old address; check those against the IdP’s alias history before removing the seat.

#!/usr/bin/env python3
"""Reconcile AI tool seats against the identity provider export.
Usage: python3 reconcile_seats.py idp.csv seats-claude.csv seats-codex.csv ...
idp.csv: email,status,cost_center (status: active | suspended | terminated)
seats-*: email,seat_type,last_active (last_active: YYYY-MM-DD, empty if never)
"""
import csv, sys
from datetime import date, timedelta
STALE_AFTER = timedelta(days=30)
def rows(path):
with open(path, newline="") as f:
return [{k: (v or "").strip() for k, v in r.items()} for r in csv.DictReader(f)]
idp = {r["email"].lower(): r for r in rows(sys.argv[1])}
findings, seen = [], {}
for path in sys.argv[2:]:
for seat in rows(path):
email = seat["email"].lower()
person = idp.get(email)
seen.setdefault(email, []).append(path)
if person is None:
findings.append((path, email, "ORPHANED: no identity in the IdP export"))
elif person["status"] != "active":
findings.append((path, email, f"LEAVER: IdP status is {person['status']}"))
elif not person.get("cost_center"):
findings.append((path, email, "UNOWNED: no cost center"))
last = seat.get("last_active")
try:
seen_on = date.fromisoformat(last[:10]) if last else None
except ValueError:
findings.append((path, email, f"BADDATE: last_active is {last!r}"))
continue
if seen_on is None or date.today() - seen_on > STALE_AFTER:
findings.append((path, email, f"IDLE: last active {last or 'never'}"))
for email, paths in seen.items():
if len(paths) != len(set(paths)):
findings.append((paths[0], email, "DUPLICATE: two seats in one tool"))
w = csv.writer(sys.stdout)
w.writerow(["source", "email", "finding"])
w.writerows(sorted(findings))
sys.exit(1 if any(f[2].startswith(("ORPHANED", "LEAVER")) for f in findings) else 0)

Vendor exports use their own column names, so rename columns to email, seat_type, and last_active before you run it. The script reads the first ten characters of last_active as a YYYY-MM-DD date, so an ISO timestamp such as 2026-09-01T10:00:00Z works; normalise any other date format to YYYY-MM-DD, or the row is reported as BADDATE. Where the data comes from, as documented on 2026-09-26:

  • Claude Team and Enterprise: take email from the organization member list in the claude.ai admin settings, and activity from the Claude Code analytics dashboard (claude.ai/analytics/claude-code), which shows daily active users and exports per-user data as CSV; confirm the export carries a date you can map to last_active. The spend report in your organization’s analytics settings is the cost input only: it appears once usage credits are on and does not meter usage inside the seat allowance. On Enterprise, the Claude Enterprise Analytics API returns per-user engagement, usage, and cost reports; it is not available on the Team plan.
  • Claude Console (API billing): the team insights table shows per-user spend for the month, and the Claude Code Analytics API returns the same daily per-user metrics with an Admin API key. Anthropic labels the dashboard spend figures as estimates; the billing page holds actual costs.
  • Codex and Cursor: use the workspace admin’s member and usage exports. Neither export format could be verified here, so check the column names against a real export before you schedule the job.

Treat IDLE as a conversation, not a cancellation. A seat idle for 30 days may belong to someone on leave. Treat ORPHANED and LEAVER as incidents: remove the seat that day and record why the IdP did not catch it. For budget sanity, Anthropic reports the average across enterprise deployments at “around $13 per developer per active day and $150-250 per developer per month” (Claude Code costs page, checked 2026-09-26). The attribution of spend to teams and outcomes belongs to AI usage cost governance.

Run these in Claude Code, Codex, or Cursor with the exports in the working directory. They work the same way in all three tools. Keep personal data inside tools your data review approved.

How do you prove the account controls work?

Section titled “How do you prove the account controls work?”

You do not need to open every account. You need evidence that fails loudly when a control breaks, and a named person who signs it off.

ControlEvidencePass conditionSigns off
Seat ownershipMonthly reconciliation output filed with the invoiceZero ORPHANED and LEAVER rows, or each one closed with a ticketEngineering finance partner
Login bindingA test login with a personal account on a managed machineThe tool rejects it, and the rejection is recordedSecurity lead
OffboardingQuarterly drill with a test accountFirst failed login within your target window after IdP suspensionIT or identity owner
Data termsService record per tool and plan, datedAccount configuration matches the approved recordData protection owner
ExceptionsException registerEvery personal plan has an owner, scope, and unexpired end dateCTO

Two rules keep this honest. First, the spend review looks at unused seats and completed work. It never ranks employees by activity, because a leaderboard of tokens rewards waste. Second, the evidence lives where an auditor can read it: the reconciliation CSVs, drill records, and service records go into a versioned repository or ticket, not a chat thread.

What breaks in AI team account governance?

Section titled “What breaks in AI team account governance?”

Central invoice, unmanaged access. Finance pays for seats while developers keep signing in with personal accounts. The reconciliation shows seats with no activity while usage is high. Recovery: deploy the managed login binding from the tabs above, then run a test login with a personal account to confirm the rejection.

The IdP is not the source of truth. Seats were added by hand in the vendor console, so SCIM or SSO removal misses them. The first reconciliation run shows ORPHANED rows. Recovery: remove the orphans, restrict seat assignment to IdP groups where the plan allows it, and make the reconciliation job fail the build on any new orphan.

Leaver tokens outlive the leaver. The seat is gone, but an API key, a long-lived token from claude setup-token, or a CI secret created by the person still works. Recovery: include credential inventory in the offboarding runbook, rotate everything the person could read, and move CI agents to their own identities as described in agent identity and secrets.

Usage limits push people back to personal plans. Developers on a lower seat hit the limit and expense a personal plan, which reopens the data-terms gap. Recovery: move those people to a higher seat through the eligibility matrix, and treat any expense claim for an AI plan as a signal to review the matrix, not as a reimbursement.

Data terms reviewed once, never again. A plan change, a new model, or a new feature changes retention. For example, Anthropic classifies Claude Fable 5.1 as a Covered Model that requires data retention by default, which matters for a ZDR organization. Recovery: re-review the service record whenever the plan, the default model, or a data-handling feature changes, and date every record.

Account governance sits between the approved-workflow decision and the cost model. Start with the policy, then the spend.

Frequently asked questions

Why does CTO Scorecard Q3 treat team AI accounts primarily as an identity control?

Binding every Claude, OpenAI, and Cursor login to corporate SSO with enforced joiner/mover/leaver lifecycle rules ensures that organizational data governance applies to every session and that departing staff lose access immediately.

What monthly routine is required alongside SSO for a 3-point Q3 score?

In addition to organization-owned accounts and tested joiner/mover/leaver controls, finance and engineering must reconcile active seats, role assignments, and spend against HR records every month.