Back to AI App Dev Series

Anthropic SDK Track Part 16: Administration & Compliance

May 22, 2026 Wasil Zafar 30 min read

Manage API keys, monitor usage, control costs, understand rate limits, and implement organizational governance for Anthropic services. The Admin API, workspace management, and compliance frameworks for enterprise deployments.

CCA Domain 5 · 15% Tasks 5.7, 5.8

Table of Contents

  1. API Key Management
  2. Usage Monitoring
  3. Rate Limits & Cost Controls
  4. Organizational Governance
  5. Admin API (CCA 13.1)
What You’ll Learn: As your agent system scales from a side project to a team-wide platform, you need governance: who can deploy agents, what models they can use, how much they can spend, and what data they can access. This article covers the administrative controls — workspace management, usage policies, audit logging, and organizational best practices for safe AI deployment.

1. API Key Management

# API Key Best Practices for CCA

# 1. Use workspace-scoped keys (not organization-wide)
# Each team/project gets its own workspace with separate keys
# This enables per-team billing and access control

# 2. Rotate keys regularly according to your organization's security policy
# Many teams use 60-90 day rotation windows plus immediate rotation on incidents

# 3. Never hardcode keys
import os

# ✅ GOOD: Environment variable
api_key = os.environ.get("ANTHROPIC_API_KEY")

# ✅ GOOD: Secret manager
# from cloud_provider import secret_manager
# api_key = secret_manager.get("anthropic-api-key")

# ❌ BAD: Hardcoded
# api_key = "sk-ant-api03-..."

# 4. Scope keys to minimum required permissions
# - Read-only keys for monitoring dashboards
# - Scoped keys for specific models or features
# - Admin keys only for infrastructure management

# 5. Key naming convention for audit trails
# Format: {team}-{environment}-{purpose}
# Examples: ml-prod-inference, backend-staging-testing

2. Usage Monitoring

import anthropic
import json
from datetime import datetime

client = anthropic.Anthropic()

# Track usage per request for cost attribution
class UsageTracker:
    def __init__(self):
        self.records = []

    def record_usage(self, response, metadata: dict):
        """Record API usage with attribution metadata."""
        self.records.append({
            "timestamp": datetime.utcnow().isoformat(),
            "model": response.model,
            "input_tokens": response.usage.input_tokens,
            "output_tokens": response.usage.output_tokens,
            "stop_reason": response.stop_reason,
            "team": metadata.get("team"),
            "feature": metadata.get("feature"),
            "request_id": response.id
        })

    def get_cost_estimate(self) -> dict:
        """Estimate costs based on token usage."""
        # Pricing (example — check platform.claude.com for current)
        pricing = {
            "claude-sonnet-4-6": {"input": 3.0, "output": 15.0},  # per 1M tokens
            "claude-opus-4-7": {"input": 5.0, "output": 25.0},
            "claude-haiku-4-5-20251001": {"input": 1.0, "output": 5.0}
        }

        total_cost = 0.0
        by_team = {}

        for record in self.records:
            model = record["model"]
            rates = pricing.get(model, {"input": 3.0, "output": 15.0})
            cost = (
                (record["input_tokens"] / 1_000_000) * rates["input"] +
                (record["output_tokens"] / 1_000_000) * rates["output"]
            )
            total_cost += cost
            team = record.get("team", "unknown")
            by_team[team] = by_team.get(team, 0) + cost

        return {"total_usd": round(total_cost, 4), "by_team": by_team}

3. Rate Limits & Cost Controls

import anthropic
import time
from collections import deque

# Rate limit tiers (per Anthropic documentation):
# - Requests per minute (RPM)
# - Tokens per minute (TPM)
# - Tokens per day (TPD)
# Limits vary by tier (Build → Scale → Custom)

class RateLimitedClient:
    """Client with local rate limiting to avoid 429 errors."""

    def __init__(self, rpm_limit: int = 50, tpm_limit: int = 40000):
        self.client = anthropic.Anthropic()
        self.rpm_limit = rpm_limit
        self.tpm_limit = tpm_limit
        self.request_times = deque()
        self.token_usage = deque()

    def _check_rpm(self):
        """Enforce requests per minute limit."""
        now = time.time()
        # Remove entries older than 60 seconds
        while self.request_times and self.request_times[0] < now - 60:
            self.request_times.popleft()
        if len(self.request_times) >= self.rpm_limit:
            sleep_time = 60 - (now - self.request_times[0])
            time.sleep(max(0, sleep_time))
        self.request_times.append(now)

    def create_message(self, **kwargs) -> anthropic.types.Message:
        """Rate-limited message creation."""
        self._check_rpm()

        try:
            response = self.client.messages.create(**kwargs)
            return response
        except anthropic.RateLimitError as e:
            # Read retry-after header
            retry_after = int(e.response.headers.get("retry-after", 60))
            time.sleep(retry_after)
            return self.client.messages.create(**kwargs)

# Cost controls: set spending limits
# (Configured in Anthropic Console, not via API)
# - Monthly spending cap per workspace
# - Per-key daily limits
# - Alert thresholds at 50%, 80%, 95% of budget
Real-World Application

Enterprise AI Governance at Scale

A Fortune 500 company manages 200+ Claude-powered agents across 15 departments. Their governance framework: centralized model registry, per-department spending caps with alerts, mandatory audit logging for regulated departments (legal, finance), and quarterly access reviews. Result: zero compliance incidents in 12 months while enabling rapid agent development.

GovernanceEnterprise

4. Organizational Governance

Enterprise Governance Architecture
                            flowchart TD
                                ORG["Organization"] --> WS1["Workspace: Dev"]
                                ORG --> WS2["Workspace: Staging"]
                                ORG --> WS3["Workspace: Production"]

                                WS3 --> MAC["Model Access Control
Pin versions, restrict models"] WS3 --> DHP["Data Handling Policies
PII rules, retention limits"] WS3 --> AUD["Audit Requirements
Log all API calls"] WS3 --> COMP["Compliance Frameworks
SOC 2 · HIPAA · GDPR"] style WS1 fill:#f8f9fa,stroke:#3B9797 style WS2 fill:#f8f9fa,stroke:#16476A style WS3 fill:#f8f9fa,stroke:#BF092F
# Enterprise governance — audit event structure
audit_event = {
    "event": "api_call",
    "timestamp": "2026-05-22T10:30:00Z",
    "workspace": "prod-customer-support",
    "api_key_id": "key_abc123",  # NOT the key itself
    "model": "claude-sonnet-4-6",
    "input_tokens": 1500,
    "output_tokens": 800,
    "tools_used": ["get_customer", "lookup_order"],
    "stop_reason": "end_turn",
    "latency_ms": 2340
}

# 5. Compliance frameworks (availability depends on your contract and setup)
# - SOC 2 Type II: Anthropic maintains certification
# - HIPAA: Available via BAA for eligible healthcare use cases
# - GDPR: Data processing agreements available
# - Enterprise: Custom data retention / governance options may be available
CCA Tasks 5.7 & 5.8 — Final Exam Topics: (1) Workspace-scoped keys for access isolation, (2) rate limits are per-organization, shared across all keys, (3) the Batches API does NOT count toward real-time rate limits, (4) cost = (input_tokens × input_price + output_tokens × output_price), (5) extended thinking tokens are billed as output tokens, (6) the Admin API manages workspaces and members programmatically.
Series Complete

Anthropic SDK Track Summary

This 16-part series covers all 5 CCA Domains:

  • Domain 1 (30%): Parts 1-6 — Platform, Messages API, Agentic Loops, Multi-Agent, Hooks/State, Tool Design
  • Domain 2 (20%): Part 7 — MCP Servers & Built-In Tools
  • Domain 3 (20%): Parts 8-9 — CLAUDE.md, Rules, Plan Mode, CI/CD
  • Domain 4 (15%): Parts 10-12 — Prompts, Structured Output, Context Preservation
  • Domain 5 (15%): Parts 13-16 — Errors, Thinking, Environments, Administration
CCA CompleteAll 5 Domains
Try It Yourself: Design an access control policy for a 3-team organization using Claude agents: Engineering (full access, all models), Marketing (text generation only, no tool use, $500/month cap), and Finance (structured output only, audit logging required). Document the policy and implement the enforcement layer using API key scoping and middleware.

5. Admin API (CCA 13.1)

The Admin API manages your organization’s users, invitations, and workspace membership programmatically. This is how enterprises automate onboarding, offboarding, and access governance — instead of managing everything through the Console UI.

5.1 Invitations & User Management

import anthropic
import json

# Admin API requires an Admin API key (separate from regular API keys)
# Org admins provision these from Claude Console admin key settings

# INVITATIONS — Invite users to your organization
# POST /v1/admin/invitations
# invite = admin_client.invitations.create(
#     email="newuser@company.com",
#     role="developer",          # Roles: admin, developer, billing, viewer
#     workspaces=["ws_eng_01"],  # Optional: auto-add to workspaces
#     expires_in_days=7
# )

# LIST pending invitations
# GET /v1/admin/invitations
# invites = admin_client.invitations.list(status="pending")

# REVOKE an invitation
# DELETE /v1/admin/invitations/{invite_id}
# admin_client.invitations.revoke("inv_abc123")

# USERS — Manage existing organization members
# GET /v1/admin/users — List all users
# users = admin_client.users.list()

# GET /v1/admin/users/{user_id} — Get user details
# user = admin_client.users.get("user_xyz")
# print(f"Role: {user.role}, Workspaces: {user.workspace_ids}")

# PUT /v1/admin/users/{user_id} — Update user role
# admin_client.users.update("user_xyz", role="admin")

# DELETE /v1/admin/users/{user_id} — Remove from organization
# admin_client.users.remove("user_xyz")

# WORKSPACE MEMBERS — Control workspace-level access
# POST /v1/admin/workspaces/{ws_id}/members
# admin_client.workspaces.members.add("ws_eng_01", user_id="user_xyz", role="developer")

# DELETE /v1/admin/workspaces/{ws_id}/members/{user_id}
# admin_client.workspaces.members.remove("ws_eng_01", "user_xyz")

print("Admin API: manage users, invites, and workspace membership programmatically")
print("Roles: admin (full access), developer (API + builds), billing (cost only), viewer (read-only)")

5.2 Usage Reports (CCA 13.2)

import anthropic
import json
from datetime import datetime, timedelta

# Usage Reports — detailed breakdown of API consumption
# Three report types: Messages, Claude Code, and Cost

# MESSAGES USAGE — per-model, per-workspace token consumption
# GET /v1/admin/usage/messages?start_date=2024-03-01&end_date=2024-03-31
# usage = admin_client.usage.messages(
#     start_date="2024-03-01",
#     end_date="2024-03-31",
#     group_by=["model", "workspace"]  # Aggregation dimensions
# )
# for entry in usage.data:
#     print(f"{entry.model}: {entry.input_tokens:,} in / {entry.output_tokens:,} out")

# CLAUDE CODE USAGE — session hours, tool calls, active users
# GET /v1/admin/usage/claude-code?start_date=2024-03-01
# cc_usage = admin_client.usage.claude_code(
#     start_date="2024-03-01",
#     end_date="2024-03-31",
#     group_by=["user", "project"]
# )

# COST REPORTS — dollar amounts by model, workspace, user
# GET /v1/admin/usage/cost?start_date=2024-03-01
# costs = admin_client.usage.cost(
#     start_date="2024-03-01",
#     end_date="2024-03-31",
#     group_by=["workspace"]
# )
# for ws in costs.data:
#     print(f"Workspace {ws.workspace_name}: ${ws.total_cost:.2f}")

# Common queries:
# - "Which team is spending the most?" → group_by workspace
# - "Which model is most used?" → group_by model
# - "Who are our power users?" → group_by user (Claude Code report)
# - "Month-over-month growth?" → compare start_date ranges

print("Usage reports: Messages (tokens), Claude Code (sessions), Cost (dollars)")
print("Group by: model, workspace, user, project — for accountability")

5.3 Compliance API (CCA 13.3)

import anthropic
import json
from datetime import datetime

# Compliance API — audit trail and data-governance support for regulated workflows
# Commonly used for: SOC 2, HIPAA, GDPR, and financial-services controls

# QUERY ACTIVITIES — complete audit log of all API interactions
# POST /v1/admin/compliance/activities/query
# activities = admin_client.compliance.activities.query(
#     start_time="2024-03-01T00:00:00Z",
#     end_time="2024-03-31T23:59:59Z",
#     filters={
#         "user_id": "user_xyz",              # Optional: specific user
#         "activity_type": "messages.create",  # Optional: specific action
#         "model": "claude-sonnet-4-6"      # Optional: specific model
#     },
#     include_content=False  # True = includes actual prompts/responses (PII risk!)
# )

# Activity types tracked:
# - messages.create (API calls)
# - sessions.create / sessions.event (managed sessions)
# - files.upload / files.download
# - agents.create / agents.update
# - admin.users.update (role changes)
# - admin.keys.create / admin.keys.revoke

# LIST ORGANIZATIONS (for multi-org compliance)
# GET /v1/admin/compliance/organizations
# orgs = admin_client.compliance.organizations.list()

# LIST USERS across compliance scope
# GET /v1/admin/compliance/users
# users = admin_client.compliance.users.list(organization_id="org_abc")

# COMPLIANCE GROUPS — logical groupings for access control
# (e.g., "HIPAA-regulated", "PII-handling", "external-facing")
# POST /v1/admin/compliance/groups
# group = admin_client.compliance.groups.create(
#     name="hipaa-regulated",
#     description="Agents handling PHI data",
#     restrictions={
#         "data_retention_days": 30,
#         "require_encryption": True,
#         "allowed_regions": ["us-east-1", "us-west-2"],
#         "audit_level": "full"  # Log everything including content
#     }
# )

# Data retention policies vary by organization settings and contractual controls.
# Treat these values as example policy shapes, not universal Anthropic defaults.

print("Compliance API: audit trail, data governance, regulatory controls")
print("Key: activity logs are immutable — cannot be deleted or modified")
print("Use compliance groups for different data sensitivity levels")
CCA Exam Pattern (13.1–13.3): Questions test: (1) Admin API uses a separate Admin API key (not regular API keys). (2) Usage reports support group_by dimensions such as model, workspace, and user. (3) Audit/compliance activity logs are intended to be append-only records. (4) include_content=False is the safer default when prompts may contain sensitive data. (5) Workspace and compliance controls can shape retention and regional policy. (6) ZDR or zero-retention arrangements should be described carefully as contractual/runtime retention controls, not as a blanket claim that no technical artifacts ever exist.

Next in the SDK Track

In Part 17: Use Cases & Ticket Routing, we cover CCA Phase 1 applied patterns — choosing the right Claude architecture, intent classification with tool_choice, confidence-based routing, and production routing architectures.